Integration with a SQL database, human-readable output of departures
This commit is contained in:
parent
5e7434b20b
commit
0fa0126dbc
110
monitor.py
110
monitor.py
@ -6,6 +6,23 @@ from pprint import pprint, pformat
|
|||||||
import datetime
|
import datetime
|
||||||
import pause
|
import pause
|
||||||
import sys
|
import sys
|
||||||
|
import mysql.connector
|
||||||
|
|
||||||
|
TABLE = """
|
||||||
|
CREATE TABLE IF NOT EXISTS vrr (
|
||||||
|
line_code varchar(9) not null,
|
||||||
|
direction_code varchar(1) not null,
|
||||||
|
station_id int not null,
|
||||||
|
orig_datetime datetime not null,
|
||||||
|
status enum('on_time', 'early', 'late', 'cancelled', 'no_data') not null,
|
||||||
|
delay_value int default null,
|
||||||
|
primary key (line_code, direction_code, station_id, orig_datetime));
|
||||||
|
"""
|
||||||
|
|
||||||
|
# CONFIGURATION
|
||||||
|
USE_MODES = []
|
||||||
|
USE_STATION_ID = 20021002
|
||||||
|
USE_LINES = []
|
||||||
|
|
||||||
|
|
||||||
class MOT:
|
class MOT:
|
||||||
@ -30,16 +47,8 @@ lines_filter = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def t(s: str) -> str:
|
def make_request_data(station_id: int, result_count: int = 8, modes: List = MOT.ALL_MODES,
|
||||||
"""
|
lines: List[str] = ALL_LINES) -> dict:
|
||||||
Encode a string to be used as a station identifier.
|
|
||||||
:param s: a string to encode
|
|
||||||
:return: the encoded string
|
|
||||||
"""
|
|
||||||
return s.replace(' ', '+')
|
|
||||||
|
|
||||||
|
|
||||||
def make_request_data(station_id: int, result_count: int = 8, modes: List = MOT.ALL_MODES, lines: List[str] = ALL_LINES) -> dict:
|
|
||||||
"""
|
"""
|
||||||
Prepare a request data dictionary to put into get_data()
|
Prepare a request data dictionary to put into get_data()
|
||||||
:param station_id: an EFA station ID
|
:param station_id: an EFA station ID
|
||||||
@ -81,7 +90,7 @@ def make_request_data(station_id: int, result_count: int = 8, modes: List = MOT.
|
|||||||
if lines is ALL_LINES:
|
if lines is ALL_LINES:
|
||||||
request_data['useAllLines'] = 1
|
request_data['useAllLines'] = 1
|
||||||
else:
|
else:
|
||||||
lines_dictarr = [{'data': t(v)} for v in lines]
|
lines_dictarr = [{'data': v.replace(' ', '+')} for v in lines]
|
||||||
request_data['linesFilter'] = json.dumps(lines_dictarr)
|
request_data['linesFilter'] = json.dumps(lines_dictarr)
|
||||||
request_data['useAllLines'] = 0
|
request_data['useAllLines'] = 0
|
||||||
|
|
||||||
@ -116,9 +125,12 @@ def is_early(trip: dict) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
# Pretty-print the reply data.
|
def is_on_time(trip: dict) -> bool:
|
||||||
"""print("Data:")
|
return int(trip['delay']) == 0
|
||||||
pprint(reply_data)"""
|
|
||||||
|
|
||||||
|
def has_realtime(trip: dict) -> bool:
|
||||||
|
return trip['delay'] != ''
|
||||||
|
|
||||||
|
|
||||||
def fixup_data(d: dict) -> dict:
|
def fixup_data(d: dict) -> dict:
|
||||||
@ -129,13 +141,20 @@ def fixup_data(d: dict) -> dict:
|
|||||||
|
|
||||||
|
|
||||||
def print_trip(trip: dict) -> None:
|
def print_trip(trip: dict) -> None:
|
||||||
trip_part = "The {}:{} {} (???:{}: :{}) service to {} ".format(trip['orgHour'], trip['orgMinute'], trip['lineNumber'], trip['lineCode'], trip['directionCode'], trip['direction'])
|
trip_part = "The {}:{} {} (???:{}: :{}) service to {} ".format(trip['orgHour'], trip['orgMinute'],
|
||||||
|
trip['lineNumber'], trip['lineCode'],
|
||||||
|
trip['directionCode'], trip['direction'])
|
||||||
|
if has_realtime(trip):
|
||||||
if is_cancelled(trip):
|
if is_cancelled(trip):
|
||||||
print(trip_part + "is cancelled.")
|
print(trip_part + "is cancelled.")
|
||||||
elif is_late(trip):
|
elif is_late(trip):
|
||||||
print(trip_part + "is {} minutes late.".format(trip['delay']))
|
print(trip_part + "is {} minutes late.".format(trip['delay']))
|
||||||
elif is_early(trip):
|
elif is_early(trip):
|
||||||
print(trip_part + "is {} minutes early.".format(-trip['delay']))
|
print(trip_part + "is {} minutes early.".format(-trip['delay']))
|
||||||
|
elif is_on_time(trip):
|
||||||
|
print(trip_part + "is on time.")
|
||||||
|
else:
|
||||||
|
print(trip_part + "has no real-time data.")
|
||||||
|
|
||||||
|
|
||||||
def get_next_refresh(data: dict):
|
def get_next_refresh(data: dict):
|
||||||
@ -147,37 +166,80 @@ def get_next_refresh(data: dict):
|
|||||||
times.sort()
|
times.sort()
|
||||||
for time in times:
|
for time in times:
|
||||||
if (datetime.datetime.fromtimestamp(time) - datetime.datetime.now()) > datetime.timedelta(seconds=30):
|
if (datetime.datetime.fromtimestamp(time) - datetime.datetime.now()) > datetime.timedelta(seconds=30):
|
||||||
if (datetime.datetime.fromtimestamp(time)-datetime.datetime.now()) > datetime.timedelta(minutes=5):
|
if (datetime.datetime.fromtimestamp(time) - datetime.datetime.now()) > datetime.timedelta(minutes=5):
|
||||||
return (datetime.datetime.now()+datetime.timedelta(minutes=5)).timestamp()
|
return (datetime.datetime.now() + datetime.timedelta(minutes=5)).timestamp()
|
||||||
return time
|
return time
|
||||||
return (datetime.datetime.now() + datetime.timedelta(seconds=60)).timestamp()
|
return (datetime.datetime.now() + datetime.timedelta(seconds=60)).timestamp()
|
||||||
|
|
||||||
|
|
||||||
def update():
|
def _make_delay_value_for_sql(value: str or int or None) -> int or None:
|
||||||
|
if value == '':
|
||||||
|
value = None
|
||||||
|
else:
|
||||||
|
value = int(value)
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def _make_status_value_for_sql(trip: dict) -> str:
|
||||||
|
if not has_realtime(trip):
|
||||||
|
status = 'no_data'
|
||||||
|
else:
|
||||||
|
if is_late(trip):
|
||||||
|
status = 'late'
|
||||||
|
elif is_cancelled(trip):
|
||||||
|
status = 'cancelled'
|
||||||
|
elif is_early(trip):
|
||||||
|
status = 'early'
|
||||||
|
elif is_on_time(trip):
|
||||||
|
status = 'on_time'
|
||||||
|
else:
|
||||||
|
raise ValueError("unknown delay value")
|
||||||
|
return status
|
||||||
|
|
||||||
|
|
||||||
|
def update(station_id: int):
|
||||||
reply_data = get_data(
|
reply_data = get_data(
|
||||||
make_request_data(
|
make_request_data(
|
||||||
20021002,
|
station_id,
|
||||||
8,
|
8,
|
||||||
lines=lines_filter
|
lines=lines_filter
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
reply_data = fixup_data(reply_data)
|
|
||||||
for trip in reply_data['departureData']:
|
for trip in reply_data['departureData']:
|
||||||
print_trip(trip)
|
print_trip(trip)
|
||||||
return reply_data
|
return reply_data
|
||||||
|
|
||||||
|
|
||||||
def wait():
|
def wait(cxn: mysql.connector.MySQLConnection, station_id: int):
|
||||||
data = update()
|
lines_filter = [
|
||||||
|
'rbg:70070: :H', # U70 -> Düsseldorf Hbf
|
||||||
|
'rbg:70070: :R', # U70 -> Krefeld Rheinstr
|
||||||
|
'rbg:70076: :H', # U76 -> Düsseldorf Hbf
|
||||||
|
'rbg:70076: :R', # U76 -> Krefeld Rheinstr
|
||||||
|
]
|
||||||
|
cur = cxn.cursor()
|
||||||
while True:
|
while True:
|
||||||
|
data = update(station_id)
|
||||||
|
for t in data['departureData']:
|
||||||
|
cur.execute('REPLACE INTO vrr '
|
||||||
|
'(line_code, direction_code, station_id, orig_datetime, status, delay_value)'
|
||||||
|
' VALUES (%s, %s, %s, '
|
||||||
|
'from_unixtime(%s), %s, %s)',
|
||||||
|
(t['lineCode'], t['directionCode'], station_id,
|
||||||
|
t['orgFullTime'], _make_status_value_for_sql(t), _make_delay_value_for_sql(t['delay'])
|
||||||
|
))
|
||||||
|
cxn.commit()
|
||||||
next_refresh = get_next_refresh(data)
|
next_refresh = get_next_refresh(data)
|
||||||
print("Sleeping until " + datetime.datetime.fromtimestamp(next_refresh).isoformat(), file=sys.stderr)
|
print("Sleeping until " + datetime.datetime.fromtimestamp(next_refresh).isoformat(), file=sys.stderr)
|
||||||
pause.until(next_refresh)
|
pause.until(next_refresh)
|
||||||
data = update()
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
wait()
|
cxn = mysql.connector.connect(user='vrr', password='vrr', host='127.0.0.1', database='vrr')
|
||||||
|
cursor = cxn.cursor()
|
||||||
|
cursor.execute(TABLE)
|
||||||
|
|
||||||
|
wait(cxn, USE_STATION_ID)
|
||||||
|
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
requests
|
requests
|
||||||
pause
|
pause
|
||||||
|
mysql-connector-python
|
Loading…
Reference in New Issue
Block a user