Skip to content

Commit bbc054c

Browse files
Optimized API usage, added departures filtering
1 parent 4767d61 commit bbc054c

File tree

3 files changed

+66
-33
lines changed

3 files changed

+66
-33
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ This sensor uses unofficial API to get data from [*Rozkładzik.pl*](https://www.
2020
| `id` | ID of stop |
2121
| `name` | Name of stop |
2222
| `stops_group_mode` | Enables stops group mode. Possible values: `true`, `false`. |
23+
| `lines` | `list` | `False` | all available | List of monitored lines. |
24+
| `directions` | `list` | `False` | all available | List of monitored directions. |
2325

2426
## Example usage
2527

@@ -30,9 +32,13 @@ sensor:
3032
stops:
3133
- id: 1281
3234
name: 'Plac Grunwaldzki'
35+
directions:
36+
- "Reja"
3337
- id: 94
3438
name: 'Rynek'
3539
stops_group_mode: true
40+
lines:
41+
- "33"
3642
```
3743

3844
## Installation

custom_components/rozkladzik/sensor.py

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
CONF_STOP_ID = 'id'
1414
CONF_STOP_NAME = 'name'
1515
CONF_GROUP_MODE = 'stops_group_mode'
16+
CONF_LINES = 'lines'
17+
CONF_DIRECTIONS = 'directions'
1618
CONF_CITY = 'city'
1719

1820
DEFAULT_NAME = 'Rozkładzik'
@@ -25,6 +27,8 @@
2527
vol.Required(CONF_STOP_ID): cv.positive_int,
2628
vol.Required(CONF_STOP_NAME): cv.string,
2729
vol.Optional(CONF_GROUP_MODE, default=False): cv.boolean,
30+
vol.Optional(CONF_LINES, default=[]): cv.ensure_list,
31+
vol.Optional(CONF_DIRECTIONS, default=[]): cv.ensure_list
2832
})])
2933
})
3034

@@ -38,22 +42,27 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
3842
stop_id = stop.get(CONF_STOP_ID)
3943
stop_name = stop.get(CONF_STOP_NAME)
4044
group_mode = stop.get(CONF_GROUP_MODE)
45+
lines = stop.get(CONF_LINES)
46+
directions = stop.get(CONF_DIRECTIONS)
4147
uid = '{}_{}_{}'.format(name, city, stop_id)
4248
entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, uid, hass=hass)
43-
dev.append(RozkladzikSensor(entity_id, name, city, stop_id, stop_name, group_mode))
49+
dev.append(RozkladzikSensor(entity_id, name, city, stop_id, stop_name, group_mode, lines, directions))
4450
add_entities(dev, True)
4551

4652

4753
class RozkladzikSensor(Entity):
48-
def __init__(self, entity_id, name, city, stop_id, stop_name, group_mode):
54+
def __init__(self, entity_id, name, city, stop_id, stop_name, group_mode, watched_lines, watched_directions):
4955
self.entity_id = entity_id
5056
self._name = name
5157
self._stop_id = stop_id
5258
self._stop_name = stop_name
5359
self._city = city
5460
self._city_data = self.get_city_data()
5561
self._group_mode = group_mode
56-
self._departures_number = None
62+
self._watched_lines = watched_lines
63+
self._watched_directions = watched_directions
64+
self._last_response = None
65+
self._departures_number = 0
5766
self._departures_ordered = []
5867
self._departures_by_line = dict()
5968
self._state = None
@@ -90,35 +99,47 @@ def device_state_attributes(self):
9099
def update(self):
91100
now = datetime.datetime.now()
92101
r_time = now.hour * 60 + now.minute
93-
url_template = 'https://www.rozkladzik.pl/{}/timetable.txt?c=tsa&t={}&day={}&time={}'
94-
if self._group_mode:
95-
url_template = 'https://www.rozkladzik.pl/{}/timetable.txt?c=bsa&b={}&day={}&time={}'
96-
response = requests.get(url_template.format(self._city, self._stop_id, now.weekday(), r_time))
97-
if response.status_code == 200 and response.content.__len__() > 0:
98-
raw_array = response.text.split("|")
99-
self._departures_ordered = []
100-
self._departures_by_line = dict()
101-
departures_by_line = dict()
102-
lines_directions = dict()
103-
for r in raw_array:
104-
line, direction_number, departures = self.process_raw(r, r_time)
105-
direction = self.get_direction(line, direction_number)
106-
if not line in lines_directions:
107-
lines_directions[line] = []
108-
lines_directions[line].append(direction)
109-
departures_by_line[(line, direction)] = []
110-
for departure_time, departure_diff in departures:
111-
self._departures_ordered.append((line, direction, departure_time, departure_diff))
112-
departures_by_line[(line, direction)].append((departure_time, departure_diff))
113-
departures_by_line[(line, direction)].sort(key=lambda e: e[1])
114-
for line in lines_directions:
115-
self._departures_by_line[line] = dict()
116-
for direction in lines_directions[line]:
117-
self._departures_by_line[line][direction] = []
118-
for departure in departures_by_line[(line, direction)]:
119-
self._departures_by_line[line][direction].append(departure)
120-
self._departures_ordered.sort(key=lambda e: e[3])
121-
self._departures_number = len(self._departures_ordered)
102+
if self._should_update(now):
103+
url_template = 'https://www.rozkladzik.pl/{}/timetable.txt?c=tsa&t={}&day={}&time={}'
104+
if self._group_mode:
105+
url_template = 'https://www.rozkladzik.pl/{}/timetable.txt?c=bsa&b={}&day={}&time={}'
106+
response = requests.get(url_template.format(self._city, self._stop_id, now.weekday(), r_time))
107+
if response.status_code == 200 and response.content.__len__() > 0:
108+
self._last_response = response.text
109+
if self._last_response is not None:
110+
self.update_values_for_time(r_time)
111+
112+
def _should_update(self, now):
113+
return self._last_response is None or self._departures_ordered is None or len(self._departures_ordered) == 0 or self._departures_ordered[0][4] < now
114+
115+
def update_values_for_time(self, r_time):
116+
raw_array = self._last_response.split("|")
117+
self._departures_ordered = []
118+
self._departures_by_line = dict()
119+
departures_by_line = dict()
120+
lines_directions = dict()
121+
for r in raw_array:
122+
line, direction_number, departures = self.process_raw(r, r_time)
123+
direction = self.get_direction(line, direction_number)
124+
if len(self._watched_lines) > 0 and line not in self._watched_lines \
125+
or len(self._watched_directions) > 0 and direction not in self._watched_directions:
126+
continue
127+
if not line in lines_directions:
128+
lines_directions[line] = []
129+
lines_directions[line].append(direction)
130+
departures_by_line[(line, direction)] = []
131+
for departure_time, departure_diff, departure_timestamp in departures:
132+
self._departures_ordered.append((line, direction, departure_time, departure_diff, departure_timestamp))
133+
departures_by_line[(line, direction)].append((departure_time, departure_diff))
134+
departures_by_line[(line, direction)].sort(key=lambda e: e[1])
135+
for line in lines_directions:
136+
self._departures_by_line[line] = dict()
137+
for direction in lines_directions[line]:
138+
self._departures_by_line[line][direction] = []
139+
for departure in departures_by_line[(line, direction)]:
140+
self._departures_by_line[line][direction].append(departure)
141+
self._departures_ordered.sort(key=lambda e: e[3])
142+
self._departures_number = len(self._departures_ordered)
122143

123144
def get_html(self):
124145
html = '<table width="100%" border=1 style="border: 1px black solid; border-collapse: collapse;">\n'
@@ -178,5 +199,5 @@ def process_raw(raw, now):
178199
hour = time // 60
179200
minute = time % 60
180201
t = "{:02}:{:02}".format(hour, minute)
181-
times.append((t, diff))
202+
times.append((t, diff, time))
182203
return line, direction_number, times

info.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
| `id` | ID of stop |
1414
| `name` | Name of stop |
1515
| `stops_group_mode` | Enables stops group mode. Possible values: `true`, `false`. |
16+
| `lines` | `list` | `False` | all available | List of monitored lines. |
17+
| `directions` | `list` | `False` | all available | List of monitored directions. |
1618

1719
## Example usage
1820

@@ -23,9 +25,13 @@ sensor:
2325
stops:
2426
- id: 1281
2527
name: 'Plac Grunwaldzki'
28+
directions:
29+
- "Reja"
2630
- id: 94
2731
name: 'Rynek'
2832
stops_group_mode: true
33+
lines:
34+
- "33"
2935
```
3036

3137
## Hints

0 commit comments

Comments
 (0)