Improved backend & multi stop support
This commit is contained in:
parent
883bb30fea
commit
6214b6cdf1
|
@ -1,5 +1,4 @@
|
|||
import threading
|
||||
from operator import itemgetter
|
||||
from wsgiref.simple_server import make_server, WSGIRequestHandler
|
||||
from departures import Departure
|
||||
from bottle import route, error, run, get, ServerAdapter, static_file
|
||||
|
@ -17,13 +16,9 @@ class Server(ServerAdapter):
|
|||
def stop(self):
|
||||
self.server.shutdown()
|
||||
|
||||
@route('/departures')
|
||||
def index():
|
||||
resp = []
|
||||
for d in Departure.storage:
|
||||
resp.append(Departure.storage[d].json())
|
||||
resp.sort(key=itemgetter("departure"))
|
||||
return {'departures': resp}
|
||||
@route('/departures/<stop_id>')
|
||||
def index(stop_id: int):
|
||||
return {'departures': Departure.get(stop_id)}
|
||||
|
||||
@get("/")
|
||||
def static():
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from math import floor
|
||||
from operator import itemgetter
|
||||
from datetime import datetime
|
||||
from dateutil import parser
|
||||
|
||||
|
@ -7,6 +8,16 @@ class Departure:
|
|||
id_pool = []
|
||||
storage = dict()
|
||||
|
||||
@staticmethod
|
||||
def get(stop_id: str):
|
||||
resp = []
|
||||
for id in Departure.storage:
|
||||
d = Departure.storage[id]
|
||||
if d.stop_id == int(stop_id):
|
||||
resp.append(d.json())
|
||||
resp.sort(key=itemgetter("departure"))
|
||||
return resp
|
||||
|
||||
@staticmethod
|
||||
def get_id():
|
||||
i = 0
|
||||
|
@ -21,20 +32,20 @@ class Departure:
|
|||
remove = []
|
||||
for did in Departure.storage:
|
||||
d = Departure.storage[did]
|
||||
if d.get_departure() < -35:
|
||||
if d.get_departure() < -3.5:
|
||||
Departure.id_pool.remove(d.id)
|
||||
remove.append(did)
|
||||
for did in remove:
|
||||
Departure.storage.pop(did)
|
||||
|
||||
def __init__(self, did, type, line, last_stop, departure, delay, lora_controller):
|
||||
def __init__(self, did, stop_id, type, line, last_stop, departure, delay, lora_controller):
|
||||
departure = (parser.parse(departure)).timestamp()
|
||||
if -(datetime.now().timestamp() - (departure + delay*60))/60 <= -1:
|
||||
return
|
||||
Departure.storage[did] = self
|
||||
if len(last_stop) >= 21:
|
||||
last_stop = last_stop[:20].strip() + "..."
|
||||
self.did = did
|
||||
self.stop_id = stop_id
|
||||
self.id = Departure.get_id()
|
||||
self.line = line
|
||||
self.type = type
|
||||
|
@ -43,6 +54,7 @@ class Departure:
|
|||
self.delay = delay
|
||||
self.controller = lora_controller
|
||||
self.controller.data(self)
|
||||
Departure.storage[did] = self
|
||||
|
||||
def update(self, delay):
|
||||
if delay != self.delay:
|
||||
|
@ -50,14 +62,10 @@ class Departure:
|
|||
self.delay = delay
|
||||
|
||||
def get_departure(self):
|
||||
departure = floor(self.get_accurate_departure()*10)
|
||||
return departure
|
||||
|
||||
def get_accurate_departure(self):
|
||||
return -((datetime.now().timestamp() - (self.departure + self.delay*60))/60)
|
||||
return -(floor(((datetime.now().timestamp() - (self.departure + self.delay*60))/60)*10)/10)
|
||||
|
||||
def __repr__(self):
|
||||
return f"{self.id}|{self.type}|{self.line}|{self.last_stop}|{self.get_departure()}"
|
||||
return f"{self.id}|{self.type}|{self.line}|{self.last_stop}|{(self.get_departure()*10):.0f}"
|
||||
|
||||
def json(self):
|
||||
return {
|
||||
|
@ -65,6 +73,6 @@ class Departure:
|
|||
'line': self.line,
|
||||
'type': self.type,
|
||||
'last_stop': self.last_stop,
|
||||
'departure': floor(self.get_accurate_departure()),
|
||||
'departure': self.get_departure(),
|
||||
'delay': self.delay
|
||||
}
|
|
@ -35,8 +35,8 @@ class LoraController:
|
|||
data = requests.post(url, verify=False, headers=headers, data=json.dumps(data)).json()
|
||||
self.token = data["token"]
|
||||
|
||||
def new(self, id):
|
||||
self.devices.append(LoraDevice(self, id))
|
||||
def new(self, id: int, stop_id: int):
|
||||
self.devices.append(LoraDevice(self, id, stop_id))
|
||||
|
||||
def time(self):
|
||||
def to_string():
|
||||
|
@ -46,10 +46,11 @@ class LoraController:
|
|||
|
||||
def data(self, data):
|
||||
for d in self.devices:
|
||||
if d.stop_id == data.stop_id:
|
||||
d.send(data.__repr__)
|
||||
|
||||
def send(self, id, port, msg):
|
||||
self.message_pool.append((id, port, msg))
|
||||
def send(self, id, msg):
|
||||
self.message_pool.append((id, msg))
|
||||
if not self.thread or not self.thread.is_alive():
|
||||
self.thread = threading.Thread(target=self.thread_sending)
|
||||
self.thread.start()
|
||||
|
@ -60,14 +61,14 @@ class LoraController:
|
|||
break
|
||||
data = self.message_pool.pop(0)
|
||||
url = f"https://lora.plzen.eu/api/v2/nodes/{data[0]:0>16x}/queue"
|
||||
string = data[2]()
|
||||
string = data[1]()
|
||||
headers = CaseInsensitiveDict()
|
||||
headers["Content-Type"] = "application/json"
|
||||
headers["Authorization"] = f"Bearer {self.token}"
|
||||
payload = {
|
||||
"confirmed": True,
|
||||
"data": b64encode(string.encode("utf-8")).decode("ascii"),
|
||||
"fPort": data[1],
|
||||
"fPort": 10,
|
||||
"reference": "string"
|
||||
}
|
||||
requests.post(url, verify=False, headers=headers, data=json.dumps(payload))
|
||||
|
@ -75,11 +76,10 @@ class LoraController:
|
|||
|
||||
class LoraDevice:
|
||||
|
||||
def __init__(self, controller: LoraController, deveui: int):
|
||||
def __init__(self, controller: LoraController, deveui: int, stop_id: int):
|
||||
self.controller = controller
|
||||
self.id = deveui
|
||||
self.port = 0
|
||||
self.stop_id = stop_id
|
||||
|
||||
def send(self, msg):
|
||||
self.controller.send(self.id, self.port+1, msg)
|
||||
self.port = (self.port + 1) % 15
|
||||
self.controller.send(self.id, msg)
|
|
@ -12,7 +12,7 @@ import sys
|
|||
|
||||
class Main:
|
||||
|
||||
def __init__(self, stop_id):
|
||||
def __init__(self):
|
||||
config = Path("config.yml")
|
||||
try:
|
||||
self.config = yaml.safe_load(config.read_text(encoding="utf-8-sig"))
|
||||
|
@ -20,9 +20,9 @@ class Main:
|
|||
print("Invalid config file!")
|
||||
sys.exit(-1)
|
||||
self.ended = False
|
||||
self.stop_id = stop_id
|
||||
lora_controller = LoraController(self)
|
||||
lora_controller.new(0xbdea85badeedf1)
|
||||
for d in self.config["devices"]:
|
||||
lora_controller.new(d["id"], d["stop_id"])
|
||||
self.controller = lora_controller
|
||||
self.thread = threading.Thread(target=self.update_loop)
|
||||
self.thread.start()
|
||||
|
@ -44,13 +44,14 @@ class Main:
|
|||
"FullResults": False
|
||||
}
|
||||
|
||||
resp = requests.post(url, headers=headers, data=json.dumps(data), timeout=100).json()
|
||||
resp = requests.post(url, headers=headers, data=json.dumps(data), timeout=1000).json()
|
||||
|
||||
for c in resp:
|
||||
did = f"{stop_id}|{abs(c['ConnectionId']['ConnectionId'])}"
|
||||
if did not in Departure.storage:
|
||||
Departure(
|
||||
did,
|
||||
stop_id,
|
||||
c["Line"]["TractionType"],
|
||||
c["Line"]["Name"],
|
||||
c["LastStopName"],
|
||||
|
@ -76,7 +77,8 @@ class Main:
|
|||
|
||||
if refetch == 0:
|
||||
self.controller.time()
|
||||
self.fetch(self.stop_id, 20)
|
||||
for s in self.config["stops"]:
|
||||
self.fetch(s["id"], 15)
|
||||
|
||||
refetch = (refetch + 1) % 3
|
||||
regenerate = (regenerate + 1) % (6*30)
|
||||
|
@ -119,5 +121,5 @@ class Main:
|
|||
except KeyboardInterrupt:
|
||||
self.stop()
|
||||
|
||||
main = Main("40")
|
||||
main = Main()
|
||||
main.input_loop()
|
|
@ -47,11 +47,11 @@
|
|||
<div class="header">zpoždění</div>
|
||||
<div class="header">odjezd</div>
|
||||
<template v-for="d in departures">
|
||||
<template v-if="d.departure >= 0">
|
||||
<template v-if="d.departure > -0.7">
|
||||
<div class="line" :class="'type'+d.type">{{ d.line }}</div>
|
||||
<div class="last-stop">{{ d.last_stop }}</div>
|
||||
<div class="delay">{{ d.delay == 0 ? '' : '+'+d.delay }}</div>
|
||||
<div class="departure">{{ d.departure == 0 ? '<1' : d.departure }}</div>
|
||||
<div class="departure">{{ d.departure < 1 ? '<1' : Math.floor(d.departure) }}</div>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
|
@ -78,7 +78,7 @@
|
|||
resolve(null);
|
||||
}
|
||||
};
|
||||
xhr.open("GET", "/departures", true);
|
||||
xhr.open("GET", "/departures/40", true);
|
||||
xhr.send();
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue