Crystal Orb MVP, omtrent. Programmet henter avgangstider og kan skrive dem til en kjørende mpv-instans
This commit is contained in:
parent
2d40bf296a
commit
a352264efe
72
README.md
72
README.md
|
@ -3,3 +3,75 @@
|
||||||
> Ta en titt inn i krystallkulen og se om det går en buss i dag.
|
> Ta en titt inn i krystallkulen og se om det går en buss i dag.
|
||||||
|
|
||||||
AtB-infoskjerm til å visepå TV-skjermen på terminalrommet.
|
AtB-infoskjerm til å visepå TV-skjermen på terminalrommet.
|
||||||
|
|
||||||
|
## Få tak i avgangstider
|
||||||
|
|
||||||
|
Det ser ut til at API-et [mpolden](https://github.com/mpolden/atb) har laget er tilstrekkelig
|
||||||
|
for å få tak i alle busser og avgangstider for et gitt stoppested (stopPlace).
|
||||||
|
API-et hans er en wrapper for Entur sitt API som er litt tyngre skyts en det hackere har behov for,
|
||||||
|
derav hvorfor han lagde et (tror jeg).
|
||||||
|
|
||||||
|
### Informasjon fra mpolden sitt API
|
||||||
|
|
||||||
|
Dersom man gir https://mpolden.no/atb/v2/departures/ en høvelig kode for stoppested, gir den tilbake
|
||||||
|
disse feltene:
|
||||||
|
|
||||||
|
- `line`
|
||||||
|
- Dette er linje-nummeret til bussen
|
||||||
|
- `scheduledDepartureTime`
|
||||||
|
- Dette er den forventede avgangstiden til bussen, basert på Entur sitt felt `expectedDepartureTime`
|
||||||
|
- I tilleg finnes `aimedDepartureTime` og `actualDepartureTime` hos Entur,
|
||||||
|
som er hva bussen er satt opp til etter planen og når bussen faktisk dro.
|
||||||
|
- Av disse er naturligvis `expectedDepartureTime` det viktigste feltet for oss
|
||||||
|
- `destination`
|
||||||
|
- Hvor bussen skal til slutt, det er dette som står foran på bussen
|
||||||
|
- Basert på `destinationDisplay.frontText` hos Entur
|
||||||
|
- `isRealTimeData`
|
||||||
|
- Hvorvidt tidspunktet er oppdatert/basert på sanntidsdata
|
||||||
|
- Gir en indikasjon på hvor stabil informasjonen er
|
||||||
|
- Hvis det er sanntid skal man ta det med en klype salt
|
||||||
|
- Hvis det ikke er sanntid er det ikke vits å finne frem saltbøssen engang
|
||||||
|
- `isGoingTowardsCentrum`
|
||||||
|
- Basert på `journeyPattern.directionType` hos Entur
|
||||||
|
- Busser går stort sett enten inn mot Midtbyen eller ut,
|
||||||
|
dette er kjekt å vite ettersom man ofte vet hvilken retning man skal herfra
|
||||||
|
|
||||||
|
### Koder for stoppested
|
||||||
|
|
||||||
|
Man kan finne stoppestedskoden på url https://stoppested.entur.org/ .
|
||||||
|
De mest relevante kodene for oss på PVV er:
|
||||||
|
|
||||||
|
- Gløshaugen: 44085
|
||||||
|
- Høgskoleringen: 42029
|
||||||
|
- Hesthagen: 41620
|
||||||
|
|
||||||
|
## Funksjonalitet
|
||||||
|
|
||||||
|
Vi har på dette tidspunktet ingen anelse hvilken funksjonalitet dette programmet skal ha,
|
||||||
|
men noen ideer har vi allerede.
|
||||||
|
|
||||||
|
- Mulighet for å vise de kommende avgangstidene på Georg/Grzegorz
|
||||||
|
- Mer generelt gjennom `mpv` på en eller annen måte
|
||||||
|
- Gjerne med kule farger eller et nice layout
|
||||||
|
- Hadde kanskje vært kult med et cli hvor man kjapt kan sjekke de neste bussene som drar
|
||||||
|
- Kule farger er også nice her
|
||||||
|
- En nettside eller en annen visualiseringsmetode
|
||||||
|
- Nettopp for å kunne støtte et brukervennlig layout av informasjonen
|
||||||
|
|
||||||
|
## Hvordan kjøre programmet slik det er
|
||||||
|
|
||||||
|
Akkurat nå funker `crystal_orb.py` omtrent slik:
|
||||||
|
|
||||||
|
- Man kjører programmet med `python crystal_orb.py <stoppested>`
|
||||||
|
- Stoppested kan være gløshaugen, høgskoleringen eller hesthagen
|
||||||
|
- `crystal orb` får avgangsinformasjon fra `mpolden` sitt API
|
||||||
|
- `crystal orb` lager en liste av all avgangsinformasjonen den fikk
|
||||||
|
- `crystal orb` skriver teksten på en kjørende mpv-sesjon
|
||||||
|
- Merk at `mpv` må ha satt opp en ipc socket som `crystal orb` skriver til
|
||||||
|
- Hvis denne socket-en ikke finnes, skrives listen til stdout
|
||||||
|
|
||||||
|
## Forbedringer
|
||||||
|
|
||||||
|
- Legge til `aimedDepartureTime` slik at vi kan se hva avviket er
|
||||||
|
- Av og til kjører bussen inn igjen etterslepet, dermed kan det være nyttig
|
||||||
|
-
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
import json
|
||||||
|
import requests
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
# See github project: https://github.com/mpolden/atb
|
||||||
|
ATB_API_URL = "https://mpolden.no/atb/v2/departures/"
|
||||||
|
# Stop place codes found through https://stoppested.entur.org/
|
||||||
|
STOP_PLACES = {
|
||||||
|
"gløshaugen": "44085",
|
||||||
|
"høgskoleringen": "42029",
|
||||||
|
"hesthagen": "41620"
|
||||||
|
}
|
||||||
|
|
||||||
|
def format_departure(departure_dict: dict) -> str:
|
||||||
|
"""Formats the json supplied by mpolden's atb api to a single line of text
|
||||||
|
quickly summarizing the scheduled bus.
|
||||||
|
"""
|
||||||
|
line = departure_dict["line"]
|
||||||
|
departure_time = departure_dict["scheduledDepartureTime"].split("T")[1].split(".")[0]
|
||||||
|
destination = departure_dict["destination"]
|
||||||
|
is_real_time = departure_dict["isRealtimeData"]
|
||||||
|
towards_city_center = departure_dict["isGoingTowardsCentrum"]
|
||||||
|
|
||||||
|
# return f"{departure_time}: {line}\t({'R' if is_real_time else 'S'}, {'I' if towards_city_center else 'O'}) {destination}"
|
||||||
|
return f"{departure_time}: {line}\t{destination}\t ({'realtime' if is_real_time else 'aimed'},\t{'til Midtbyen' if towards_city_center else 'fra Midtbyen'})"
|
||||||
|
|
||||||
|
|
||||||
|
def write_to_socket(s: str, mpv_socket) -> None:
|
||||||
|
"""Writes the string s to the mpv on screen display through
|
||||||
|
the open mpv ipc socket located at the path `mpv_socket`.
|
||||||
|
"""
|
||||||
|
cmd_dict = {"command": ["show-text", f"{s}", 10000]}
|
||||||
|
mpv_cmd = json.dumps(cmd_dict)
|
||||||
|
cmd = f'echo \'{mpv_cmd}\' | socat - ./{mpv_socket}'
|
||||||
|
subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
input_stop_place = sys.argv[1]
|
||||||
|
if input_stop_place in STOP_PLACES.keys():
|
||||||
|
active_stop_place = STOP_PLACES[input_stop_place]
|
||||||
|
else:
|
||||||
|
active_stop_place = STOP_PLACES["gløshaugen"]
|
||||||
|
|
||||||
|
r = requests.get(ATB_API_URL + active_stop_place)
|
||||||
|
departures = r.json()["departures"]
|
||||||
|
sorted_departures = sorted(departures, key = lambda d: d["scheduledDepartureTime"])
|
||||||
|
|
||||||
|
# ensure mpv is running with the ipc-server socket set in MPV_SOCKET
|
||||||
|
MPV_SOCKET = "mpv_ipc.socket"
|
||||||
|
if os.path.exists(MPV_SOCKET):
|
||||||
|
write_to_socket(
|
||||||
|
f"{'\n'.join([
|
||||||
|
format_departure(sorted_departures[i])
|
||||||
|
for i in range(len(sorted_departures))
|
||||||
|
])}", MPV_SOCKET)
|
||||||
|
else:
|
||||||
|
for dep in sorted_departures:
|
||||||
|
print(format_departure(dep))
|
||||||
|
|
Loading…
Reference in New Issue