parent
54daa84786
commit
07bd6ef7af
|
@ -18,6 +18,7 @@ from mycroft.util.log import LOG
|
|||
from mycroft.messagebus.client.ws import WebsocketClient
|
||||
from mycroft.configuration import Configuration, LocalConf, SYSTEM_CONFIG
|
||||
|
||||
|
||||
def main():
|
||||
# Read the system configuration
|
||||
system_config = LocalConf(SYSTEM_CONFIG)
|
||||
|
@ -32,9 +33,10 @@ def main():
|
|||
from mycroft.client.enclosure.mark2 import Enclosure_Mark2
|
||||
enclosure = Enclosure_Mark2()
|
||||
else:
|
||||
LOG.debug("Creating generic enclosure (platform='{}')".format(platform))
|
||||
LOG.debug("Creating generic enclosure, platform='{}'".format(platform))
|
||||
|
||||
# TODO: Mechanism to load from elsewhere?
|
||||
# TODO: Mechanism to load from elsewhere. E.g. read a script path from
|
||||
# the mycroft.conf, then load/launch that script.
|
||||
from mycroft.client.enclosure.generic import Enclosure_Generic
|
||||
enclosure = Enclosure_Generic()
|
||||
|
||||
|
@ -50,6 +52,5 @@ def main():
|
|||
LOG.debug("No enclosure available for this hardware, running headless")
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -27,7 +27,8 @@ from mycroft.messagebus.message import Message
|
|||
|
||||
|
||||
def DEBUG(str):
|
||||
print(str)
|
||||
# print(str)
|
||||
pass # disable by default
|
||||
|
||||
|
||||
class Enclosure(object):
|
||||
|
@ -54,7 +55,6 @@ class Enclosure(object):
|
|||
self.bus.on("gui.value.set", self.on_gui_set_value)
|
||||
self.bus.on("gui.page.show", self.on_gui_show_page)
|
||||
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
self.bus.run_forever()
|
||||
|
@ -69,7 +69,7 @@ class Enclosure(object):
|
|||
if not namespace:
|
||||
return
|
||||
|
||||
if not namespace in self._active_namespaces:
|
||||
if namespace not in self._active_namespaces:
|
||||
if move_to_top:
|
||||
self._active_namespaces.insert(0, namespace)
|
||||
else:
|
||||
|
@ -79,10 +79,10 @@ class Enclosure(object):
|
|||
self._active_namespaces.insert(0, namespace)
|
||||
# TODO: Keep a timestamp and auto-cull?
|
||||
|
||||
|
||||
def on_gui_set_value(self, message):
|
||||
data = message.data
|
||||
namespace = data.get("__from", "")
|
||||
|
||||
self._gui_activate(namespace)
|
||||
|
||||
# Pass these values on to the GUI renderers
|
||||
|
@ -93,7 +93,7 @@ class Enclosure(object):
|
|||
|
||||
def on_gui_show_page(self, message):
|
||||
data = message.data
|
||||
if not 'page' in data:
|
||||
if 'page' not in data:
|
||||
return
|
||||
namespace = data.get("__from", "")
|
||||
self._gui_activate(namespace, move_to_top=True)
|
||||
|
@ -179,6 +179,7 @@ gui_app_settings = {
|
|||
'debug': True
|
||||
}
|
||||
|
||||
|
||||
class GUIConnection(object):
|
||||
""" A single GUIConnection exists per graphic interface. This object
|
||||
maintains the socket used for communication and keeps the state of the
|
||||
|
@ -197,7 +198,7 @@ class GUIConnection(object):
|
|||
TODO: Implement data coming back from Qt to Mycroft
|
||||
"""
|
||||
|
||||
last_used_port = 0
|
||||
_last_idx = 0 # this is incremented by 1 for each open GUIConnection
|
||||
server_thread = None
|
||||
|
||||
def __init__(self, id, config, callback_disconnect, enclosure):
|
||||
|
@ -223,8 +224,8 @@ class GUIConnection(object):
|
|||
websocket_config = config.get("gui_websocket")
|
||||
host = websocket_config.get("host")
|
||||
route = websocket_config.get("route")
|
||||
self.port = websocket_config.get("base_port") + GUIConnection.last_used_port
|
||||
GUIConnection.last_used_port += 1
|
||||
self.port = websocket_config.get("base_port") + GUIConnection._last_idx
|
||||
GUIConnection._last_idx += 1
|
||||
|
||||
self.webapp = tornado.web.Application([
|
||||
(route, GUIWebsocketHandler)
|
||||
|
@ -235,8 +236,9 @@ class GUIConnection(object):
|
|||
# TODO: This might need to move up a level
|
||||
# Can't run two IOLoop's in the same process
|
||||
if not GUIConnection.server_thread:
|
||||
GUIConnection.server_thread = create_daemon(ioloop.IOLoop.instance().start)
|
||||
DEBUG("IOLoop started on ws://"+str(host)+":"+str(self.port)+str(route))
|
||||
GUIConnection.server_thread = create_daemon(
|
||||
ioloop.IOLoop.instance().start)
|
||||
DEBUG("IOLoop started @ ws://"+str(host)+":"+str(self.port)+str(route))
|
||||
|
||||
def on_connection_opened(self, socket_handler):
|
||||
DEBUG("on_connection_opened")
|
||||
|
@ -264,16 +266,17 @@ class GUIConnection(object):
|
|||
def set(self, namespace, name, value):
|
||||
self.sync_active()
|
||||
|
||||
if not namespace in self.datastore:
|
||||
if namespace not in self.datastore:
|
||||
self.datastore[namespace] = {}
|
||||
if self.datastore[namespace].get(name) != value:
|
||||
msg = { "type": "mycroft.session.set",
|
||||
"namespace": namespace,
|
||||
"data": { name: value}}
|
||||
msg = {"type": "mycroft.session.set",
|
||||
"namespace": namespace,
|
||||
"data": {name: value}}
|
||||
self.socket.send(msg)
|
||||
self.datastore[namespace][name] = value
|
||||
|
||||
def show(self, namespace, page):
|
||||
DEBUG("GUIConnection activating: "+namespace)
|
||||
self.sync_active()
|
||||
|
||||
self.socket.send({"type": "mycroft.gui.show",
|
||||
|
@ -286,27 +289,21 @@ class GUIConnection(object):
|
|||
# The main Enclosure keeps a list of active skills. Each GUI also
|
||||
# has a list. Synchronize when appropriate.
|
||||
if self.enclosure._active_namespaces != self._active_namespaces:
|
||||
# TODO: Optimize bandwidth using list.insert, etc.
|
||||
#self.socket.send({"type": "mycroft.session.list.insert",
|
||||
# "namespace": "mycroft.system.active_skills",
|
||||
## "position": 0,
|
||||
# "data": [{'skill_id': self.enclosure._active_namespaces[0] }]
|
||||
# })
|
||||
|
||||
# First, zap the old list
|
||||
if self._active_namespaces:
|
||||
self.socket.send({"type": "mycroft.session.list.remove",
|
||||
"namespace": "mycroft.system.active_skills",
|
||||
"position": 0,
|
||||
"items_number": len(self._active_namespaces)})
|
||||
"namespace": "mycroft.system.active_skills",
|
||||
"position": 0,
|
||||
"items_number": len(self._active_namespaces)
|
||||
})
|
||||
|
||||
# Now fill it back up
|
||||
for ns in reversed(self.enclosure._active_namespaces):
|
||||
self.socket.send({"type": "mycroft.session.list.insert",
|
||||
"namespace": "mycroft.system.active_skills",
|
||||
"position": 0,
|
||||
"data": [{'skill_id': ns }]
|
||||
})
|
||||
"data": [{'skill_id': ns}]
|
||||
})
|
||||
self._active_namespaces = self.enclosure._active_namespaces.copy()
|
||||
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ class Enclosure_Generic(object):
|
|||
"""
|
||||
|
||||
_last_internet_notification = 0
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ from queue import Queue
|
|||
# The Arduino can also send back notifications in response to either
|
||||
# pressing or turning a rotary encoder.
|
||||
|
||||
|
||||
class EnclosureReader(Thread):
|
||||
"""
|
||||
Reads data from Serial port.
|
||||
|
@ -335,7 +336,7 @@ class Enclosure_Mark1(Enclosure):
|
|||
url=self.port, baudrate=self.rate, timeout=self.timeout)
|
||||
LOG.info("Connected to: %s rate: %s timeout: %s" %
|
||||
(self.port, self.rate, self.timeout))
|
||||
except:
|
||||
except except Exception:
|
||||
LOG.error("Impossible to connect to serial port: "+str(self.port))
|
||||
raise
|
||||
|
||||
|
|
|
@ -14,9 +14,10 @@
|
|||
#
|
||||
from mycroft.client.enclosure.base import Enclosure
|
||||
|
||||
|
||||
class Enclosure_Mark2(Enclosure):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
# TODO: Any Mark II specific startup actions
|
||||
# TODO: Any Mark II specific startup actions
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2017 Mycroft AI Inc.
|
||||
# Copyright 2018 Mycroft AI Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -30,6 +30,7 @@ skill = None
|
|||
page = None
|
||||
vars = {}
|
||||
|
||||
|
||||
def start_qml_gui(messagebus, output_buf):
|
||||
global bus
|
||||
global buffer
|
||||
|
@ -41,8 +42,7 @@ def start_qml_gui(messagebus, output_buf):
|
|||
log_message("Announcing CLI GUI")
|
||||
bus.on('mycroft.gui.port', handle_gui_ready)
|
||||
bus.emit(Message("mycroft.gui.connected",
|
||||
{"gui_id" : "cli_" + str(getpid())}))
|
||||
|
||||
{"gui_id": "cli_" + str(getpid())}))
|
||||
log_message("Announced CLI GUI")
|
||||
|
||||
|
||||
|
@ -72,6 +72,7 @@ def build_output_buffer():
|
|||
return
|
||||
buffer.append(m)
|
||||
|
||||
|
||||
def handle_gui_ready(msg):
|
||||
# Attempt to connect to the port
|
||||
gui_id = msg.data.get("gui_id")
|
||||
|
@ -83,11 +84,10 @@ def handle_gui_ready(msg):
|
|||
port = msg.data.get("port")
|
||||
if port:
|
||||
log_message("Connecting CLI GUI on "+str(port))
|
||||
#ws = create_connection("ws://0.0.0.0:" + str(port) + "/gui",
|
||||
ws = websocket.WebSocketApp("ws://0.0.0.0:" + str(port) + "/gui",
|
||||
on_message=on_gui_message,
|
||||
on_error=on_gui_error,
|
||||
on_close=on_gui_close)
|
||||
on_message=on_gui_message,
|
||||
on_error=on_gui_error,
|
||||
on_close=on_gui_close)
|
||||
|
||||
log_message("WS = "+str(ws))
|
||||
event_thread = Thread(target=gui_connect, args=[ws])
|
||||
|
@ -115,7 +115,7 @@ def on_gui_message(ws, payload):
|
|||
global vars
|
||||
namespace = msg.get("namespace")
|
||||
data = msg.get("data")
|
||||
if not namespace in vars:
|
||||
if namespace not in vars:
|
||||
vars[namespace] = {}
|
||||
for d in data:
|
||||
vars[namespace][d] = data[d]
|
||||
|
|
|
@ -409,9 +409,9 @@ def handle_message(msg):
|
|||
# add_log_message(msg)
|
||||
pass
|
||||
|
||||
|
||||
##############################################################################
|
||||
# "Graphic primitives"
|
||||
|
||||
def draw(x, y, msg, pad=None, pad_chr=None, clr=None):
|
||||
"""Draw a text to the screen
|
||||
|
||||
|
@ -445,7 +445,7 @@ def draw(x, y, msg, pad=None, pad_chr=None, clr=None):
|
|||
if not clr:
|
||||
clr = CLR_LOG1
|
||||
|
||||
scr.addstr(y,x, s, clr)
|
||||
scr.addstr(y, x, s, clr)
|
||||
|
||||
|
||||
##############################################################################
|
||||
|
@ -575,11 +575,12 @@ def _do_meter(height):
|
|||
scr.addstr(curses.LINES - 1 - i, curses.COLS - len(str_thresh) - 4,
|
||||
"*", clr_bar)
|
||||
|
||||
|
||||
def _do_gui(gui_width):
|
||||
clr = curses.color_pair(2) # dark red
|
||||
x = curses.COLS - gui_width
|
||||
y = 3
|
||||
draw(x,y, " "+make_titlebar("= GUI", gui_width-1)+" ", clr=CLR_HEADING)
|
||||
draw(x, y, " "+make_titlebar("= GUI", gui_width-1)+" ", clr=CLR_HEADING)
|
||||
cnt = len(gui_text)+1
|
||||
if cnt > curses.LINES-15:
|
||||
cnt = curses.LINES-15
|
||||
|
@ -590,7 +591,8 @@ def _do_gui(gui_width):
|
|||
else:
|
||||
draw(x+2, y+1+i, "*"*(gui_width-3))
|
||||
draw(x+(gui_width-1), y+1+i, "!", clr=CLR_HEADING)
|
||||
draw(x,y+cnt, " "+"-"*(gui_width-2)+" ", clr=CLR_HEADING)
|
||||
draw(x, y+cnt, " "+"-"*(gui_width-2)+" ", clr=CLR_HEADING)
|
||||
|
||||
|
||||
def set_screen_dirty():
|
||||
global is_screen_dirty
|
||||
|
@ -998,7 +1000,7 @@ def _get_cmd_param(cmd, keyword):
|
|||
# Returns parameter to a command. Will de-quote.
|
||||
# Ex: find 'abc def' returns: abc def
|
||||
# find abc def returns: abc def
|
||||
cmd = cmd.replace(keyword,"").strip()
|
||||
cmd = cmd.replace(keyword, "").strip()
|
||||
if not cmd:
|
||||
return None
|
||||
|
||||
|
|
|
@ -263,7 +263,7 @@ class SkillGUI(object):
|
|||
# Then request display of the correct page
|
||||
self.skill.bus.emit(Message("gui.page.show",
|
||||
{"page": page_url,
|
||||
'__from': self.skill.skill_id}))
|
||||
'__from': self.skill.skill_id}))
|
||||
else:
|
||||
self.skill.log.debug("Unable to find page: " + str(self.page))
|
||||
|
||||
|
|
Loading…
Reference in New Issue