Skip to content

Commit

Permalink
Merge pull request #39 from dala318/events
Browse files Browse the repository at this point in the history
Events
  • Loading branch information
dala318 authored Sep 16, 2024
2 parents fec3adf + c41548b commit 1ac249c
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 78 deletions.
63 changes: 22 additions & 41 deletions custom_components/nordpool_planner/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,6 @@
PLATFORMS = [Platform.BINARY_SENSOR, Platform.NUMBER]


# async def async_setup(hass: HomeAssistant, config: Config) -> bool:
# hass.data.setdefault(DOMAIN, {})
# return True


# async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
# entry_data = dict(entry.data)
# hass.data[DOMAIN][entry.entry_id] = entry_data
# await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
# return True
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
"""Set up this integration using UI."""
config_entry.async_on_unload(config_entry.add_update_listener(async_reload_entry))
Expand All @@ -52,9 +42,6 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b

if config_entry.entry_id not in hass.data[DOMAIN]:
hass.data[DOMAIN][config_entry.entry_id] = NordpoolPlanner(hass, config_entry)
# else:
# planner = hass.data[DOMAIN][config_entry.entry_id]
# await planner.async_config_entry_first_refresh()

if config_entry is not None:
if config_entry.source == SOURCE_IMPORT:
Expand All @@ -67,16 +54,12 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
return True


# async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
# unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
# if unload_ok:
# hass.data[DOMAIN].pop(entry.entry_id)
# return unload_ok
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unloading a config_flow entry."""
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if unload_ok:
hass.data[DOMAIN].pop(entry.entry_id)
planner = hass.data[DOMAIN].pop(entry.entry_id)
planner.cleanup()
return unload_ok


Expand All @@ -93,25 +76,17 @@ def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None:
"""Initialize my coordinator."""
self._hass = hass
self._config = config_entry
self._state_change_listners = []

# if self._np_entity.unique_id is not None:
# self.async_on_remove(
# async_track_state_change_event(
# self._hass,
# [self._np_entity.unique_id],
# self._async_input_changed,
# )
# )

# Internal states
# Input entities
self._np_entity = NordpoolEntity(self._config.data[CONF_NP_ENTITY])

# # TODO: Dont seem to work as expected!
# async_track_state_change_event(
# self._hass,
# [self._np_entity.unique_id],
# self._async_input_changed,
# )
self._state_change_listners.append(
async_track_state_change_event(
self._hass,
[self._np_entity.unique_id],
self._async_input_changed,
)
)

# Configuration entities
self._duration_number_entity = ""
Expand Down Expand Up @@ -172,6 +147,11 @@ def _accept_rate(self) -> float:
"""Get accept rate parameter."""
return self.get_number_entity_value(self._accept_rate_number_entity)

def cleanup(self):
"""Clenaup by removing event listners."""
for lister in self._state_change_listners:
lister()

def get_number_entity_value(
self, entity_id: str, integer: bool = False
) -> float | int | None:
Expand Down Expand Up @@ -219,11 +199,12 @@ def register_input_entity_id(self, entity_id, conf_key) -> None:
entity_id,
conf_key,
)
# TODO: Dont seem to work as expected!
async_track_state_change_event(
self._hass,
[entity_id],
self._async_input_changed,
self._state_change_listners.append(
async_track_state_change_event(
self._hass,
[entity_id],
self._async_input_changed,
)
)

def register_output_listner_entity(self, entity, conf_key="") -> None:
Expand Down
20 changes: 10 additions & 10 deletions custom_components/nordpool_planner/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
key=CONF_SEARCH_LENGTH_ENTITY,
device_class=NumberDeviceClass.DURATION,
native_min_value=3,
native_max_value=12,
native_max_value=23, # Let's keep it below 24h to not risk wrapping a day.
native_step=1,
native_unit_of_measurement=UnitOfTime.HOURS,
)
Expand All @@ -78,15 +78,15 @@ async def async_setup_entry(
entities.append(
NordpoolPlannerNumber(
planner,
callback=planner.input_changed,
# callback=planner.input_changed,
start_val=3,
entity_description=DURATION_ENTITY_DESCRIPTION,
)
)

if config_entry.data.get(CONF_ACCEPT_COST_ENTITY):
entity_description = ACCEPT_COST_ENTITY_DESCRIPTION
# Override if curensy option is set
# Override if currency option is set
if currency := config_entry.options.get(CONF_CURENCY):
entity_description = NumberEntityDescription(
key=ACCEPT_COST_ENTITY_DESCRIPTION.key,
Expand All @@ -99,7 +99,7 @@ async def async_setup_entry(
entities.append(
NordpoolPlannerNumber(
planner,
callback=planner.input_changed,
# callback=planner.input_changed,
start_val=0.0,
entity_description=entity_description,
)
Expand All @@ -109,7 +109,7 @@ async def async_setup_entry(
entities.append(
NordpoolPlannerNumber(
planner,
callback=planner.input_changed,
# callback=planner.input_changed,
start_val=0.1,
entity_description=ACCEPT_RATE_ENTITY_DESCRIPTION,
)
Expand All @@ -119,7 +119,7 @@ async def async_setup_entry(
entities.append(
NordpoolPlannerNumber(
planner,
callback=planner.input_changed,
# callback=planner.input_changed,
start_val=10,
entity_description=SEARCH_LENGTH_ENTITY_DESCRIPTION,
)
Expand All @@ -129,7 +129,7 @@ async def async_setup_entry(
entities.append(
NordpoolPlannerNumber(
planner,
callback=planner.input_changed,
# callback=planner.input_changed,
start_val=7,
entity_description=END_TIME_ENTITY_DESCRIPTION,
)
Expand All @@ -145,15 +145,15 @@ class NordpoolPlannerNumber(NordpoolPlannerEntity, RestoreNumber):
def __init__(
self,
planner,
callback,
# callback,
start_val,
entity_description: NumberEntityDescription,
) -> None:
"""Initialize the entity."""
super().__init__(planner)
self.entity_description = entity_description
self._default_value = start_val
self._callback = callback
# self._callback = callback
self._attr_name = (
self._planner.name
+ " "
Expand Down Expand Up @@ -188,5 +188,5 @@ async def async_set_native_value(self, value: float) -> None:
value,
self.name,
)
self._callback(value)
# self._callback(value)
self.async_schedule_update_ha_state()
64 changes: 64 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
[coverage:run]
source =
custom_components

[coverage:report]
exclude_lines =
pragma: no cover
raise NotImplemented()
if __name__ == '__main__':
main()
show_missing = true

[tool:pytest]
testpaths = tests
norecursedirs = .git
asyncio_mode = auto
addopts =
-p syrupy
--strict
--cov=custom_components

[flake8]
# https://github.com/ambv/black#line-length
max-line-length = 88
# E501: line too long
# W503: Line break occurred before a binary operator
# E203: Whitespace before ':'
# D202 No blank lines allowed after function docstring
# W504 line break after binary operator
ignore =
E501,
W503,
E203,
D202,
W504

[isort]
# https://github.com/timothycrosley/isort
# https://github.com/timothycrosley/isort/wiki/isort-Settings
# splits long import on multiple lines indented by 4 spaces
multi_line_output = 3
include_trailing_comma=True
force_grid_wrap=0
use_parentheses=True
line_length=88
indent = " "
# by default isort don't check module indexes
not_skip = __init__.py
# will group `import x` and `from x import` of the same module.
force_sort_within_sections = true
sections = FUTURE,STDLIB,INBETWEENS,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
default_section = THIRDPARTY
known_first_party = custom_components,tests
forced_separate = tests
combine_as_imports = true

[mypy]
python_version = 3.7
ignore_errors = true
follow_imports = silent
ignore_missing_imports = true
warn_incomplete_stub = true
warn_redundant_casts = true
warn_unused_configs = true
17 changes: 17 additions & 0 deletions tests/bandit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# https://bandit.readthedocs.io/en/latest/config.html

tests:
- B108
- B306
- B307
- B313
- B314
- B315
- B316
- B317
- B318
- B319
- B320
- B325
- B602
- B604
9 changes: 9 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""Fixtures for testing."""

import pytest


@pytest.fixture(autouse=True)
def auto_enable_custom_integrations(enable_custom_integrations):
"""Enable custom integrations."""
return
55 changes: 28 additions & 27 deletions tests/test_planner.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,40 @@

from custom_components.nordpool_planner.const import *
from homeassistant import config_entries
from homeassistant.components import sensor
from homeassistant.core import HomeAssistant

# from homeassistant.components import sensor
# from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

NAME = "My planner 1"
TYPE = "moving"
DURATION_ENT = "duration_ent"
SEARCH_LENGTH_ENT = "search_len"
NP_ENT = "sensor.np_ent"
CURRENCY = "EUR"

CONF_ENTRY = config_entries.ConfigEntry(
data={
CONF_NAME: NAME,
CONF_TYPE: TYPE,
CONF_NP_ENTITY: NP_ENT,
CONF_DURATION_ENTITY: DURATION_ENT,
CONF_SEARCH_LENGTH_ENTITY: SEARCH_LENGTH_ENT,
},
options={CONF_CURENCY: CURRENCY},
domain=DOMAIN,
version=1,
minor_version=2,
source="user",
title="Nordpool Planner",
unique_id="123456",
)


@pytest.mark.asyncio
async def test_planner_init(hass):
"""Test the planner initialization."""

NAME = "My planner 1"
TYPE = "moving"
DURATION_ENT = "duration_ent"
SEARCH_LENGTH_ENT = "search_len"
NP_ENT = "sensor.np_ent"
CURRENCY = "EUR"

# async def async_setup_entry_init(
# hass: HomeAssistant, config_entry: config_entries.ConfigEntry
# ) -> bool:
Expand All @@ -48,23 +66,6 @@ async def test_planner_init(hass):
# ),
# )

config_entry = config_entries.ConfigEntry(
data={
CONF_NAME: NAME,
CONF_TYPE: TYPE,
CONF_NP_ENTITY: NP_ENT,
CONF_DURATION_ENTITY: DURATION_ENT,
CONF_SEARCH_LENGTH_ENTITY: SEARCH_LENGTH_ENT,
},
options={CONF_CURENCY: CURRENCY},
domain=DOMAIN,
version=1,
minor_version=2,
source="user",
title="Nordpool Planner",
unique_id="123456",
)

# # Fake nordpool sensor
# np_sensor = sensor.SensorEntity()
# np_sensor.entity_id = NP_ENT
Expand All @@ -84,7 +85,7 @@ async def test_planner_init(hass):
# MockPlatform(async_setup_entry=async_setup_entry_platform),
# )

planner = NordpoolPlanner(hass, config_entry)
planner = NordpoolPlanner(hass, CONF_ENTRY)

assert planner.name == NAME
assert planner._is_static == False
Expand Down

0 comments on commit 1ac249c

Please sign in to comment.