Moved config to yml file
This commit is contained in:
parent
1067333518
commit
883bb30fea
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,3 +1,3 @@
|
||||||
config.py
|
config.yml
|
||||||
*.pyc
|
*.pyc
|
||||||
assets
|
assets
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
from bottle import route, template, error, run, get, ServerAdapter, static_file
|
|
||||||
from departures import Departure
|
|
||||||
from operator import itemgetter
|
|
||||||
import threading
|
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
|
||||||
|
|
||||||
class Server(ServerAdapter):
|
class Server(ServerAdapter):
|
||||||
server = None
|
server = None
|
||||||
def run(self, handler):
|
def run(self, handler):
|
||||||
from wsgiref.simple_server import make_server, WSGIRequestHandler
|
|
||||||
if self.quiet:
|
if self.quiet:
|
||||||
class QuietHandler(WSGIRequestHandler):
|
class QuietHandler(WSGIRequestHandler):
|
||||||
def log_request(self, *args, **kw):
|
def log_request(self, *args, **kw):
|
||||||
|
@ -17,8 +17,6 @@ class Server(ServerAdapter):
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.server.shutdown()
|
self.server.shutdown()
|
||||||
|
|
||||||
server = Server(host="0.0.0.0", port=8080)
|
|
||||||
|
|
||||||
@route('/departures')
|
@route('/departures')
|
||||||
def index():
|
def index():
|
||||||
resp = []
|
resp = []
|
||||||
|
@ -29,14 +27,18 @@ def index():
|
||||||
|
|
||||||
@get("/")
|
@get("/")
|
||||||
def static():
|
def static():
|
||||||
return static_file("index.html", root="static")
|
return static_file("index.html", root="static")
|
||||||
|
|
||||||
@error(404)
|
@error(404)
|
||||||
def error404(error):
|
def error404(err):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def start():
|
class API:
|
||||||
run(quiet=True, server=server)
|
|
||||||
|
|
||||||
thread = threading.Thread(target=start)
|
def __init__(self, main):
|
||||||
thread.start()
|
self.server = Server(host=main.config["http"]["host"], port=main.config["http"]["port"])
|
||||||
|
self.thread = threading.Thread(target=self.start)
|
||||||
|
self.thread.start()
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
run(quiet=True, server=self.server)
|
|
@ -1,13 +1,6 @@
|
||||||
|
|
||||||
|
|
||||||
from requests.structures import CaseInsensitiveDict
|
|
||||||
import json
|
|
||||||
import requests
|
|
||||||
from dateutil import parser
|
|
||||||
from datetime import datetime
|
|
||||||
from lora import lora_controller
|
|
||||||
from math import floor
|
from math import floor
|
||||||
|
from datetime import datetime
|
||||||
|
from dateutil import parser
|
||||||
|
|
||||||
class Departure:
|
class Departure:
|
||||||
|
|
||||||
|
@ -33,43 +26,8 @@ class Departure:
|
||||||
remove.append(did)
|
remove.append(did)
|
||||||
for did in remove:
|
for did in remove:
|
||||||
Departure.storage.pop(did)
|
Departure.storage.pop(did)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def fetch(stop_id, limit):
|
|
||||||
|
|
||||||
url = "https://jizdnirady.pmdp.cz/odjezdy/vyhledat"
|
def __init__(self, did, type, line, last_stop, departure, delay, lora_controller):
|
||||||
|
|
||||||
headers = CaseInsensitiveDict()
|
|
||||||
headers["Content-Type"] = "application/json"
|
|
||||||
|
|
||||||
data = {
|
|
||||||
"Stop": {
|
|
||||||
"StopId": stop_id
|
|
||||||
},
|
|
||||||
"DateAndTime": None,
|
|
||||||
"MaxResults": limit,
|
|
||||||
"FullResults": False
|
|
||||||
}
|
|
||||||
|
|
||||||
resp = requests.post(url, headers=headers, data=json.dumps(data), timeout=100).json()
|
|
||||||
|
|
||||||
for c in resp:
|
|
||||||
did = f"{stop_id}|{abs(c['ConnectionId']['ConnectionId'])}"
|
|
||||||
if did not in Departure.storage:
|
|
||||||
Departure(
|
|
||||||
did,
|
|
||||||
c["Line"]["TractionType"],
|
|
||||||
c["Line"]["Name"],
|
|
||||||
c["LastStopName"],
|
|
||||||
c["DepartureTime"],
|
|
||||||
0 if not c["DelayMin"] else c["DelayMin"]
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
Departure.storage[did].update(
|
|
||||||
0 if not c["DelayMin"] else c["DelayMin"]
|
|
||||||
)
|
|
||||||
|
|
||||||
def __init__(self, did, type, line, last_stop, departure, delay):
|
|
||||||
departure = (parser.parse(departure)).timestamp()
|
departure = (parser.parse(departure)).timestamp()
|
||||||
if -(datetime.now().timestamp() - (departure + delay*60))/60 <= -1:
|
if -(datetime.now().timestamp() - (departure + delay*60))/60 <= -1:
|
||||||
return
|
return
|
||||||
|
@ -83,11 +41,12 @@ class Departure:
|
||||||
self.last_stop = last_stop
|
self.last_stop = last_stop
|
||||||
self.departure = departure
|
self.departure = departure
|
||||||
self.delay = delay
|
self.delay = delay
|
||||||
lora_controller.data(self)
|
self.controller = lora_controller
|
||||||
|
self.controller.data(self)
|
||||||
|
|
||||||
def update(self, delay):
|
def update(self, delay):
|
||||||
if delay != self.delay:
|
if delay != self.delay:
|
||||||
lora_controller.data(self)
|
self.controller.data(self)
|
||||||
self.delay = delay
|
self.delay = delay
|
||||||
|
|
||||||
def get_departure(self):
|
def get_departure(self):
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import requests
|
import requests
|
||||||
from requests.structures import CaseInsensitiveDict
|
from requests.structures import CaseInsensitiveDict
|
||||||
import config
|
|
||||||
import json
|
import json
|
||||||
import threading
|
import threading
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
@ -12,27 +11,29 @@ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
|
||||||
class LoraController:
|
class LoraController:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, main):
|
||||||
|
self.main = main
|
||||||
self.storage = dict()
|
self.storage = dict()
|
||||||
self.devices = []
|
self.devices = []
|
||||||
# TODO: create separated message pool for each device
|
# TODO: create separated message pool for each device
|
||||||
self.message_pool = []
|
self.message_pool = []
|
||||||
self.thread = None
|
self.thread = None
|
||||||
|
self.token = ""
|
||||||
|
|
||||||
def generate_token(self):
|
def generate_token(self):
|
||||||
|
|
||||||
url = f"https://lora.plzen.eu/api/v2/login"
|
url = "https://lora.plzen.eu/api/v2/login"
|
||||||
|
|
||||||
headers = CaseInsensitiveDict()
|
headers = CaseInsensitiveDict()
|
||||||
headers["Content-Type"] = "application/json"
|
headers["Content-Type"] = "application/json"
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
"email": config.lora_api_username,
|
"email": self.main.config["lora_api"]["username"],
|
||||||
"password": config.lora_api_password
|
"password": self.main.config["lora_api"]["password"]
|
||||||
}
|
}
|
||||||
|
|
||||||
data = requests.post(url, verify=False, headers=headers, data=json.dumps(data)).json()
|
data = requests.post(url, verify=False, headers=headers, data=json.dumps(data)).json()
|
||||||
config.lora_api_token = data["token"]
|
self.token = data["token"]
|
||||||
|
|
||||||
def new(self, id):
|
def new(self, id):
|
||||||
self.devices.append(LoraDevice(self, id))
|
self.devices.append(LoraDevice(self, id))
|
||||||
|
@ -55,14 +56,14 @@ class LoraController:
|
||||||
|
|
||||||
def thread_sending(self):
|
def thread_sending(self):
|
||||||
while True:
|
while True:
|
||||||
if not len(self.message_pool):
|
if len(self.message_pool) == 0:
|
||||||
break
|
break
|
||||||
data = self.message_pool.pop(0)
|
data = self.message_pool.pop(0)
|
||||||
url = f"https://lora.plzen.eu/api/v2/nodes/{data[0]:0>16x}/queue"
|
url = f"https://lora.plzen.eu/api/v2/nodes/{data[0]:0>16x}/queue"
|
||||||
string = data[2]()
|
string = data[2]()
|
||||||
headers = CaseInsensitiveDict()
|
headers = CaseInsensitiveDict()
|
||||||
headers["Content-Type"] = "application/json"
|
headers["Content-Type"] = "application/json"
|
||||||
headers["Authorization"] = f"Bearer {config.lora_api_token}"
|
headers["Authorization"] = f"Bearer {self.token}"
|
||||||
payload = {
|
payload = {
|
||||||
"confirmed": True,
|
"confirmed": True,
|
||||||
"data": b64encode(string.encode("utf-8")).decode("ascii"),
|
"data": b64encode(string.encode("utf-8")).decode("ascii"),
|
||||||
|
@ -81,9 +82,4 @@ class LoraDevice:
|
||||||
|
|
||||||
def send(self, msg):
|
def send(self, msg):
|
||||||
self.controller.send(self.id, self.port+1, msg)
|
self.controller.send(self.id, self.port+1, msg)
|
||||||
self.port = (self.port + 1) % 15
|
self.port = (self.port + 1) % 15
|
||||||
|
|
||||||
|
|
||||||
lora_controller = LoraController()
|
|
||||||
|
|
||||||
lora_controller.new(0xbdea85badeedf1)
|
|
|
@ -1,18 +1,67 @@
|
||||||
from departures import Departure
|
from departures import Departure
|
||||||
|
from requests.structures import CaseInsensitiveDict
|
||||||
|
import json
|
||||||
|
import requests
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from lora import lora_controller
|
from lora import LoraController
|
||||||
import threading
|
import threading
|
||||||
from api import server
|
from api import API
|
||||||
|
from pathlib import Path
|
||||||
|
import yaml
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
class MainLoop:
|
class Main:
|
||||||
|
|
||||||
def __init__(self, stop_id, controller):
|
def __init__(self, stop_id):
|
||||||
|
config = Path("config.yml")
|
||||||
|
try:
|
||||||
|
self.config = yaml.safe_load(config.read_text(encoding="utf-8-sig"))
|
||||||
|
except:
|
||||||
|
print("Invalid config file!")
|
||||||
|
sys.exit(-1)
|
||||||
self.ended = False
|
self.ended = False
|
||||||
self.stop_id = stop_id
|
self.stop_id = stop_id
|
||||||
self.controller = controller
|
lora_controller = LoraController(self)
|
||||||
|
lora_controller.new(0xbdea85badeedf1)
|
||||||
|
self.controller = lora_controller
|
||||||
self.thread = threading.Thread(target=self.update_loop)
|
self.thread = threading.Thread(target=self.update_loop)
|
||||||
self.thread.start()
|
self.thread.start()
|
||||||
|
self.api = API(self)
|
||||||
|
|
||||||
|
def fetch(self, stop_id, limit):
|
||||||
|
|
||||||
|
url = "https://jizdnirady.pmdp.cz/odjezdy/vyhledat"
|
||||||
|
|
||||||
|
headers = CaseInsensitiveDict()
|
||||||
|
headers["Content-Type"] = "application/json"
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"Stop": {
|
||||||
|
"StopId": stop_id
|
||||||
|
},
|
||||||
|
"DateAndTime": None,
|
||||||
|
"MaxResults": limit,
|
||||||
|
"FullResults": False
|
||||||
|
}
|
||||||
|
|
||||||
|
resp = requests.post(url, headers=headers, data=json.dumps(data), timeout=100).json()
|
||||||
|
|
||||||
|
for c in resp:
|
||||||
|
did = f"{stop_id}|{abs(c['ConnectionId']['ConnectionId'])}"
|
||||||
|
if did not in Departure.storage:
|
||||||
|
Departure(
|
||||||
|
did,
|
||||||
|
c["Line"]["TractionType"],
|
||||||
|
c["Line"]["Name"],
|
||||||
|
c["LastStopName"],
|
||||||
|
c["DepartureTime"],
|
||||||
|
0 if not c["DelayMin"] else c["DelayMin"],
|
||||||
|
self.controller
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
Departure.storage[did].update(
|
||||||
|
0 if not c["DelayMin"] else c["DelayMin"]
|
||||||
|
)
|
||||||
|
|
||||||
def update_loop(self):
|
def update_loop(self):
|
||||||
refetch = 0
|
refetch = 0
|
||||||
|
@ -27,7 +76,7 @@ class MainLoop:
|
||||||
|
|
||||||
if refetch == 0:
|
if refetch == 0:
|
||||||
self.controller.time()
|
self.controller.time()
|
||||||
Departure.fetch(self.stop_id, 20)
|
self.fetch(self.stop_id, 20)
|
||||||
|
|
||||||
refetch = (refetch + 1) % 3
|
refetch = (refetch + 1) % 3
|
||||||
regenerate = (regenerate + 1) % (6*30)
|
regenerate = (regenerate + 1) % (6*30)
|
||||||
|
@ -36,14 +85,14 @@ class MainLoop:
|
||||||
|
|
||||||
Departure.clear()
|
Departure.clear()
|
||||||
|
|
||||||
for i in range(10):
|
for _ in range(10):
|
||||||
sleep(1)
|
sleep(1)
|
||||||
if self.ended:
|
if self.ended:
|
||||||
break
|
break
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
print("Stopping...")
|
print("Stopping...")
|
||||||
server.stop()
|
self.api.server.stop()
|
||||||
self.ended = True
|
self.ended = True
|
||||||
self.controller.message_pool = []
|
self.controller.message_pool = []
|
||||||
|
|
||||||
|
@ -70,5 +119,5 @@ class MainLoop:
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
self.stop()
|
self.stop()
|
||||||
|
|
||||||
main_loop = MainLoop("40", lora_controller)
|
main = Main("40")
|
||||||
main_loop.input_loop()
|
main.input_loop()
|
Loading…
Reference in a new issue