gui_server.py
Go to the documentation of this file.
1 # Copyright 2018 Mycroft AI Inc.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 #
15 
16 from os import getpid
17 from os.path import basename
18 import json
19 import websocket
20 from threading import Thread, Lock
21 
22 from mycroft.messagebus.client.ws import WebsocketClient
23 from mycroft.messagebus.message import Message
24 
25 
26 bus = None
27 buffer = None # content will show on the CLI "GUI" representation
28 msgs = []
29 
30 loaded = []
31 skill = None
32 page = None
33 vars = {}
34 
35 
36 def start_qml_gui(messagebus, output_buf):
37  global bus
38  global buffer
39 
40  bus = messagebus
41  buffer = output_buf
42 
43  # Initiate the QML GUI
44  log_message("Announcing CLI GUI")
45  bus.on('mycroft.gui.port', handle_gui_ready)
46  bus.emit(Message("mycroft.gui.connected",
47  {"gui_id": "cli_" + str(getpid())}))
48  log_message("Announced CLI GUI")
49 
50 
51 def log_message(msg):
52  global msgs
53  msgs.append(msg)
54  if len(msgs) > 20:
55  del msgs[0]
57 
58 
60  global buffer
61  buffer.clear()
62  try:
63  if skill:
64  buffer.append("Active Skill: {}".format(skill))
65  buffer.append("Page: {}".format(basename(page)))
66  buffer.append("vars: ")
67  for v in vars[skill]:
68  buffer.append(" {}: {}".format(v, vars[skill][v]))
69  except Exception as e:
70  buffer.append(repr(e))
71  buffer.append("-----------------")
72  buffer.append("MESSAGES")
73  buffer.append("-----------------")
74  for m in msgs:
75  if len(buffer) > 20: # cap out at 20 lines total
76  return
77  buffer.append(m)
78 
79 
81  # Attempt to connect to the port
82  gui_id = msg.data.get("gui_id")
83  if not gui_id == "cli_" + str(getpid()):
84  # Not us, ignore!
85  return
86 
87  # Create the websocket for GUI communications
88  port = msg.data.get("port")
89  if port:
90  log_message("Connecting CLI GUI on "+str(port))
91  ws = websocket.WebSocketApp("ws://0.0.0.0:" + str(port) + "/gui",
92  on_message=on_gui_message,
93  on_error=on_gui_error,
94  on_close=on_gui_close)
95 
96  log_message("WS = "+str(ws))
97  event_thread = Thread(target=gui_connect, args=[ws])
98  event_thread.setDaemon(True)
99  event_thread.start()
100 
101 
102 def gui_connect(ws):
103  # Once the websocket has connected, just watch it for speak events
104  log_message("GUI Connected"+str(ws))
105  ws.on_open = on_gui_open
106  ws.run_forever()
107 
108 
109 def on_gui_open(ws):
110  log_message("GUI Opened")
111 
112 
113 def on_gui_message(ws, payload):
114  global loaded
115  global skill
116  global page
117  global vars
118  try:
119  msg = json.loads(payload)
120  log_message("Msg: "+str(payload))
121  type = msg.get("type")
122  if type == "mycroft.session.set":
123  skill = msg.get("namespace")
124  data = msg.get("data")
125  if skill not in vars:
126  vars[skill] = {}
127  for d in data:
128  vars[skill][d] = data[d]
129  elif type == "mycroft.session.list.insert":
130  # Insert new namespace
131  skill = msg.get('data')[0]['skill_id']
132  loaded.insert(0, [skill, []])
133  elif type == "mycroft.gui.list.insert":
134  # Insert a page in an existing namespace
135  page = msg['data'][0]['url']
136  pos = msg.get('position')
137  loaded[0][1].insert(pos, page)
138  skill = loaded[0][0]
139  elif type == "mycroft.session.list.move":
140  # Move the namespace at "pos" to the top of the stack
141  pos = msg.get('from')
142  loaded.insert(0, loaded.pop(pos))
143  elif type == "mycroft.events.triggered":
144  # Switch selected page of namespace
145  skill = msg['namespace']
146  pos = msg['data']['number']
147  for n in loaded:
148  if n[0] == skill:
149  page = n[1][pos]
150 
152  except Exception as e:
153  log_message(repr(e))
154  log_message("Invalid JSON: "+str(payload))
155 
156 
157 def on_gui_close(ws):
158  log_message("GUI closed")
159 
160 
161 def on_gui_error(ws, err):
162  log_message("GUI error: "+str(err))
def start_qml_gui(messagebus, output_buf)
Definition: gui_server.py:36
def on_gui_message(ws, payload)
Definition: gui_server.py:113


mycroft_ros
Author(s):
autogenerated on Mon Apr 26 2021 02:35:40