Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Support for Irish Rail RTPI information."""
2 
3 from __future__ import annotations
4 
5 from datetime import timedelta
6 from typing import Any
7 
8 from pyirishrail.pyirishrail import IrishRailRTPI
9 import voluptuous as vol
10 
12  PLATFORM_SCHEMA as SENSOR_PLATFORM_SCHEMA,
13  SensorEntity,
14 )
15 from homeassistant.const import CONF_NAME, UnitOfTime
16 from homeassistant.core import HomeAssistant
18 from homeassistant.helpers.entity_platform import AddEntitiesCallback
19 from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
20 
21 ATTR_STATION = "Station"
22 ATTR_ORIGIN = "Origin"
23 ATTR_DESTINATION = "Destination"
24 ATTR_DIRECTION = "Direction"
25 ATTR_STOPS_AT = "Stops at"
26 ATTR_DUE_IN = "Due in"
27 ATTR_DUE_AT = "Due at"
28 ATTR_EXPECT_AT = "Expected at"
29 ATTR_NEXT_UP = "Later Train"
30 ATTR_TRAIN_TYPE = "Train type"
31 
32 CONF_STATION = "station"
33 CONF_DESTINATION = "destination"
34 CONF_DIRECTION = "direction"
35 CONF_STOPS_AT = "stops_at"
36 
37 DEFAULT_NAME = "Next Train"
38 
39 
40 SCAN_INTERVAL = timedelta(minutes=2)
41 TIME_STR_FORMAT = "%H:%M"
42 
43 PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend(
44  {
45  vol.Required(CONF_STATION): cv.string,
46  vol.Optional(CONF_DIRECTION): cv.string,
47  vol.Optional(CONF_DESTINATION): cv.string,
48  vol.Optional(CONF_STOPS_AT): cv.string,
49  vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
50  }
51 )
52 
53 
55  hass: HomeAssistant,
56  config: ConfigType,
57  add_entities: AddEntitiesCallback,
58  discovery_info: DiscoveryInfoType | None = None,
59 ) -> None:
60  """Set up the Irish Rail transport sensor."""
61 
62  station = config.get(CONF_STATION)
63  direction = config.get(CONF_DIRECTION)
64  destination = config.get(CONF_DESTINATION)
65  stops_at = config.get(CONF_STOPS_AT)
66  name = config.get(CONF_NAME)
67 
68  irish_rail = IrishRailRTPI()
69  data = IrishRailTransportData(irish_rail, station, direction, destination, stops_at)
71  [
73  data, station, direction, destination, stops_at, name
74  )
75  ],
76  True,
77  )
78 
79 
81  """Implementation of an irish rail public transport sensor."""
82 
83  _attr_attribution = "Data provided by Irish Rail"
84  _attr_icon = "mdi:train"
85 
86  def __init__(self, data, station, direction, destination, stops_at, name):
87  """Initialize the sensor."""
88  self.datadata = data
89  self._station_station = station
90  self._direction_direction = direction
91  self._direction_direction = direction
92  self._stops_at_stops_at = stops_at
93  self._name_name = name
94  self._state_state = None
95  self._times_times = []
96 
97  @property
98  def name(self):
99  """Return the name of the sensor."""
100  return self._name_name
101 
102  @property
103  def native_value(self):
104  """Return the state of the sensor."""
105  return self._state_state
106 
107  @property
108  def extra_state_attributes(self) -> dict[str, Any] | None:
109  """Return the state attributes."""
110  if self._times_times:
111  next_up = "None"
112  if len(self._times_times) > 1:
113  next_up = (
114  f"{self._times[1][ATTR_ORIGIN]} to "
115  f"{self._times[1][ATTR_DESTINATION]} in "
116  f"{self._times[1][ATTR_DUE_IN]}"
117  )
118 
119  return {
120  ATTR_STATION: self._station_station,
121  ATTR_ORIGIN: self._times_times[0][ATTR_ORIGIN],
122  ATTR_DESTINATION: self._times_times[0][ATTR_DESTINATION],
123  ATTR_DUE_IN: self._times_times[0][ATTR_DUE_IN],
124  ATTR_DUE_AT: self._times_times[0][ATTR_DUE_AT],
125  ATTR_EXPECT_AT: self._times_times[0][ATTR_EXPECT_AT],
126  ATTR_DIRECTION: self._times_times[0][ATTR_DIRECTION],
127  ATTR_STOPS_AT: self._times_times[0][ATTR_STOPS_AT],
128  ATTR_NEXT_UP: next_up,
129  ATTR_TRAIN_TYPE: self._times_times[0][ATTR_TRAIN_TYPE],
130  }
131  return None
132 
133  @property
135  """Return the unit this state is expressed in."""
136  return UnitOfTime.MINUTES
137 
138  def update(self) -> None:
139  """Get the latest data and update the states."""
140  self.datadata.update()
141  self._times_times = self.datadata.info
142  if self._times_times:
143  self._state_state = self._times_times[0][ATTR_DUE_IN]
144  else:
145  self._state_state = None
146 
147 
149  """The Class for handling the data retrieval."""
150 
151  def __init__(self, irish_rail, station, direction, destination, stops_at):
152  """Initialize the data object."""
153  self._ir_api_ir_api = irish_rail
154  self.stationstation = station
155  self.directiondirection = direction
156  self.destinationdestination = destination
157  self.stops_atstops_at = stops_at
158  self.infoinfo = self._empty_train_data_empty_train_data()
159 
160  def update(self):
161  """Get the latest data from irishrail."""
162  trains = self._ir_api_ir_api.get_station_by_name(
163  self.stationstation,
164  direction=self.directiondirection,
165  destination=self.destinationdestination,
166  stops_at=self.stops_atstops_at,
167  )
168  stops_at = self.stops_atstops_at if self.stops_atstops_at else ""
169  self.infoinfo = []
170  for train in trains:
171  train_data = {
172  ATTR_STATION: self.stationstation,
173  ATTR_ORIGIN: train.get("origin"),
174  ATTR_DESTINATION: train.get("destination"),
175  ATTR_DUE_IN: train.get("due_in_mins"),
176  ATTR_DUE_AT: train.get("scheduled_arrival_time"),
177  ATTR_EXPECT_AT: train.get("expected_departure_time"),
178  ATTR_DIRECTION: train.get("direction"),
179  ATTR_STOPS_AT: stops_at,
180  ATTR_TRAIN_TYPE: train.get("type"),
181  }
182  self.infoinfo.append(train_data)
183 
184  if not self.infoinfo:
185  self.infoinfo = self._empty_train_data_empty_train_data()
186 
187  def _empty_train_data(self):
188  """Generate info for an empty train."""
189  dest = self.destinationdestination if self.destinationdestination else ""
190  direction = self.directiondirection if self.directiondirection else ""
191  stops_at = self.stops_atstops_at if self.stops_atstops_at else ""
192  return [
193  {
194  ATTR_STATION: self.stationstation,
195  ATTR_ORIGIN: "",
196  ATTR_DESTINATION: dest,
197  ATTR_DUE_IN: "n/a",
198  ATTR_DUE_AT: "n/a",
199  ATTR_EXPECT_AT: "n/a",
200  ATTR_DIRECTION: direction,
201  ATTR_STOPS_AT: stops_at,
202  ATTR_TRAIN_TYPE: "",
203  }
204  ]
def __init__(self, irish_rail, station, direction, destination, stops_at)
Definition: sensor.py:151
def __init__(self, data, station, direction, destination, stops_at, name)
Definition: sensor.py:86
def add_entities(account, async_add_entities, tracked)
Definition: sensor.py:40
None setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback add_entities, DiscoveryInfoType|None discovery_info=None)
Definition: sensor.py:59