Skip to content

Commit 3557d65

Browse files
authored
Update NSByt app (#3035)
1 parent 68081f1 commit 3557d65

File tree

1 file changed

+90
-45
lines changed

1 file changed

+90
-45
lines changed

apps/nsbyt/nsbyt.star

Lines changed: 90 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Applet: NS Timetable
33
Author: tim-hanssen
44
Summary: NS Timetable
5-
Description: Shows a timetable for a station in the Dutch Railways.
5+
Description: Shows a timetable for a station in the Netherlands (NS).
66
"""
77

88
load("cache.star", "cache")
@@ -21,6 +21,10 @@ INFO_BACKGROUND_COLOR = "#FF7700"
2121
MAINTENANCE_BACKGROUND_COLOR = "#FFB519"
2222
CANCELED_BACKGROUND_COLOR = "#DB0029"
2323

24+
TIME_GREEN = "#5fdb00"
25+
TIME_ORANGE = "#FF7700"
26+
TIME_RED = "#DB0029"
27+
2428
BLACK_TEXT_COLOR = "#000"
2529
CORE_TEXT_COLOR = "#FFFFFF"
2630
NORMAL_TEXT_COLOR = "#FFC917"
@@ -34,30 +38,31 @@ DEFAULT_STATION = "ehv"
3438
def main(config):
3539
station_id = config.str("station")
3640
station_dest = config.str("dest_station")
37-
skiptime = config.get("skiptime", 0)
41+
skip_time = config.get("skiptime", 0)
42+
time_to_leave = config.bool("time_to_leave", False)
3843

3944
if station_id == None:
4045
station_id = DEFAULT_STATION
4146
else:
4247
station_id = json.decode(station_id)["value"]
4348

44-
# Check if we need to convert the skiptime to Int
45-
if (skiptime):
46-
if type(skiptime) == "string":
47-
skiptime = int(skiptime)
49+
# Check if we need to convert the skip_time to Int
50+
if (skip_time):
51+
if type(skip_time) == "string":
52+
skip_time = int(skip_time)
4853

4954
# Check that the skip time is valid
50-
if skiptime < 0:
51-
skiptime = 0
55+
if skip_time < 0:
56+
skip_time = 0
5257

5358
# If we don't have a Trip, list trains for station.
5459
if station_dest == None:
5560
# Normal Train Operations
56-
stops = getTrains(station_id, skiptime)
61+
stops = getTrains(station_id, skip_time)
5762

5863
else:
5964
station_dest = json.decode(station_dest)["value"]
60-
stops = getTrip(station_id, station_dest, skiptime)
65+
stops = getTrip(station_id, station_dest, skip_time)
6166

6267
if stops == None or len(stops) == 0:
6368
return render.Root(
@@ -70,24 +75,24 @@ def main(config):
7075
)
7176

7277
if len(stops) == 1:
73-
return render.Root(child = renderTrain(stops[0]))
78+
return render.Root(child = renderTrain(stops[0], skip_time, time_to_leave))
7479

7580
return render.Root(
7681
show_full_animation = True,
7782
child = render.Column(
7883
children = [
79-
renderTrain(stops[0]),
84+
renderTrain(stops[0], skip_time, time_to_leave),
8085
render.Box(
8186
color = "#ffffff",
8287
width = 64,
8388
height = 1,
8489
),
85-
renderTrain(stops[1]),
90+
renderTrain(stops[1], skip_time, time_to_leave),
8691
],
8792
),
8893
)
8994

90-
def renderTrain(stop_info):
95+
def renderTrain(stop_info, skip_time, time_to_leave):
9196
backgroundColor = CORE_BACKGROUND_COLOR
9297
textColor = CORE_TEXT_COLOR
9398

@@ -103,8 +108,6 @@ def renderTrain(stop_info):
103108
departureTimeText = re.sub("(minutes|minute)", "min", departureTimeText)
104109
departureTimeText = re.sub("(seconds|second)", "sec", departureTimeText)
105110

106-
# destination = train + " " + destination
107-
108111
# Info messages.
109112
message = None
110113

@@ -198,35 +201,71 @@ def renderTrain(stop_info):
198201

199202
departureTimeRender = render.Animation(children = renderTimeChild)
200203

201-
return render.Row(
202-
expanded = True,
203-
main_align = "space_between",
204-
cross_align = "end",
205-
children = [
204+
# Render Time To Leave indicator
205+
timeToLeaveColor = TIME_GREEN
206+
207+
if time_to_leave == True:
208+
departureTimeInSeconds = (parse_time(stop_info["actualDateTime"]) - time.now()).seconds
209+
210+
# LESS THAN SKIP TIME + 3 MIN
211+
if departureTimeInSeconds < ((skip_time * 60) + 180):
212+
timeToLeaveColor = TIME_RED
213+
214+
# LESS THAN SKIP TIME + 6 MIN
215+
if departureTimeInSeconds < ((skip_time * 60) + 360):
216+
if departureTimeInSeconds > ((skip_time * 60) + 180):
217+
timeToLeaveColor = TIME_ORANGE
218+
219+
# Hide TTL indicator if cancelled
220+
if stop_info["cancelled"] == True:
221+
timeToLeaveColor = BLACK_TEXT_COLOR
222+
223+
# Render Final rows
224+
renderTrainFinal = []
225+
226+
if time_to_leave == True:
227+
renderTrainFinal.extend([
206228
render.Padding(
207-
pad = 2,
229+
pad = (0, 0, 0, 2),
208230
child = render.Box(
209-
width = 10,
231+
width = 2,
210232
height = 10,
211-
color = backgroundColor,
212-
child = render.Text(
213-
color = textColor,
214-
content = stop_info.get("actualTrack", "-"),
215-
),
233+
color = timeToLeaveColor,
216234
),
217235
),
218-
render.Column(
219-
children = [
220-
render.Marquee(
221-
width = 64 - 13,
222-
child = render.Text(
223-
content = destination.upper(),
224-
),
225-
),
226-
departureTimeRender,
227-
],
236+
])
237+
238+
renderTrainFinal.extend([
239+
render.Padding(
240+
pad = 2,
241+
child = render.Box(
242+
width = 10,
243+
height = 10,
244+
color = backgroundColor,
245+
child = render.Text(
246+
color = textColor,
247+
content = stop_info.get("actualTrack", "-"),
248+
),
228249
),
229-
],
250+
),
251+
render.Column(
252+
children = [
253+
render.Marquee(
254+
width = 64 - 14,
255+
child = render.Text(
256+
content = destination.upper(),
257+
),
258+
),
259+
departureTimeRender,
260+
],
261+
),
262+
])
263+
264+
return render.Row(
265+
expanded = True,
266+
main_align = "space_between",
267+
cross_align = "end",
268+
children = renderTrainFinal,
230269
)
231270

232271
def format_duration(d):
@@ -245,7 +284,7 @@ def parse_time(time_string):
245284
time_obj = time.parse_time(time_string[0:19], format = "2006-01-02T15:04:05", location = "Europe/Amsterdam")
246285
return time_obj
247286

248-
def getTrip(station_id, station_dest, skiptime):
287+
def getTrip(station_id, station_dest, skip_time):
249288
resp = http.get("https://gateway.apiportal.ns.nl/reisinformatie-api/api/v3/trips", params = {"fromStation": station_id, "toStation": station_dest}, headers = {"Ocp-Apim-Subscription-Key": API_KEY}, ttl_seconds = 30)
250289

251290
if resp.status_code != 200:
@@ -267,8 +306,8 @@ def getTrip(station_id, station_dest, skiptime):
267306
continue
268307

269308
# Skip trains that are not in allowed frame.
270-
if skiptime > 0:
271-
timeStart = time.parse_duration("%im" % skiptime) + time.now()
309+
if skip_time > 0:
310+
timeStart = time.parse_duration("%im" % skip_time) + time.now()
272311
timeDepart = time.parse_time(originTime[0:19], format = "2006-01-02T15:04:05", location = "Europe/Amsterdam")
273312
if timeDepart >= timeStart:
274313
stops.append(
@@ -299,7 +338,7 @@ def getTrip(station_id, station_dest, skiptime):
299338

300339
return stops
301340

302-
def getTrains(station_id, skiptime):
341+
def getTrains(station_id, skip_time):
303342
resp = http.get("https://gateway.apiportal.ns.nl/reisinformatie-api/api/v2/departures", params = {"station": station_id}, headers = {"Ocp-Apim-Subscription-Key": API_KEY}, ttl_seconds = 30)
304343

305344
if resp.status_code != 200:
@@ -314,8 +353,8 @@ def getTrains(station_id, skiptime):
314353

315354
startID = 0
316355

317-
if skiptime > 0:
318-
timeStart = time.parse_duration("%im" % skiptime) + time.now()
356+
if skip_time > 0:
357+
timeStart = time.parse_duration("%im" % skip_time) + time.now()
319358

320359
for i, train in enumerate(departuresTrains):
321360
timeDepart = time.parse_time(train["actualDateTime"][0:19], format = "2006-01-02T15:04:05", location = "Europe/Amsterdam")
@@ -388,5 +427,11 @@ def get_schema():
388427
desc = "Shows the connections starting n minutes in the future.",
389428
icon = "clock",
390429
),
430+
schema.Toggle(
431+
id = "time_to_leave",
432+
name = "Time To Leave",
433+
desc = "Shows a green/orange/red line to indicate how soon you need to leave your house to catch the train. (uses Departure Offset to render the indicator).",
434+
icon = "personWalking",
435+
),
391436
],
392437
)

0 commit comments

Comments
 (0)