Fix enclosure issues for our first run wizard.

QuickFix for now, will be changed by proper enclosure plugin.
This commit is contained in:
j1nx 2021-02-18 20:35:00 +01:00
parent b732a1221a
commit 8968f515a0
1 changed files with 293 additions and 0 deletions

View File

@ -0,0 +1,293 @@
From ae33770b5b842b9ac51fa7eefcb9b3808590f2e8 Mon Sep 17 00:00:00 2001
From: jarbasal <jarbasai@mailfence.com>
Date: Thu, 18 Feb 2021 18:28:31 +0000
Subject: [PATCH 1/2] enclosure cleanup
---
mycroft/client/enclosure/base.py | 39 ++++++
mycroft/client/enclosure/generic/__init__.py | 139 +------------------
2 files changed, 42 insertions(+), 136 deletions(-)
diff --git a/mycroft/client/enclosure/base.py b/mycroft/client/enclosure/base.py
index 4d26a42f43f..7d55040d13b 100644
--- a/mycroft/client/enclosure/base.py
+++ b/mycroft/client/enclosure/base.py
@@ -23,6 +23,7 @@
from mycroft.util.log import LOG
import json
+import time
import tornado.web as web
from tornado import ioloop
from tornado.websocket import WebSocketHandler
@@ -70,6 +71,10 @@ def __init__(self):
# Create Message Bus Client
self.bus = MessageBusClient()
+ # TODO: this requires the Enclosure to be up and running before the
+ # training is complete.
+ self.bus.on('mycroft.skills.trained', self.is_device_ready)
+
self.gui = create_gui_service(self, config['gui_websocket'])
# This datastore holds the data associated with the GUI provider. Data
# is stored in Namespaces, so you can have:
@@ -115,6 +120,40 @@ def stop(self):
"""Perform any enclosure shutdown processes."""
pass
+ def is_device_ready(self, message):
+ is_ready = False
+ # Bus service assumed to be alive if messages sent and received
+ # Enclosure assumed to be alive if this method is running
+ services = {'audio': False, 'speech': False, 'skills': False}
+ start = time.monotonic()
+ while not is_ready:
+ is_ready = self.check_services_ready(services)
+ if is_ready:
+ break
+ elif time.monotonic() - start >= 60:
+ raise Exception('Timeout waiting for services start.')
+ else:
+ time.sleep(3)
+
+ if is_ready:
+ LOG.info("Mycroft is all loaded and ready to roll!")
+ self.bus.emit(Message('mycroft.ready'))
+
+ return is_ready
+
+ def check_services_ready(self, services):
+ """Report if all specified services are ready.
+
+ services (iterable): service names to check.
+ """
+ for ser in services:
+ services[ser] = False
+ response = self.bus.wait_for_response(Message(
+ 'mycroft.{}.is_ready'.format(ser)))
+ if response and response.data['status']:
+ services[ser] = True
+ return all([services[ser] for ser in services])
+
######################################################################
# GUI client API
@property
diff --git a/mycroft/client/enclosure/generic/__init__.py b/mycroft/client/enclosure/generic/__init__.py
index 3c47a545943..23c4fde794c 100644
--- a/mycroft/client/enclosure/generic/__init__.py
+++ b/mycroft/client/enclosure/generic/__init__.py
@@ -12,144 +12,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-import subprocess
-import time
-import sys
-from threading import Thread, Timer
-
-import mycroft.dialog
from mycroft.client.enclosure.base import Enclosure
-from mycroft.api import has_been_paired
-from mycroft.audio import wait_while_speaking
-from mycroft.enclosure.display_manager import \
- init_display_manager_bus_connection
-from mycroft.messagebus.message import Message
-from mycroft.util import connected
-from mycroft.util.log import LOG
class EnclosureGeneric(Enclosure):
"""
- Serves as a communication interface between a simple text frontend and
- Mycroft Core. This is used for Picroft or other headless systems,
- and/or for users of the CLI.
- """
-
- _last_internet_notification = 0
-
- def __init__(self):
- super().__init__()
-
- # Notifications from mycroft-core
- self.bus.on('enclosure.notify.no_internet', self.on_no_internet)
- # TODO: this requires the Enclosure to be up and running before the
- # training is complete.
- self.bus.on('mycroft.skills.trained', self.is_device_ready)
-
- # initiates the web sockets on display manager
- # NOTE: this is a temporary place to connect the display manager
- init_display_manager_bus_connection()
-
- # verify internet connection and prompt user on bootup if needed
- if not connected():
- # We delay this for several seconds to ensure that the other
- # clients are up and connected to the messagebus in order to
- # receive the "speak". This was sometimes happening too
- # quickly and the user wasn't notified what to do.
- Timer(5, self._do_net_check).start()
-
- def is_device_ready(self, message):
- is_ready = False
- # Bus service assumed to be alive if messages sent and received
- # Enclosure assumed to be alive if this method is running
- services = {'audio': False, 'speech': False, 'skills': False}
- start = time.monotonic()
- while not is_ready:
- is_ready = self.check_services_ready(services)
- if is_ready:
- break
- elif time.monotonic() - start >= 60:
- raise Exception('Timeout waiting for services start.')
- else:
- time.sleep(3)
-
- if is_ready:
- LOG.info("Mycroft is all loaded and ready to roll!")
- self.bus.emit(Message('mycroft.ready'))
-
- return is_ready
-
- def check_services_ready(self, services):
- """Report if all specified services are ready.
-
- services (iterable): service names to check.
- """
- for ser in services:
- services[ser] = False
- response = self.bus.wait_for_response(Message(
- 'mycroft.{}.is_ready'.format(ser)))
- if response and response.data['status']:
- services[ser] = True
- return all([services[ser] for ser in services])
-
- def on_no_internet(self, event=None):
- if connected():
- # One last check to see if connection was established
- return
-
- if time.time() - Enclosure._last_internet_notification < 30:
- # don't bother the user with multiple notifications with 30 secs
- return
-
- Enclosure._last_internet_notification = time.time()
-
- # TODO: This should go into EnclosureMark1 subclass of Enclosure.
- if has_been_paired():
- # Handle the translation within that code.
- self.bus.emit(Message("speak", {
- 'utterance': "This device is not connected to the Internet. "
- "Either plug in a network cable or set up your "
- "wifi connection."}))
- else:
- # enter wifi-setup mode automatically
- self.bus.emit(Message('system.wifi.setup', {'lang': self.lang}))
-
- def speak(self, text):
- self.bus.emit(Message("speak", {'utterance': text}))
-
- def _handle_pairing_complete(self, _):
- """
- Handler for 'mycroft.paired', unmutes the mic after the pairing is
- complete.
- """
- self.bus.emit(Message("mycroft.mic.unmute"))
-
- def _do_net_check(self):
- # TODO: This should live in the derived Enclosure, e.g. EnclosureMark1
- LOG.info("Checking internet connection")
- if not connected(): # and self.conn_monitor is None:
- if has_been_paired():
- # TODO: Enclosure/localization
- self.speak("This unit is not connected to the Internet. "
- "Either plug in a network cable or setup your "
- "wifi connection.")
- else:
- # Begin the unit startup process, this is the first time it
- # is being run with factory defaults.
-
- # TODO: This logic should be in EnclosureMark1
- # TODO: Enclosure/localization
-
- # Don't listen to mic during this out-of-box experience
- self.bus.emit(Message("mycroft.mic.mute"))
- # Setup handler to unmute mic at the end of on boarding
- # i.e. after pairing is complete
- self.bus.once('mycroft.paired', self._handle_pairing_complete)
-
- self.speak(mycroft.dialog.get('mycroft.intro'))
- wait_while_speaking()
- time.sleep(2) # a pause sounds better than just jumping in
-
- # Kick off wifi-setup automatically
- data = {'allow_timeout': False, 'lang': self.lang}
- self.bus.emit(Message('system.wifi.setup', data))
+ Serves as a communication interface between GUI and
+ Mycroft Core. This is used for Picroft or other headless systems
+ """
\ No newline at end of file
From a5ab14ae5acc5c88fef2dbb23a6729d1eff5ca9e Mon Sep 17 00:00:00 2001
From: jarbasal <jarbasai@mailfence.com>
Date: Thu, 18 Feb 2021 19:24:59 +0000
Subject: [PATCH 2/2] only report ready after pairing
---
mycroft/client/enclosure/base.py | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/mycroft/client/enclosure/base.py b/mycroft/client/enclosure/base.py
index 7d55040d13b..aacefe46449 100644
--- a/mycroft/client/enclosure/base.py
+++ b/mycroft/client/enclosure/base.py
@@ -16,7 +16,7 @@
from collections import namedtuple
from threading import Lock
-
+from mycroft.api import is_paired
from mycroft.configuration import Configuration
from mycroft.messagebus.client import MessageBusClient
from mycroft.util import create_daemon, start_message_bus_client
@@ -73,7 +73,8 @@ def __init__(self):
# TODO: this requires the Enclosure to be up and running before the
# training is complete.
- self.bus.on('mycroft.skills.trained', self.is_device_ready)
+ self.bus.once('mycroft.skills.trained',
+ self.handle_check_device_readiness)
self.gui = create_gui_service(self, config['gui_websocket'])
# This datastore holds the data associated with the GUI provider. Data
@@ -120,7 +121,7 @@ def stop(self):
"""Perform any enclosure shutdown processes."""
pass
- def is_device_ready(self, message):
+ def is_device_ready(self):
is_ready = False
# Bus service assumed to be alive if messages sent and received
# Enclosure assumed to be alive if this method is running
@@ -134,12 +135,19 @@ def is_device_ready(self, message):
raise Exception('Timeout waiting for services start.')
else:
time.sleep(3)
+ return is_ready
- if is_ready:
- LOG.info("Mycroft is all loaded and ready to roll!")
- self.bus.emit(Message('mycroft.ready'))
+ def handle_check_device_readiness(self, message):
- return is_ready
+ def handle_ready(message=None):
+ if self.is_device_ready():
+ LOG.info("Mycroft is all loaded and ready to roll!")
+ self.bus.emit(Message('mycroft.ready'))
+
+ if not is_paired():
+ self.bus.once("mycroft.paired", handle_ready)
+ else:
+ handle_ready()
def check_services_ready(self, services):
"""Report if all specified services are ready.