Skip to content

Commit

Permalink
Code cleanup, and bug fixes. (#5)
Browse files Browse the repository at this point in the history
* Cleanup imports, and spelling.

* Simplify.

* Clean up comments.

* Clean up ambiguous naming.  Comment tests.
  • Loading branch information
randomletters authored May 6, 2024
1 parent 906c8e7 commit 4773a87
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 183 deletions.
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,11 @@
"python.analysis.extraPaths": [
"/usr/src/homeassistant",
"/usr/local/lib/python3.12/site-packages/pytest_homeassistant_custom_component"
],
"cSpell.words": [
"devcontainer",
"freezegun",
"hass",
"pytest"
]
}
6 changes: 2 additions & 4 deletions custom_components/motion_dimmer/datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from __future__ import annotations

import datetime
from datetime import datetime
import logging

from homeassistant.components.datetime import DateTimeEntity
Expand Down Expand Up @@ -44,9 +44,7 @@ async def async_added_to_hass(self) -> None:
"""Restore last state."""
last_state = await self.async_get_last_state()
if last_state:
self._attr_native_value = datetime.datetime.fromisoformat(
str(last_state.state)
)
self._attr_native_value = datetime.fromisoformat(str(last_state.state))
else:
self._attr_native_value = now()

Expand Down
3 changes: 0 additions & 3 deletions custom_components/motion_dimmer/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,9 @@
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.util.dt import now

from .const import (
DOMAIN,
SENSOR_DURATION,
SENSOR_END_TIME,
ControlEntities as CE,
)
from .models import MotionDimmerData, MotionDimmerEntity, internal_id
Expand Down
75 changes: 40 additions & 35 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,18 @@
from copy import deepcopy
from datetime import datetime, timedelta
from typing import Any
from homeassistant.components.light import ColorMode

from homeassistant.components.light import (
ATTR_BRIGHTNESS,
ColorMode,
)
from homeassistant.config_entries import SOURCE_USER
from homeassistant.core import Event, HomeAssistant
from homeassistant.setup import async_setup_component, logging
from homeassistant.util.dt import now, parse_duration
from pytest_homeassistant_custom_component.common import (
MockConfigEntry,
async_capture_events,
async_fire_time_changed,
async_fire_time_changed_exact,
)
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
)

from custom_components.motion_dimmer.const import (
Expand Down Expand Up @@ -53,7 +52,6 @@
SCRIPT_DOMAIN,
)


_LOGGER = logging.getLogger(__name__)
logging.basicConfig(level=logging.ERROR, force=True)

Expand Down Expand Up @@ -111,7 +109,6 @@ async def setup_integration(
source=source,
data=deepcopy(config),
options=deepcopy(options),
# entry_id=entry_id,
unique_id=unique_id,
)
config_entry.add_to_hass(hass)
Expand Down Expand Up @@ -159,7 +156,7 @@ def to_pct(num: float) -> float:
return round(num / 2.55, 2)


async def dimmer_is_set_to(events: list, values: dict):
async def dimmer_is_set_to(events: list[Event], values: dict):
"""Check that the dimmer is set to the desired value."""
assert event_extract(events, "domain") == LIGHT_DOMAIN
assert event_extract(events, "service") == "turn_on"
Expand Down Expand Up @@ -249,37 +246,44 @@ async def call_service(hass, service, data):


def secs(time: datetime):
"""Get number of seconds until a datetime."""
return round((time - now()).total_seconds())


def dur(duration: str):
"""Get number of seconds from a duration string."""
return round(parse_duration(duration).total_seconds())


def event_keys(events: list[dict]) -> list:
def entry_keys(log: list[dict]) -> list:
"""Get a list of keys from the log."""
keys = []
for event in events:
keys.append(list(event.keys())[0])
for entry in log:
keys.append(list(entry.keys())[0])
return keys


def has_event(events: list[dict], key) -> bool:
for event in events:
if event.get(key):
def has_entry(log: list[dict], key) -> bool:
"""Check if log has entry based on key."""
for entry in log:
if entry.get(key):
return True

return False


def get_event_value(events: list[dict], key, subkey) -> Any:
for event in events:
if event.get(key) and event.get(key).get(subkey):
return event.get(key).get(subkey)
def get_entry_value(log: list[dict], key, subkey) -> Any:
"""Return the value of a log entry based on key."""
for entry in log:
if entry.get(key) and entry.get(key).get(subkey):
return entry.get(key).get(subkey)

return None


class MockAdapter(MotionDimmerAdapter):
"""Mock adapter for testing."""

# Override the properties so they can be set manually.
are_triggers_on: bool = False
brightness_min: int = 0
Expand All @@ -303,7 +307,7 @@ class MockAdapter(MotionDimmerAdapter):

def __init__(self):
# Initialize with the default values.
self._events: list = []
self._log: list = []
self.are_triggers_on = False
self.brightness_min = DEFAULT_MIN_BRIGHTNESS
self.disabled_until = now()
Expand All @@ -324,23 +328,24 @@ def __init__(self):
self.timer = TimerState(now(), "00:00:00", SENSOR_IDLE)
self._state_change = None

def flush_events(self):
events = self._events
self._events = []
return events
def flush_entries(self):
"""Return the entries and clear the log."""
log = self._log
self._log = []
return log

def cancel_periodic_timer(self) -> None:
self._events.append({"cancel_periodic_timer": True})
self._log.append({"cancel_periodic_timer": True})

def cancel_timer(self) -> None:
self._events.append({"cancel_timer": True})
self._log.append({"cancel_timer": True})

def dimmer_state_callback(self, *args, **kwargs) -> None:
self._events.append({"dimmer_state_callback": kwargs})
self._log.append({"dimmer_state_callback": kwargs})
return self._state_change

def schedule_periodic_timer(self, time, callback) -> None:
self._events.append(
self._log.append(
{
"schedule_periodic_timer": {
"secs": secs(time),
Expand All @@ -350,7 +355,7 @@ def schedule_periodic_timer(self, time, callback) -> None:
)

def schedule_pump_timer(self, time, callback) -> None:
self._events.append(
self._log.append(
{
"schedule_pump_timer": {
"secs": secs(time),
Expand All @@ -360,7 +365,7 @@ def schedule_pump_timer(self, time, callback) -> None:
)

def schedule_timer(self, time: datetime, duration: str, callback) -> None:
self._events.append(
self._log.append(
{
"schedule_timer": {
"secs": secs(time),
Expand All @@ -371,10 +376,10 @@ def schedule_timer(self, time: datetime, duration: str, callback) -> None:
)

def set_temporarily_disabled(self, next_time: datetime):
self._events.append({"set_temporarily_disabled": {"secs": secs(next_time)}})
self._log.append({"set_temporarily_disabled": {"secs": secs(next_time)}})

def track_timer(self, timer_end, duration, state) -> None:
self._events.append(
self._log.append(
{
"track_timer": {
"secs": secs(timer_end),
Expand All @@ -385,10 +390,10 @@ def track_timer(self, timer_end, duration, state) -> None:
)

def turn_on_dimmer(self, **kwargs) -> None:
self._events.append({"turn_on_dimmer": kwargs})
self._log.append({"turn_on_dimmer": kwargs})

def turn_off_dimmer(self) -> None:
self._events.append({"turn_off_dimmer": True})
self._log.append({"turn_off_dimmer": True})

def turn_on_script(self) -> None:
self._events.append({"turn_on_script": True})
self._log.append({"turn_on_script": True})
19 changes: 19 additions & 0 deletions tests/test_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from homeassistant.components.script import DOMAIN as SCRIPT_DOMAIN
from homeassistant.components.light import (
ColorMode,
ATTR_COLOR_TEMP,
ATTR_RGB_COLOR,
)
from homeassistant.core import HomeAssistant
from homeassistant.util.dt import now, utcnow
Expand All @@ -31,6 +33,7 @@
event_extract,
from_pct,
setup_integration,
set_segment_light_to,
)

from .const import (
Expand Down Expand Up @@ -70,18 +73,33 @@ async def test_home_assistant_adapter(hass: HomeAssistant):
assert -1 < delta < 1
assert timer.duration == "00:00:00"

# Change color temp to test color mode.
await set_segment_light_to(hass, "seg_1", "turn_on", {ATTR_COLOR_TEMP: 500})
assert adapter.color_temp == 500
assert adapter.color_mode == ColorMode.COLOR_TEMP

# Change color to test color mode.
await set_segment_light_to(
hass, "seg_1", "turn_on", {ATTR_RGB_COLOR: (255, 0, 0)}
)
assert adapter.rgb_color == (255, 0, 0)
assert adapter.color_mode == ColorMode.RGB

# Test setting temporary disable.
events = async_capture_events(hass, "call_service")
await adapter.async_set_temporarily_disabled(now())
await hass.async_block_till_done()
assert event_extract(events, "domain") == DATETIME_DOMAIN
assert event_extract(events, "service") == "set_value"

# Test turn on dimmer.
events.clear()
await adapter.async_turn_on_dimmer()
await hass.async_block_till_done()
assert event_extract(events, "domain") == LIGHT_DOMAIN
assert event_extract(events, "service") == "turn_on"

# Test turn off dimmer.
events.clear()
await adapter.async_turn_off_dimmer()
await hass.async_block_till_done()
Expand All @@ -90,6 +108,7 @@ async def test_home_assistant_adapter(hass: HomeAssistant):

await advance_time(hass, 1000, frozen_time)

# Test turn on script.
events.clear()
await adapter.async_turn_on_script()
await hass.async_block_till_done()
Expand Down
2 changes: 1 addition & 1 deletion tests/test_config_flow.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Test the SmartThinQ sensors config flow."""
"""Test the config flow."""

import logging

Expand Down
17 changes: 2 additions & 15 deletions tests/test_features.py
Original file line number Diff line number Diff line change
@@ -1,45 +1,32 @@
"""Test Motion Dimmer setup process."""
"""Test Motion Dimmer features."""

import logging
from freezegun import freeze_time
from homeassistant.util.dt import utcnow
from homeassistant.core import HomeAssistant, State
from homeassistant.core import HomeAssistant
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
)
from pytest_homeassistant_custom_component.common import (
async_capture_events,
mock_state_change_event,
)

from custom_components.motion_dimmer.const import (
DEFAULT_PREDICTION_BRIGHTNESS,
DEFAULT_PREDICTION_SECS,
DEFAULT_MANUAL_OVERRIDE,
PUMP_TIME,
ControlEntities,
)
from tests import (
advance_time,
dimmer_is_not_temporarily_disabled,
dimmer_is_off,
dimmer_is_set_to,
from_pct,
get_disable_delta,
let_dimmer_turn_off,
set_number_field_to,
set_segment_light_to,
setup_integration,
event_extract,
trigger_motion_dimmer,
turn_off_trigger,
turn_on_segment,
)

from .const import (
MOCK_LIGHT_1_ID,
SMALL_TIME,
)

logging.basicConfig(level=logging.ERROR, force=True)
_LOGGER = logging.getLogger(__name__)
Expand Down
17 changes: 8 additions & 9 deletions tests/test_light.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
"""Test Motion Dimmer setup process."""
"""Test Motion Dimmer light."""

import logging

from freezegun import freeze_time
from homeassistant.util.dt import utcnow
from homeassistant.core import HomeAssistant
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
ATTR_COLOR_TEMP,
ATTR_RGB_COLOR,
ATTR_TRANSITION,
ATTR_WHITE,
)
from homeassistant.core import HomeAssistant
from homeassistant.util.dt import utcnow
from pytest_homeassistant_custom_component.common import (
async_capture_events,
)

from custom_components.motion_dimmer.const import (
DEFAULT_SEG_SECONDS,
Expand All @@ -20,10 +24,10 @@
from tests import (
advance_time,
dimmer_is_set_to,
event_extract,
let_dimmer_turn_off,
set_segment_light_to,
setup_integration,
event_extract,
trigger_motion_dimmer,
)

Expand All @@ -33,11 +37,6 @@
SWITCH_DOMAIN,
)

from pytest_homeassistant_custom_component.common import (
async_capture_events,
mock_state_change_event,
)

_LOGGER = logging.getLogger(__name__)
logging.basicConfig(level=logging.ERROR, force=True)

Expand Down
Loading

0 comments on commit 4773a87

Please sign in to comment.