Add show plan loading, send more info to Webstudio UI.
This commit is contained in:
parent
23f1da515b
commit
1a59b2d5bf
4 changed files with 214 additions and 67 deletions
|
@ -17,34 +17,77 @@
|
||||||
November 2020
|
November 2020
|
||||||
"""
|
"""
|
||||||
import requests
|
import requests
|
||||||
|
import json
|
||||||
import config
|
import config
|
||||||
from plan import PlanItem
|
from plan import PlanItem
|
||||||
from helpers.os_environment import resolve_external_file_path
|
from helpers.os_environment import resolve_external_file_path
|
||||||
|
from helpers.logging_manager import LoggingManager
|
||||||
|
from logging import CRITICAL, INFO, DEBUG
|
||||||
class MyRadioAPI():
|
class MyRadioAPI():
|
||||||
|
logger = None
|
||||||
|
|
||||||
@classmethod
|
def __init__(self, logger: LoggingManager):
|
||||||
def get_filename(cls, item: PlanItem):
|
self.logger = logger
|
||||||
|
|
||||||
|
def get_non_api_call(self, url):
|
||||||
|
|
||||||
|
url = "{}{}".format(config.MYRADIO_BASE_URL, url)
|
||||||
|
|
||||||
|
if "?" in url:
|
||||||
|
url += "&api_key={}".format(config.API_KEY)
|
||||||
|
else:
|
||||||
|
url += "?api_key={}".format(config.API_KEY)
|
||||||
|
|
||||||
|
self._log("Requesting non-API URL: " + url)
|
||||||
|
request = requests.get(url, timeout=10)
|
||||||
|
self._log("Finished request.")
|
||||||
|
|
||||||
|
if request.status_code != 200:
|
||||||
|
self._logException("Failed to get API request. Status code: " + str(request.status_code))
|
||||||
|
self._logException(str(request.content))
|
||||||
|
return None
|
||||||
|
|
||||||
|
return request
|
||||||
|
|
||||||
|
def get_apiv2_call(self, url):
|
||||||
|
|
||||||
|
url = "{}/v2{}".format(config.MYRADIO_API_URL, url)
|
||||||
|
|
||||||
|
if "?" in url:
|
||||||
|
url += "&api_key={}".format(config.API_KEY)
|
||||||
|
else:
|
||||||
|
url += "?api_key={}".format(config.API_KEY)
|
||||||
|
|
||||||
|
self._log("Requesting API V2 URL: " + url)
|
||||||
|
request = requests.get(url, timeout=10)
|
||||||
|
self._log("Finished request.")
|
||||||
|
|
||||||
|
if request.status_code != 200:
|
||||||
|
self._logException("Failed to get API request. Status code: " + str(request.status_code))
|
||||||
|
self._logException(str(request.content))
|
||||||
|
return None
|
||||||
|
|
||||||
|
return request
|
||||||
|
|
||||||
|
def get_filename(self, item: PlanItem):
|
||||||
format = "mp3" # TODO: Maybe we want this customisable?
|
format = "mp3" # TODO: Maybe we want this customisable?
|
||||||
if item.trackId:
|
if item.trackId:
|
||||||
itemType = "track"
|
itemType = "track"
|
||||||
id = item.trackId
|
id = item.trackId
|
||||||
url = "{}/NIPSWeb/secure_play?trackid={}&{}&api_key={}".format(config.MYRADIO_BASE_URL, id, format, config.API_KEY)
|
url = "/NIPSWeb/secure_play?trackid={}&{}".format(id, format)
|
||||||
|
|
||||||
elif item.managedId:
|
elif item.managedId:
|
||||||
itemType = "managed"
|
itemType = "managed"
|
||||||
id = item.managedId
|
id = item.managedId
|
||||||
url = "{}/NIPSWeb/managed_play?managedid={}&api_key={}".format(config.MYRADIO_BASE_URL, id, config.API_KEY)
|
url = "/NIPSWeb/managed_play?managedid={}".format(id)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
request = requests.get(url, timeout=10)
|
|
||||||
|
|
||||||
if request.status_code != 200:
|
request = self.get_non_api_call(url)
|
||||||
# TODO: Log something here
|
|
||||||
|
if not request:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
filename: str = resolve_external_file_path("/music-tmp/{}-{}.{}".format(itemType, id, format))
|
filename: str = resolve_external_file_path("/music-tmp/{}-{}.{}".format(itemType, id, format))
|
||||||
|
@ -53,3 +96,23 @@ class MyRadioAPI():
|
||||||
file.write(request.content)
|
file.write(request.content)
|
||||||
|
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
|
def get_showplan(self, timeslotid: int):
|
||||||
|
|
||||||
|
url = "/timeslot/{}/showplan".format(timeslotid)
|
||||||
|
request = self.get_apiv2_call(url)
|
||||||
|
|
||||||
|
if not request:
|
||||||
|
self._logException("Failed to get show plan.")
|
||||||
|
return None
|
||||||
|
|
||||||
|
return json.loads(request.content)["payload"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _log(self, text:str, level: int = INFO):
|
||||||
|
self.logger.log.log(level, "MyRadio API: " + text)
|
||||||
|
|
||||||
|
def _logException(self, text:str):
|
||||||
|
self.logger.log.exception("MyRadio API: " + text)
|
||||||
|
|
||||||
|
|
139
player.py
139
player.py
|
@ -35,7 +35,7 @@ from plan import PlanItem
|
||||||
# Stop the Pygame Hello message.
|
# Stop the Pygame Hello message.
|
||||||
import os
|
import os
|
||||||
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
|
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
|
||||||
from pygame import mixer, NOEVENT, USEREVENT, event
|
from pygame import mixer, NOEVENT, USEREVENT, event, init
|
||||||
from mutagen.mp3 import MP3
|
from mutagen.mp3 import MP3
|
||||||
|
|
||||||
from helpers.myradio_api import MyRadioAPI
|
from helpers.myradio_api import MyRadioAPI
|
||||||
|
@ -49,7 +49,9 @@ class Player():
|
||||||
running = False
|
running = False
|
||||||
out_q = None
|
out_q = None
|
||||||
last_msg = ""
|
last_msg = ""
|
||||||
|
last_time_update = None
|
||||||
logger = None
|
logger = None
|
||||||
|
api = None
|
||||||
|
|
||||||
__default_state = {
|
__default_state = {
|
||||||
"initialised": False,
|
"initialised": False,
|
||||||
|
@ -225,6 +227,29 @@ class Player():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Show Plan Related Methods
|
# Show Plan Related Methods
|
||||||
|
def get_plan(self, message: int):
|
||||||
|
plan = self.api.get_showplan(message)
|
||||||
|
self.clear_channel_plan()
|
||||||
|
channel = self.state.state["channel"]
|
||||||
|
if len(plan) > channel:
|
||||||
|
for plan_item in plan[str(channel)]:
|
||||||
|
try:
|
||||||
|
new_item: Dict[str, any] = {
|
||||||
|
"channelWeight": int(plan_item["weight"]),
|
||||||
|
"filename": None,
|
||||||
|
"title": plan_item["title"],
|
||||||
|
"artist": plan_item["artist"] if "artist" in plan_item.keys() else None,
|
||||||
|
"timeslotItemId": int(plan_item["timeslotitemid"]) if "timeslotitemid" in plan_item.keys() and plan_item["timeslotitemid"] != None else None,
|
||||||
|
"trackId": int(plan_item["trackid"]) if "managedid" not in plan_item.keys() and plan_item["trackid"] != None else None,
|
||||||
|
"recordId": int(plan_item["trackid"]) if "trackid" in plan_item.keys() and plan_item["trackid"] != None else None, # TODO This is wrong.
|
||||||
|
"managedId": int(plan_item["managedid"]) if "managedid" in plan_item.keys() and plan_item["managedid"] != None else None,
|
||||||
|
}
|
||||||
|
self.add_to_plan(new_item)
|
||||||
|
except:
|
||||||
|
continue
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def add_to_plan(self, new_item: Dict[str, Any]) -> bool:
|
def add_to_plan(self, new_item: Dict[str, Any]) -> bool:
|
||||||
self.state.update("show_plan", self.state.state["show_plan"] + [PlanItem(new_item)])
|
self.state.update("show_plan", self.state.state["show_plan"] + [PlanItem(new_item)])
|
||||||
|
@ -261,7 +286,7 @@ class Player():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if (loaded_item.filename == "" or loaded_item.filename == None):
|
if (loaded_item.filename == "" or loaded_item.filename == None):
|
||||||
loaded_item.filename = MyRadioAPI.get_filename(item = loaded_item)
|
loaded_item.filename = self.api.get_filename(item = loaded_item)
|
||||||
|
|
||||||
if not loaded_item.filename:
|
if not loaded_item.filename:
|
||||||
return False
|
return False
|
||||||
|
@ -334,6 +359,39 @@ class Player():
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def ended(self):
|
||||||
|
loaded_item = self.state.state["loaded_item"]
|
||||||
|
# check the existing state (not self.isPlaying)
|
||||||
|
# Since this is called multiple times when pygame isn't playing.
|
||||||
|
if loaded_item == None or not self.isPlaying:
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.out_q:
|
||||||
|
self.out_q.put("STOPPED") # Tell clients that we've stopped playing.
|
||||||
|
|
||||||
|
# Track has ended
|
||||||
|
print("Finished", loaded_item.name)
|
||||||
|
|
||||||
|
# Repeat 1
|
||||||
|
if self.state.state["repeat"] == "ONE":
|
||||||
|
self.play()
|
||||||
|
|
||||||
|
# Auto Advance
|
||||||
|
elif self.state.state["auto_advance"]:
|
||||||
|
for i in range(len(self.state.state["show_plan"])):
|
||||||
|
if self.state.state["show_plan"][i].channelWeight == loaded_item.channelWeight:
|
||||||
|
if len(self.state.state["show_plan"]) > i+1:
|
||||||
|
self.load(self.state.state["show_plan"][i+1].channelWeight)
|
||||||
|
break
|
||||||
|
|
||||||
|
# Repeat All
|
||||||
|
elif self.state.state["repeat"] == "ALL":
|
||||||
|
self.load(self.state.state["show_plan"][0].channelWeight)
|
||||||
|
|
||||||
|
# Play on Load
|
||||||
|
if self.state.state["play_on_load"]:
|
||||||
|
self.play()
|
||||||
|
|
||||||
def _updateState(self, pos: Optional[float] = None):
|
def _updateState(self, pos: Optional[float] = None):
|
||||||
|
|
||||||
self.state.update("initialised", self.isInit)
|
self.state.update("initialised", self.isInit)
|
||||||
|
@ -350,32 +408,11 @@ class Player():
|
||||||
|
|
||||||
self.state.update("remaining", self.state.state["length"] - self.state.state["pos_true"])
|
self.state.update("remaining", self.state.state["length"] - self.state.state["pos_true"])
|
||||||
|
|
||||||
loaded_item = self.state.state["loaded_item"]
|
def _ping_times(self):
|
||||||
if loaded_item == None or self.state.state["remaining"] != 0:
|
if self.last_time_update == None or self.last_time_update + 1 < time.time():
|
||||||
return
|
self.last_time_update = time.time()
|
||||||
|
self.out_q.put("POS:" + str(int(self.state.state["pos_true"])))
|
||||||
|
|
||||||
# Track has ended
|
|
||||||
print("Finished", loaded_item.name)
|
|
||||||
|
|
||||||
# Repeat 1
|
|
||||||
if self.state.state["repeat"] == "ONE":
|
|
||||||
self.play()
|
|
||||||
|
|
||||||
# Auto Advance
|
|
||||||
elif self.state.state["auto_advance"]:
|
|
||||||
for i in range(len(self.state.state["show_plan"])):
|
|
||||||
if self.state.state["show_plan"][i].channelWeight == loaded_item.channelWeight:
|
|
||||||
if len(self.state.state["show_plan"]) > i+1:
|
|
||||||
self.load(self.state.state["show_plan"][i+1].channelWeight)
|
|
||||||
break
|
|
||||||
|
|
||||||
# Repeat All
|
|
||||||
elif self.state.state["repeat"] == "ALL":
|
|
||||||
self.load(self.state.state["show_plan"][0].channelWeight)
|
|
||||||
|
|
||||||
# Play on Load
|
|
||||||
if self.state.state["play_on_load"]:
|
|
||||||
self.play()
|
|
||||||
|
|
||||||
|
|
||||||
def _retMsg(self, msg: Any, okay_str: Any = False):
|
def _retMsg(self, msg: Any, okay_str: Any = False):
|
||||||
|
@ -389,7 +426,9 @@ class Player():
|
||||||
response += "FAIL:" + msg
|
response += "FAIL:" + msg
|
||||||
else:
|
else:
|
||||||
response += "FAIL"
|
response += "FAIL"
|
||||||
|
self.logger.log.info(("Preparing to send: {}".format(response)))
|
||||||
if self.out_q:
|
if self.out_q:
|
||||||
|
self.logger.log.info(("Sending: {}".format(response)))
|
||||||
self.out_q.put(response)
|
self.out_q.put(response)
|
||||||
|
|
||||||
def __init__(self, channel: int, in_q: multiprocessing.Queue, out_q: multiprocessing.Queue):
|
def __init__(self, channel: int, in_q: multiprocessing.Queue, out_q: multiprocessing.Queue):
|
||||||
|
@ -398,11 +437,16 @@ class Player():
|
||||||
setproctitle.setproctitle(process_title)
|
setproctitle.setproctitle(process_title)
|
||||||
multiprocessing.current_process().name = process_title
|
multiprocessing.current_process().name = process_title
|
||||||
|
|
||||||
|
# Init pygame, only used really for the end of playback trigger.
|
||||||
|
init()
|
||||||
|
|
||||||
self.running = True
|
self.running = True
|
||||||
self.out_q = out_q
|
self.out_q = out_q
|
||||||
|
|
||||||
self.logger = LoggingManager("channel" + str(channel))
|
self.logger = LoggingManager("channel" + str(channel))
|
||||||
|
|
||||||
|
self.api = MyRadioAPI(self.logger)
|
||||||
|
|
||||||
self.state = StateManager("channel" + str(channel), self.logger,
|
self.state = StateManager("channel" + str(channel), self.logger,
|
||||||
self.__default_state, self.__rate_limited_params)
|
self.__default_state, self.__rate_limited_params)
|
||||||
self.state.update("channel", channel)
|
self.state.update("channel", channel)
|
||||||
|
@ -434,6 +478,7 @@ class Player():
|
||||||
while self.running:
|
while self.running:
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
self._updateState()
|
self._updateState()
|
||||||
|
self._ping_times()
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
self.last_msg = in_q.get_nowait()
|
self.last_msg = in_q.get_nowait()
|
||||||
|
@ -453,7 +498,7 @@ class Player():
|
||||||
elif self.isInit:
|
elif self.isInit:
|
||||||
|
|
||||||
message_types: Dict[str, Callable[..., Any]] = { # TODO Check Types
|
message_types: Dict[str, Callable[..., Any]] = { # TODO Check Types
|
||||||
"STATUS": lambda: self._retMsg(self.status, True),
|
"STATUS": lambda: self._retMsg(self.status, True),
|
||||||
|
|
||||||
# Audio Playout
|
# Audio Playout
|
||||||
"PLAY": lambda: self._retMsg(self.play()),
|
"PLAY": lambda: self._retMsg(self.play()),
|
||||||
|
@ -466,6 +511,8 @@ class Player():
|
||||||
"PLAYONLOAD": lambda: self._retMsg(self.set_play_on_load(int(self.last_msg.split(":")[1]))),
|
"PLAYONLOAD": lambda: self._retMsg(self.set_play_on_load(int(self.last_msg.split(":")[1]))),
|
||||||
|
|
||||||
# Show Plan Items
|
# Show Plan Items
|
||||||
|
"GET_PLAN": lambda: self._retMsg(self.get_plan(int(self.last_msg.split(":")[1]))),
|
||||||
|
|
||||||
"LOAD": lambda: self._retMsg(self.load(int(self.last_msg.split(":")[1]))),
|
"LOAD": lambda: self._retMsg(self.load(int(self.last_msg.split(":")[1]))),
|
||||||
"LOADED?": lambda: self._retMsg(self.isLoaded),
|
"LOADED?": lambda: self._retMsg(self.isLoaded),
|
||||||
"UNLOAD": lambda: self._retMsg(self.unload()),
|
"UNLOAD": lambda: self._retMsg(self.unload()),
|
||||||
|
@ -479,6 +526,12 @@ class Player():
|
||||||
if message_type in message_types.keys():
|
if message_type in message_types.keys():
|
||||||
message_types[message_type]()
|
message_types[message_type]()
|
||||||
|
|
||||||
|
if message_type != "STATUS":
|
||||||
|
## Then a super hacky hack. Send the status again to update Webstudio
|
||||||
|
self._updateState()
|
||||||
|
self.last_msg = "STATUS"
|
||||||
|
self._retMsg(self.status, True)
|
||||||
|
|
||||||
elif (self.last_msg == 'QUIT'):
|
elif (self.last_msg == 'QUIT'):
|
||||||
self.running = False
|
self.running = False
|
||||||
continue
|
continue
|
||||||
|
@ -486,23 +539,25 @@ class Player():
|
||||||
else:
|
else:
|
||||||
self._retMsg("Unknown Command")
|
self._retMsg("Unknown Command")
|
||||||
else:
|
else:
|
||||||
|
|
||||||
if (self.last_msg == 'STATUS'):
|
if (self.last_msg == 'STATUS'):
|
||||||
self._retMsg(self.status)
|
self._retMsg(self.status)
|
||||||
else:
|
else:
|
||||||
self._retMsg(False)
|
self._retMsg(False)
|
||||||
|
|
||||||
#try:
|
|
||||||
#callback_event = event.poll()
|
|
||||||
#print(callback_event)
|
try:
|
||||||
#if callback_event.type == PLAYBACK_END:
|
callback_event = event.poll()
|
||||||
# if self.out_q:
|
if callback_event.type == PLAYBACK_END:
|
||||||
# print("Playback endded at end of Track.")
|
self.ended()
|
||||||
# self.out_q.put("STOP") # Tell clients that we've stopped playing.
|
else:
|
||||||
#elif callback_event.type == NOEVENT:
|
pass
|
||||||
# pass
|
except Exception as e:
|
||||||
#print("Another message")
|
pass
|
||||||
#except:
|
|
||||||
# pass
|
|
||||||
|
|
||||||
# Catch the player being killed externally.
|
# Catch the player being killed externally.
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
self.logger.log.info("Received KeyboardInterupt")
|
self.logger.log.info("Received KeyboardInterupt")
|
||||||
|
@ -510,8 +565,8 @@ class Player():
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
self.logger.log.info("Received SystemExit")
|
self.logger.log.info("Received SystemExit")
|
||||||
break
|
break
|
||||||
except:
|
except Exception as e:
|
||||||
self.logger.log.exception("Received unexpected exception.")
|
self.logger.log.exception("Received unexpected exception: {}".format(e))
|
||||||
break
|
break
|
||||||
|
|
||||||
self.logger.log.info("Quiting player ", channel)
|
self.logger.log.info("Quiting player ", channel)
|
||||||
|
|
35
server.py
35
server.py
|
@ -24,6 +24,7 @@ from typing import Any, Optional
|
||||||
import json
|
import json
|
||||||
import setproctitle
|
import setproctitle
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from helpers.os_environment import isMacOS
|
from helpers.os_environment import isMacOS
|
||||||
from helpers.device_manager import DeviceManager
|
from helpers.device_manager import DeviceManager
|
||||||
|
|
||||||
|
@ -48,6 +49,8 @@ default_state = {
|
||||||
"num_channels": 3
|
"num_channels": 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger = None
|
||||||
|
state = None
|
||||||
|
|
||||||
class BAPSicleServer():
|
class BAPSicleServer():
|
||||||
|
|
||||||
|
@ -57,6 +60,13 @@ class BAPSicleServer():
|
||||||
setproctitle.setproctitle(process_title)
|
setproctitle.setproctitle(process_title)
|
||||||
multiprocessing.current_process().name = process_title
|
multiprocessing.current_process().name = process_title
|
||||||
|
|
||||||
|
global logger
|
||||||
|
global state
|
||||||
|
logger = LoggingManager("BAPSicleServer")
|
||||||
|
|
||||||
|
state = StateManager("BAPSicleServer", logger, default_state)
|
||||||
|
state.update("server_version", config.VERSION)
|
||||||
|
|
||||||
asyncio.get_event_loop().run_until_complete(startServer())
|
asyncio.get_event_loop().run_until_complete(startServer())
|
||||||
asyncio.get_event_loop().run_forever()
|
asyncio.get_event_loop().run_forever()
|
||||||
|
|
||||||
|
@ -69,16 +79,21 @@ class PlayerHandler():
|
||||||
for channel in range(len(channel_from_q)):
|
for channel in range(len(channel_from_q)):
|
||||||
try:
|
try:
|
||||||
message = channel_from_q[channel].get_nowait()
|
message = channel_from_q[channel].get_nowait()
|
||||||
websocket_to_q[channel].put(message)
|
print("Player Handler saw:", message.split(":")[0])
|
||||||
ui_to_q[channel].put(message)
|
try:
|
||||||
|
websocket_to_q[channel].put_nowait(message)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
ui_to_q[channel].put_nowait(message)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
pass
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
|
|
||||||
logger = LoggingManager("BAPSicleServer")
|
|
||||||
|
|
||||||
state = StateManager("BAPSicleServer", logger, default_state)
|
|
||||||
state.update("server_version", config.VERSION)
|
|
||||||
|
|
||||||
app = Flask(__name__, static_url_path='')
|
app = Flask(__name__, static_url_path='')
|
||||||
|
|
||||||
|
@ -307,6 +322,14 @@ def channel_json(channel: int):
|
||||||
except:
|
except:
|
||||||
return status(channel)
|
return status(channel)
|
||||||
|
|
||||||
|
@app.route("/plan/load/<int:timeslotid>")
|
||||||
|
def load_showplan(timeslotid: int):
|
||||||
|
|
||||||
|
for channel in channel_to_q:
|
||||||
|
channel.put("GET_PLAN:" + str(timeslotid))
|
||||||
|
|
||||||
|
return ui_status()
|
||||||
|
|
||||||
def status(channel: int):
|
def status(channel: int):
|
||||||
channel_to_q[channel].put("STATUS")
|
channel_to_q[channel].put("STATUS")
|
||||||
i = 0
|
i = 0
|
||||||
|
|
|
@ -24,6 +24,7 @@ async def websocket_handler(websocket, path):
|
||||||
async for message in websocket:
|
async for message in websocket:
|
||||||
data = json.loads(message)
|
data = json.loads(message)
|
||||||
channel = int(data["channel"])
|
channel = int(data["channel"])
|
||||||
|
print(data)
|
||||||
if "command" in data.keys():
|
if "command" in data.keys():
|
||||||
if data["command"] == "PLAY":
|
if data["command"] == "PLAY":
|
||||||
channel_to_q[channel].put("PLAY")
|
channel_to_q[channel].put("PLAY")
|
||||||
|
@ -38,7 +39,6 @@ async def websocket_handler(websocket, path):
|
||||||
elif data["command"] == "LOAD":
|
elif data["command"] == "LOAD":
|
||||||
channel_to_q[channel].put("LOAD:" + str(data["weight"]))
|
channel_to_q[channel].put("LOAD:" + str(data["weight"]))
|
||||||
elif data["command"] == "ADD":
|
elif data["command"] == "ADD":
|
||||||
print(data)
|
|
||||||
if "managedId" in data["newItem"].keys() and isinstance(data["newItem"]["managedId"], str):
|
if "managedId" in data["newItem"].keys() and isinstance(data["newItem"]["managedId"], str):
|
||||||
if data["newItem"]["managedId"].startswith("managed"):
|
if data["newItem"]["managedId"].startswith("managed"):
|
||||||
managed_id = int(data["newItem"]["managedId"].split(":")[1])
|
managed_id = int(data["newItem"]["managedId"].split(":")[1])
|
||||||
|
@ -76,15 +76,21 @@ async def websocket_handler(websocket, path):
|
||||||
for channel in range(len(webstudio_to_q)):
|
for channel in range(len(webstudio_to_q)):
|
||||||
try:
|
try:
|
||||||
message = webstudio_to_q[channel].get_nowait()
|
message = webstudio_to_q[channel].get_nowait()
|
||||||
if not message.startswith("STATUS"):
|
command = message.split(":")[0]
|
||||||
continue # Ignore non state updates for now.
|
print("Websocket Out:", command)
|
||||||
try:
|
if command == "STATUS":
|
||||||
message = message.split("OKAY:")[1]
|
try:
|
||||||
message = json.loads(message)
|
message = message.split("OKAY:")[1]
|
||||||
except:
|
message = json.loads(message)
|
||||||
pass
|
except:
|
||||||
|
continue
|
||||||
|
elif command == "POS":
|
||||||
|
message = message.split(":")[1]
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
data = json.dumps({
|
data = json.dumps({
|
||||||
"command": "STATUS",
|
"command": command,
|
||||||
"data": message,
|
"data": message,
|
||||||
"channel": channel
|
"channel": channel
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue