|
6 | 6 | import logging |
7 | 7 | from typing import Any |
8 | 8 |
|
| 9 | +from ns_api import Trip |
9 | 10 | import voluptuous as vol |
10 | 11 |
|
11 | 12 | from homeassistant.components.sensor import ( |
|
38 | 39 | ) |
39 | 40 | from .coordinator import NSConfigEntry, NSDataUpdateCoordinator |
40 | 41 |
|
| 42 | + |
| 43 | +def _get_departure_time(trip: Trip | None) -> datetime | None: |
| 44 | + """Get next departure time from trip data.""" |
| 45 | + return trip.departure_time_actual or trip.departure_time_planned if trip else None |
| 46 | + |
| 47 | + |
| 48 | +def _get_time_str(time: datetime | None) -> str | None: |
| 49 | + """Get time as string.""" |
| 50 | + return time.strftime("%H:%M") if time else None |
| 51 | + |
| 52 | + |
| 53 | +def _get_route(trip: Trip | None) -> list[str]: |
| 54 | + """Get the route as a list of station names from trip data.""" |
| 55 | + if not trip or not (trip_parts := trip.trip_parts): |
| 56 | + return [] |
| 57 | + route = [] |
| 58 | + if departure := trip.departure: |
| 59 | + route.append(departure) |
| 60 | + route.extend(part.destination for part in trip_parts) |
| 61 | + return route |
| 62 | + |
| 63 | + |
| 64 | +def _get_delay(planned: datetime | None, actual: datetime | None) -> bool: |
| 65 | + """Return True if delay is present, False otherwise.""" |
| 66 | + return bool(planned and actual and planned != actual) |
| 67 | + |
| 68 | + |
41 | 69 | _LOGGER = logging.getLogger(__name__) |
42 | 70 |
|
43 | 71 | ROUTE_SCHEMA = vol.Schema( |
@@ -163,94 +191,38 @@ def native_value(self) -> datetime | None: |
163 | 191 | return None |
164 | 192 |
|
165 | 193 | first_trip = route_data.first_trip |
166 | | - if first_trip.departure_time_actual: |
167 | | - return first_trip.departure_time_actual |
168 | | - return first_trip.departure_time_planned |
| 194 | + return _get_departure_time(first_trip) |
169 | 195 |
|
170 | 196 | @property |
171 | 197 | def extra_state_attributes(self) -> dict[str, Any] | None: |
172 | 198 | """Return the state attributes.""" |
173 | | - route_data = self.coordinator.data |
174 | | - if not route_data: |
175 | | - return None |
176 | | - |
177 | | - first_trip = route_data.first_trip |
178 | | - next_trip = route_data.next_trip |
| 199 | + first_trip = self.coordinator.data.first_trip |
| 200 | + next_trip = self.coordinator.data.next_trip |
179 | 201 |
|
180 | 202 | if not first_trip: |
181 | 203 | return None |
182 | 204 |
|
183 | | - route = [] |
184 | | - if first_trip.trip_parts: |
185 | | - route = [first_trip.departure] |
186 | | - route.extend(k.destination for k in first_trip.trip_parts) |
187 | | - |
188 | | - # Static attributes |
189 | | - attributes = { |
| 205 | + return { |
190 | 206 | "going": first_trip.going, |
191 | | - "departure_time_planned": None, |
192 | | - "departure_time_actual": None, |
193 | | - "departure_delay": False, |
| 207 | + "departure_time_planned": _get_time_str(first_trip.departure_time_planned), |
| 208 | + "departure_time_actual": _get_time_str(first_trip.departure_time_actual), |
| 209 | + "departure_delay": _get_delay( |
| 210 | + first_trip.departure_time_planned, |
| 211 | + first_trip.departure_time_actual, |
| 212 | + ), |
194 | 213 | "departure_platform_planned": first_trip.departure_platform_planned, |
195 | 214 | "departure_platform_actual": first_trip.departure_platform_actual, |
196 | | - "arrival_time_planned": None, |
197 | | - "arrival_time_actual": None, |
198 | | - "arrival_delay": False, |
| 215 | + "arrival_time_planned": _get_time_str(first_trip.arrival_time_planned), |
| 216 | + "arrival_time_actual": _get_time_str(first_trip.arrival_time_actual), |
| 217 | + "arrival_delay": _get_delay( |
| 218 | + first_trip.arrival_time_planned, |
| 219 | + first_trip.arrival_time_actual, |
| 220 | + ), |
199 | 221 | "arrival_platform_planned": first_trip.arrival_platform_planned, |
200 | 222 | "arrival_platform_actual": first_trip.arrival_platform_actual, |
201 | | - "next": None, |
| 223 | + "next": _get_time_str(_get_departure_time(next_trip)), |
202 | 224 | "status": first_trip.status.lower() if first_trip.status else None, |
203 | 225 | "transfers": first_trip.nr_transfers, |
204 | | - "route": route, |
| 226 | + "route": _get_route(first_trip), |
205 | 227 | "remarks": None, |
206 | 228 | } |
207 | | - |
208 | | - # Planned departure attributes |
209 | | - if first_trip.departure_time_planned is not None: |
210 | | - attributes["departure_time_planned"] = ( |
211 | | - first_trip.departure_time_planned.strftime("%H:%M") |
212 | | - ) |
213 | | - |
214 | | - # Actual departure attributes |
215 | | - if first_trip.departure_time_actual is not None: |
216 | | - attributes["departure_time_actual"] = ( |
217 | | - first_trip.departure_time_actual.strftime("%H:%M") |
218 | | - ) |
219 | | - |
220 | | - # Delay departure attributes |
221 | | - if ( |
222 | | - attributes["departure_time_planned"] |
223 | | - and attributes["departure_time_actual"] |
224 | | - and attributes["departure_time_planned"] |
225 | | - != attributes["departure_time_actual"] |
226 | | - ): |
227 | | - attributes["departure_delay"] = True |
228 | | - |
229 | | - # Planned arrival attributes |
230 | | - if first_trip.arrival_time_planned is not None: |
231 | | - attributes["arrival_time_planned"] = ( |
232 | | - first_trip.arrival_time_planned.strftime("%H:%M") |
233 | | - ) |
234 | | - |
235 | | - # Actual arrival attributes |
236 | | - if first_trip.arrival_time_actual is not None: |
237 | | - attributes["arrival_time_actual"] = first_trip.arrival_time_actual.strftime( |
238 | | - "%H:%M" |
239 | | - ) |
240 | | - |
241 | | - # Delay arrival attributes |
242 | | - if ( |
243 | | - attributes["arrival_time_planned"] |
244 | | - and attributes["arrival_time_actual"] |
245 | | - and attributes["arrival_time_planned"] != attributes["arrival_time_actual"] |
246 | | - ): |
247 | | - attributes["arrival_delay"] = True |
248 | | - |
249 | | - # Next trip attributes |
250 | | - if next_trip: |
251 | | - if next_trip.departure_time_actual is not None: |
252 | | - attributes["next"] = next_trip.departure_time_actual.strftime("%H:%M") |
253 | | - elif next_trip.departure_time_planned is not None: |
254 | | - attributes["next"] = next_trip.departure_time_planned.strftime("%H:%M") |
255 | | - |
256 | | - return attributes |
0 commit comments