Switch balena phal skill over to general wifi phal plugin

This commit is contained in:
j1nx 2022-05-27 20:08:11 +02:00
parent 8c1e8abd46
commit 6b4833d988
1 changed files with 280 additions and 0 deletions

View File

@ -0,0 +1,280 @@
From 6b34ebccc767f33d060ed40b5c46ebb4ee34ca2f Mon Sep 17 00:00:00 2001
From: Aditya Mehra <aix.m@outlook.com>
Date: Fri, 27 May 2022 18:12:21 +0930
Subject: [PATCH] Adapt and port to wifi plugin
---
ovos_PHAL_plugin_balena_wifi/__init__.py | 197 +++++++++++------------
1 file changed, 91 insertions(+), 106 deletions(-)
diff --git a/ovos_PHAL_plugin_balena_wifi/__init__.py b/ovos_PHAL_plugin_balena_wifi/__init__.py
index 0a0f64d..8f80c0d 100644
--- a/ovos_PHAL_plugin_balena_wifi/__init__.py
+++ b/ovos_PHAL_plugin_balena_wifi/__init__.py
@@ -1,102 +1,98 @@
-from os.path import join, dirname
+import random
+from os.path import dirname, join
+from time import sleep
import pexpect
-import random
-import subprocess
from mycroft_bus_client.message import Message, dig_for_message
from ovos_plugin_manager.phal import PHALPlugin
-from ovos_utils import create_daemon
-from ovos_utils.enclosure.api import EnclosureAPI
from ovos_utils.gui import GUIInterface
from ovos_utils.log import LOG
-from ovos_utils.network_utils import is_connected
-from time import sleep
class BalenaWifiSetupPlugin(PHALPlugin):
def __init__(self, bus=None, config=None):
super().__init__(bus=bus, name="ovos-PHAL-plugin-balena-wifi", config=config)
- self.monitoring = False
+ self.gui = GUIInterface(bus=self.bus, skill_id=self.name)
+ self.client_active = False
+ self.client_id = None
+ self.registered = False
self.in_setup = False
- self.connected = False
+
self.wifi_process = None
- self.debug = False # dev setting, VERY VERBOSE DIALOGS
+ self.debug = True # dev setting, VERY VERBOSE DIALOGS
self.ssid = "OVOS"
self.pswd = None
- self.grace_period = 45
- self.time_between_checks = 30 # seconds
- self.mycroft_ready = False
self.wifi_command = "sudo /usr/local/sbin/wifi-connect --portal-ssid {ssid}"
if self.pswd:
self.wifi_command += " --portal-passphrase {pswd}"
self.color = "#FF0000"
- self.stop_on_internet = False
- self.timeout_after_internet = 90
-
- self.bus.on("mycroft.internet.connected", self.handle_internet_connected)
-
- self.enclosure = EnclosureAPI(bus=self.bus, skill_id=self.name)
- self.gui = GUIInterface(bus=self.bus, skill_id=self.name)
- self.start_internet_check()
-
- # internet watchdog
- def start_internet_check(self):
- create_daemon(self._watchdog)
-
- def stop_internet_check(self):
- self.monitoring = False
-
- def _watchdog(self):
- try:
- self.monitoring = True
- LOG.info("Wifi watchdog started")
- output = subprocess.check_output("nmcli connection show",
- shell=True).decode("utf-8")
- if "wifi" in output:
- LOG.info("Detected previously configured wifi, starting "
- "grace period to allow it to connect")
- sleep(self.grace_period)
- while self.monitoring:
- if self.in_setup:
- sleep(1) # let setup do it's thing
- continue
-
- if not is_connected():
- LOG.info("NO INTERNET")
- if not self.is_connected_to_wifi():
- LOG.info("LAUNCH SETUP")
- try:
- self.launch_wifi_setup() # blocking
- except Exception as e:
- LOG.exception(e)
- else:
- LOG.warning("CONNECTED TO WIFI, BUT NO INTERNET!!")
-
- sleep(self.time_between_checks)
- except Exception as e:
- LOG.error("Wifi watchdog crashed unexpectedly")
- LOG.exception(e)
-
- # wifi setup
- @staticmethod
- def get_wifi_ssid():
- SSID = None
- try:
- SSID = subprocess.check_output(["iwgetid", "-r"]).strip()
- except subprocess.CalledProcessError:
- # If there is no connection subprocess throws a 'CalledProcessError'
- pass
- return SSID
-
- @staticmethod
- def is_connected_to_wifi():
- return BalenaWifiSetupPlugin.get_wifi_ssid() is not None
-
- def launch_wifi_setup(self):
- if not self.in_setup:
- self.bus.emit(Message("ovos.wifi.setup.started"))
- self.stop_setup()
+
+ # WIFI Plugin Registeration and Activation Specific Events
+ self.bus.on("ovos.phal.wifi.plugin.stop.setup.event", self.handle_stop_setup)
+ self.bus.on("ovos.phal.wifi.plugin.client.registered", self.handle_registered)
+ self.bus.on("ovos.phal.wifi.plugin.client.deregistered", self.handle_deregistered)
+ self.bus.on("ovos.phal.wifi.plugin.client.registration.failure", self.handle_registration_failure)
+
+ # Try Register the Client with WIFI Plugin on Startup
+ self.register_client()
+
+ # Wifi Plugin Registeration Handling
+ def register_client(self):
+ self.bus.emit(Message("ovos.phal.wifi.plugin.register.client", {
+ "client": self.name,
+ "type": "Remote",
+ "display_text": "On Mobile Setup",
+ "has_gui": True,
+ "requires_input": False
+ }))
+
+ def handle_registered(self, message=None):
+ get_client = message.data.get("client", "")
+ if get_client == self.name:
+ get_id = message.data.get("id", "")
+ self.client_id = get_id
+ self.registered = True
+ self.bus.on(f"ovos.phal.wifi.plugin.activate.{self.client_id}", self.handle_activate_client_request)
+ self.bus.on(f"ovos.phal.wifi.plugin.deactivate.{self.client_id}", self.handle_deactivate_client_request)
+ LOG.info(f"Client Registered with WIFI Plugin: {self.client_id}")
+
+ def handle_deregistered(self, message=None):
+ self.registered = False
+ self.bus.remove(f"ovos.phal.wifi.plugin.activate.{self.client_id}", self.handle_active_client_request)
+ self.bus.remove(f"ovos.phal.wifi.plugin.deactivate.{self.client_id}", self.handle_deactivate_client_request)
+ self.client_id = None
+
+ def handle_registration_failure(self, message=None):
+ if not self.registered:
+ error = message.data.get("error", "")
+ LOG.info(f"Registration Failure: {error}")
+ # Try to Register the Client with WIFI Plugin Again
+ self.register_client()
+
+ def handle_activate_client_request(self, message=None):
+ LOG.info("Balena Wifi Plugin Activated")
+ self.client_active = True
+ self.display_network_setup()
+
+ def handle_deactivate_client_request(self, message=None):
+ LOG.info("Balena Wifi Plugin Deactivated")
+ self.cleanup_wifi_process()
+ self.client_active = False
+ self.gui.release()
+
+ def request_deactivate(self, message=None):
+ self.bus.emit(Message("ovos.phal.wifi.plugin.remove.active.client", {
+ "client": "ovos-PHAL-plugin-balena-wifi"}))
+ LOG.info("Balena Wifi Plugin Deactivation Requested")
+
+ def display_network_setup(self):
+ LOG.info("Balena Wifi In Network Setup")
+ if self.in_setup:
+ # Always start with a clean slate
+ self.cleanup_wifi_process()
+
self.in_setup = True
+
self.wifi_process = pexpect.spawn(
self.wifi_command.format(ssid=self.ssid)
)
@@ -180,24 +176,16 @@ def launch_wifi_setup(self):
except Exception as e:
LOG.exception(e)
break
- self.stop_setup()
+ self.handle_stop_setup()
+
if restart:
# handle bugs in balena, sometimes it fails to come back up
# seems to happen on
# Error: Getting access points failed
- self.launch_wifi_setup()
+ self.display_network_setup()
elif self.debug:
self.speak_dialog("debug_end_setup")
- # bus events
- def handle_internet_connected(self, message=None):
- """System came online later after booting."""
- self.enclosure.mouth_reset()
- # sync clock as soon as we have internet
- self.bus.emit(Message("system.ntp.sync"))
- self.stop_setup() # just in case
- self.gui.release()
-
# GUI events
def prompt_to_join_ap(self, message=None):
"""Provide instructions for setting up wifi."""
@@ -215,18 +203,11 @@ def prompt_to_select_network(self, message=None):
def report_setup_complete(self, message=None):
"""Wifi setup complete, network is connected."""
- # once first connected to internet increase time between checks
- self.connected = True
- self.time_between_checks = self.timeout_after_internet
- # stop watchdog on internet connection
- if self.stop_on_internet:
- self.monitoring = False
self.manage_setup_display("setup-completed", "status")
# allow GUI to linger around for a bit, will block the wifi setup loop
sleep(5)
- self.bus.emit(Message("ovos.wifi.setup.completed"))
- # pairing skill should take over now
- self.gui.release()
+ self.client_active = False
+ self.request_deactivate()
def report_setup_failed(self, message=None):
"""Wifi setup failed"""
@@ -234,6 +215,8 @@ def report_setup_failed(self, message=None):
self.speak_dialog("debug_wifi_error")
# allow GUI to linger around for a bit, will block the wifi setup loop
sleep(2)
+ self.in_setup = False
+ self.display_network_setup()
def manage_setup_display(self, state, page_type):
self.gui.clear()
@@ -268,7 +251,8 @@ def manage_setup_display(self, state, page_type):
self.gui.show_page(page, override_animations=True)
# cleanup
- def stop_setup(self):
+ def cleanup_wifi_process(self):
+ self.in_setup = False
if self.wifi_process is not None:
try:
if self.wifi_process.isalive():
@@ -289,13 +273,14 @@ def stop_setup(self):
LOG.debug('wifi setup exited gracefully.')
except Exception as e:
LOG.exception(e)
- self.wifi_process = None
- self.in_setup = False
-
+ else:
+ return
+
+ def handle_stop_setup(self, message=None):
+ self.request_deactivate()
+
def shutdown(self):
- self.monitoring = False
- self.bus.remove("mycroft.internet.connected", self.handle_internet_connected)
- self.stop_setup()
+ self.handle_stop_setup()
super().shutdown()
# speech