Skip to content

Commit 1ca6d9b

Browse files
Merge pull request #42 from andrew-codechimp/mypy
Add mypy and fixes
2 parents 0bb01af + 6a13a83 commit 1ca6d9b

File tree

4 files changed

+41
-35
lines changed

4 files changed

+41
-35
lines changed

.github/workflows/lint.yml

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,26 +31,26 @@ jobs:
3131
with:
3232
args: format --check --diff
3333

34-
# mypy:
35-
# runs-on: ubuntu-latest
34+
mypy:
35+
runs-on: ubuntu-latest
3636

37-
# steps:
38-
# - name: Checkout code
39-
# uses: actions/checkout@v5
37+
steps:
38+
- name: Checkout code
39+
uses: actions/checkout@v5
4040

41-
# - name: Install uv
42-
# uses: astral-sh/setup-uv@v7
41+
- name: Install uv
42+
uses: astral-sh/setup-uv@v7
4343

44-
# - name: Set up Python
45-
# uses: actions/setup-python@v6
46-
# with:
47-
# python-version-file: "pyproject.toml"
44+
- name: Set up Python
45+
uses: actions/setup-python@v6
46+
with:
47+
python-version-file: "pyproject.toml"
4848

49-
# - name: Install dependencies
50-
# run: uv sync
49+
- name: Install dependencies
50+
run: uv sync
5151

52-
# - name: Run mypy
53-
# run: uv run mypy
52+
- name: Run mypy
53+
run: uv run mypy
5454

5555
tests:
5656
runs-on: ubuntu-latest

custom_components/calendar_event/binary_sensor.py

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
from __future__ import annotations
44

5-
from datetime import datetime, timedelta
5+
from asyncio import TimerHandle
6+
from datetime import timedelta
67

78
from homeassistant.core import Event, HomeAssistant, callback
89
from homeassistant.const import EVENT_STATE_CHANGED
10+
from homeassistant.util.dt import utcnow
911
from homeassistant.helpers.event import async_track_entity_registry_updated_event
1012
from homeassistant.config_entries import ConfigEntry
1113
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
@@ -88,21 +90,23 @@ def __init__(
8890

8991
self._attr_is_on = False
9092
self._attr_extra_state_attributes = {}
91-
self._call_later_handle = None
93+
self._call_later_handle: TimerHandle | None = None
9294

9395
async def async_added_to_hass(self) -> None:
9496
"""Handle added to Hass."""
9597
await super().async_added_to_hass()
9698

9799
# Add state listener for the calendar entity
98100
self.async_on_remove(
99-
self._hass.bus.async_listen(EVENT_STATE_CHANGED, self._state_changed)
101+
self._hass.bus.async_listen(EVENT_STATE_CHANGED, self._state_changed) # type: ignore[arg-type]
100102
)
101103

102104
# Track entity registry updates to detect when entity is disabled/enabled
103105
self.async_on_remove(
104106
async_track_entity_registry_updated_event(
105-
self._hass, self.entity_id, self._entity_registry_updated
107+
self._hass,
108+
self.entity_id,
109+
self._entity_registry_updated, # type: ignore[arg-type]
106110
)
107111
)
108112

@@ -115,14 +119,6 @@ def _entity_registry_updated(self, event: Event) -> None:
115119
if not self.enabled:
116120
self._cancel_call_later()
117121

118-
async def async_entity_registry_updated(self) -> None:
119-
"""Handle entity registry update."""
120-
await super().async_entity_registry_updated()
121-
122-
# Cancel any pending timers if the entity is disabled
123-
if not self.enabled:
124-
self._cancel_call_later()
125-
126122
def _cancel_call_later(self) -> None:
127123
"""Cancel any pending call_later."""
128124
if self._call_later_handle is not None:
@@ -187,7 +183,7 @@ async def _update_state(self) -> None:
187183

188184
# Schedule next update only if calendar is on and entity is enabled
189185
if calendar_state.state == "on" and self.enabled:
190-
now = datetime.now()
186+
now = utcnow()
191187
seconds_until_next_minute = 60 - now.second
192188
self._call_later_handle = self._hass.loop.call_later(
193189
seconds_until_next_minute,
@@ -210,11 +206,11 @@ def _matches_criteria(self, event_summary: str) -> bool:
210206
# Default to contains if unknown criteria
211207
return summary_lower in event_summary_lower
212208

213-
async def _get_event_matching_summary(self) -> Event | None:
209+
async def _get_event_matching_summary(self) -> dict | None:
214210
"""Check if the summary is in the calendar events."""
215211

216212
# Fetch all events for the calendar entity using the get_events service
217-
now = datetime.now()
213+
now = utcnow()
218214
end_date_time = (now + timedelta(hours=1)).isoformat()
219215

220216
events = await self._hass.services.async_call(
@@ -228,11 +224,21 @@ async def _get_event_matching_summary(self) -> Event | None:
228224
return_response=True,
229225
)
230226

231-
calendar_events = events.get(self._calendar_entity_id, {}).get("events", [])
227+
if not isinstance(events, dict):
228+
return None
229+
230+
calendar_data = events.get(self._calendar_entity_id, {})
231+
if not isinstance(calendar_data, dict):
232+
return None
233+
234+
calendar_events = calendar_data.get("events", [])
235+
if not isinstance(calendar_events, list):
236+
return None
232237
for event in calendar_events:
233238
if not isinstance(event, dict):
234239
continue
235-
if self._matches_criteria(event.get("summary", "")):
240+
summary = event.get("summary", "")
241+
if isinstance(summary, str) and self._matches_criteria(summary):
236242
return event
237243

238244
return None

custom_components/calendar_event/config_flow.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
): selector.SelectSelector(
3434
selector.SelectSelectorConfig(
3535
options=_COMPARISON_METHODS,
36-
mode="dropdown",
36+
mode=selector.SelectSelectorMode.DROPDOWN,
3737
translation_key=CONF_COMPARISON_METHOD,
3838
),
3939
),

scripts/lint

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ cd "$(dirname "$0")/.."
77
echo "Running ruff check..."
88
uv run ruff check . --fix
99

10-
# echo "Running mypy..."
11-
# uv run mypy
10+
echo "Running mypy..."
11+
uv run mypy
1212

1313
echo "Running tests..."
1414
uv run pytest

0 commit comments

Comments
 (0)