Commit ·
f0dc6f2
1
Parent(s): f35a5cc
"fix-zenoh-fallback-improved"
Browse files- reachy_mini_ha_voice/main.py +44 -27
reachy_mini_ha_voice/main.py
CHANGED
|
@@ -29,7 +29,20 @@ try:
|
|
| 29 |
REACHY_MINI_AVAILABLE = True
|
| 30 |
except ImportError:
|
| 31 |
REACHY_MINI_AVAILABLE = False
|
| 32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
ReachyMini = None
|
| 34 |
|
| 35 |
|
|
@@ -49,30 +62,47 @@ class ReachyMiniHAVoiceApp(ReachyMiniApp):
|
|
| 49 |
# No custom web UI needed - configuration is automatic via Home Assistant
|
| 50 |
custom_app_url: Optional[str] = None
|
| 51 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
def wrapped_run(self, *args, **kwargs) -> None:
|
| 53 |
"""
|
| 54 |
Override wrapped_run to handle Zenoh connection failures gracefully.
|
| 55 |
|
| 56 |
If Zenoh is not available, run in standalone mode without robot control.
|
| 57 |
"""
|
|
|
|
|
|
|
| 58 |
# Check if Zenoh is available before trying to connect
|
| 59 |
if not _check_zenoh_available():
|
| 60 |
logger.warning("Zenoh service not available (port 7447)")
|
| 61 |
logger.info("Running in standalone mode without robot control")
|
| 62 |
-
self.
|
| 63 |
return
|
| 64 |
|
| 65 |
-
# Zenoh is available, try normal startup
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 76 |
|
| 77 |
def run(self, reachy_mini, stop_event: threading.Event) -> None:
|
| 78 |
"""
|
|
@@ -123,20 +153,7 @@ class ReachyMiniHAVoiceApp(ReachyMiniApp):
|
|
| 123 |
logger.info("Voice assistant stopped.")
|
| 124 |
|
| 125 |
|
| 126 |
-
|
| 127 |
-
"""Run the voice assistant without Reachy Mini robot."""
|
| 128 |
-
logger.info("Running in standalone mode (no Reachy Mini robot)")
|
| 129 |
-
|
| 130 |
-
stop_event = threading.Event()
|
| 131 |
-
app = ReachyMiniHAVoiceApp()
|
| 132 |
-
app.stop_event = stop_event
|
| 133 |
-
|
| 134 |
-
try:
|
| 135 |
-
app.run(None, stop_event)
|
| 136 |
-
except KeyboardInterrupt:
|
| 137 |
-
stop_event.set()
|
| 138 |
-
|
| 139 |
-
|
| 140 |
if __name__ == "__main__":
|
| 141 |
logging.basicConfig(
|
| 142 |
level=logging.INFO,
|
|
|
|
| 29 |
REACHY_MINI_AVAILABLE = True
|
| 30 |
except ImportError:
|
| 31 |
REACHY_MINI_AVAILABLE = False
|
| 32 |
+
|
| 33 |
+
# Create a dummy base class
|
| 34 |
+
class ReachyMiniApp:
|
| 35 |
+
custom_app_url = None
|
| 36 |
+
|
| 37 |
+
def __init__(self):
|
| 38 |
+
self.stop_event = threading.Event()
|
| 39 |
+
|
| 40 |
+
def wrapped_run(self, *args, **kwargs):
|
| 41 |
+
pass
|
| 42 |
+
|
| 43 |
+
def stop(self):
|
| 44 |
+
self.stop_event.set()
|
| 45 |
+
|
| 46 |
ReachyMini = None
|
| 47 |
|
| 48 |
|
|
|
|
| 62 |
# No custom web UI needed - configuration is automatic via Home Assistant
|
| 63 |
custom_app_url: Optional[str] = None
|
| 64 |
|
| 65 |
+
def __init__(self, *args, **kwargs):
|
| 66 |
+
"""Initialize the app."""
|
| 67 |
+
super().__init__(*args, **kwargs)
|
| 68 |
+
if not hasattr(self, 'stop_event'):
|
| 69 |
+
self.stop_event = threading.Event()
|
| 70 |
+
|
| 71 |
def wrapped_run(self, *args, **kwargs) -> None:
|
| 72 |
"""
|
| 73 |
Override wrapped_run to handle Zenoh connection failures gracefully.
|
| 74 |
|
| 75 |
If Zenoh is not available, run in standalone mode without robot control.
|
| 76 |
"""
|
| 77 |
+
logger.info("Starting Reachy Mini HA Voice App...")
|
| 78 |
+
|
| 79 |
# Check if Zenoh is available before trying to connect
|
| 80 |
if not _check_zenoh_available():
|
| 81 |
logger.warning("Zenoh service not available (port 7447)")
|
| 82 |
logger.info("Running in standalone mode without robot control")
|
| 83 |
+
self._run_standalone()
|
| 84 |
return
|
| 85 |
|
| 86 |
+
# Zenoh is available, try normal startup with ReachyMini
|
| 87 |
+
if REACHY_MINI_AVAILABLE:
|
| 88 |
+
try:
|
| 89 |
+
logger.info("Attempting to connect to Reachy Mini...")
|
| 90 |
+
super().wrapped_run(*args, **kwargs)
|
| 91 |
+
except Exception as e:
|
| 92 |
+
error_str = str(e)
|
| 93 |
+
if "Unable to connect" in error_str or "ZError" in error_str:
|
| 94 |
+
logger.warning(f"Failed to connect to Reachy Mini: {e}")
|
| 95 |
+
logger.info("Falling back to standalone mode")
|
| 96 |
+
self._run_standalone()
|
| 97 |
+
else:
|
| 98 |
+
raise
|
| 99 |
+
else:
|
| 100 |
+
logger.info("Reachy Mini SDK not available, running standalone")
|
| 101 |
+
self._run_standalone()
|
| 102 |
+
|
| 103 |
+
def _run_standalone(self) -> None:
|
| 104 |
+
"""Run in standalone mode without robot."""
|
| 105 |
+
self.run(None, self.stop_event)
|
| 106 |
|
| 107 |
def run(self, reachy_mini, stop_event: threading.Event) -> None:
|
| 108 |
"""
|
|
|
|
| 153 |
logger.info("Voice assistant stopped.")
|
| 154 |
|
| 155 |
|
| 156 |
+
# This is called when running as: python -m reachy_mini_ha_voice.main
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
if __name__ == "__main__":
|
| 158 |
logging.basicConfig(
|
| 159 |
level=logging.INFO,
|