speculative fixes for hardware speech.
This commit is contained in:
@@ -4,5 +4,5 @@
|
|||||||
# Fenrir TTY screen reader
|
# Fenrir TTY screen reader
|
||||||
# By Chrys, Storm Dragon, and contributors.
|
# By Chrys, Storm Dragon, and contributors.
|
||||||
|
|
||||||
version = "2026.05.22"
|
version = "2026.05.23"
|
||||||
code_name = "testing"
|
code_name = "testing"
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ class hardware_serial_driver(speech_driver):
|
|||||||
)
|
)
|
||||||
self._open_serial_port()
|
self._open_serial_port()
|
||||||
self._is_initialized = self.serial_port is not None
|
self._is_initialized = self.serial_port is not None
|
||||||
|
if not self._is_initialized:
|
||||||
|
raise RuntimeError("hardware speech device is not available")
|
||||||
if self._is_initialized:
|
if self._is_initialized:
|
||||||
self._stop_worker = False
|
self._stop_worker = False
|
||||||
self.worker_thread = threading.Thread(
|
self.worker_thread = threading.Thread(
|
||||||
@@ -124,6 +126,7 @@ class hardware_serial_driver(speech_driver):
|
|||||||
self._debug(
|
self._debug(
|
||||||
"Hardware speech device not found",
|
"Hardware speech device not found",
|
||||||
debug.DebugLevel.ERROR,
|
debug.DebugLevel.ERROR,
|
||||||
|
on_any_level=True,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
@@ -140,10 +143,16 @@ class hardware_serial_driver(speech_driver):
|
|||||||
termios.tcsetattr(port, termios.TCSANOW, attrs)
|
termios.tcsetattr(port, termios.TCSANOW, attrs)
|
||||||
self.serial_port = port
|
self.serial_port = port
|
||||||
self.device = device
|
self.device = device
|
||||||
|
self._debug(
|
||||||
|
f"Hardware speech device opened: {device}",
|
||||||
|
debug.DebugLevel.INFO,
|
||||||
|
on_any_level=True,
|
||||||
|
)
|
||||||
except OSError as error:
|
except OSError as error:
|
||||||
self._debug(
|
self._debug(
|
||||||
f"Hardware speech device open failed: {device}: {error}",
|
f"Hardware speech device open failed: {device}: {error}",
|
||||||
debug.DebugLevel.ERROR,
|
debug.DebugLevel.ERROR,
|
||||||
|
on_any_level=True,
|
||||||
)
|
)
|
||||||
self.serial_port = None
|
self.serial_port = None
|
||||||
|
|
||||||
@@ -173,12 +182,13 @@ class hardware_serial_driver(speech_driver):
|
|||||||
self._debug(
|
self._debug(
|
||||||
f"Hardware speech write failed: {error}",
|
f"Hardware speech write failed: {error}",
|
||||||
debug.DebugLevel.ERROR,
|
debug.DebugLevel.ERROR,
|
||||||
|
on_any_level=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _resolve_device(self, device):
|
def _resolve_device(self, device):
|
||||||
if device and device != "auto":
|
if device and device != "auto":
|
||||||
return device
|
return device
|
||||||
for pattern in ("/dev/ttyACM*", "/dev/ttyUSB*"):
|
for pattern in ("/dev/ttyACM*", "/dev/ttyUSB*", "/dev/ttyS*"):
|
||||||
matches = sorted(glob.glob(pattern))
|
matches = sorted(glob.glob(pattern))
|
||||||
if matches:
|
if matches:
|
||||||
return matches[0]
|
return matches[0]
|
||||||
@@ -205,10 +215,10 @@ class hardware_serial_driver(speech_driver):
|
|||||||
value = max(0.0, min(1.0, value))
|
value = max(0.0, min(1.0, value))
|
||||||
return int(round(minimum + value * (maximum - minimum)))
|
return int(round(minimum + value * (maximum - minimum)))
|
||||||
|
|
||||||
def _debug(self, message, level):
|
def _debug(self, message, level, on_any_level=False):
|
||||||
try:
|
try:
|
||||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||||
message, level
|
message, level, on_any_level=on_any_level
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
import select
|
import select
|
||||||
import time
|
import time
|
||||||
|
from unittest.mock import ANY
|
||||||
from unittest.mock import Mock
|
from unittest.mock import Mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@@ -103,6 +104,48 @@ def test_litetalk_driver_writes_settings_and_cancel(serial_pair):
|
|||||||
speech_driver.shutdown()
|
speech_driver.shutdown()
|
||||||
|
|
||||||
|
|
||||||
|
def test_auto_device_detection_includes_classic_serial(
|
||||||
|
monkeypatch, serial_pair
|
||||||
|
):
|
||||||
|
master_fd, slave_name = serial_pair
|
||||||
|
|
||||||
|
def fake_glob(pattern):
|
||||||
|
if pattern == "/dev/ttyS*":
|
||||||
|
return [slave_name]
|
||||||
|
return []
|
||||||
|
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"fenrirscreenreader.speechDriver.hardwareSerialDriver.glob.glob",
|
||||||
|
fake_glob,
|
||||||
|
)
|
||||||
|
speech_driver = litetalkDriver.driver()
|
||||||
|
speech_driver.initialize(build_environment("auto"))
|
||||||
|
try:
|
||||||
|
assert speech_driver.device == slave_name
|
||||||
|
speech_driver.speak("Serial")
|
||||||
|
assert read_available(master_fd, 7) == b"Serial\r"
|
||||||
|
finally:
|
||||||
|
speech_driver.shutdown()
|
||||||
|
|
||||||
|
|
||||||
|
def test_auto_device_detection_fails_when_no_serial_device(monkeypatch):
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"fenrirscreenreader.speechDriver.hardwareSerialDriver.glob.glob",
|
||||||
|
lambda pattern: [],
|
||||||
|
)
|
||||||
|
speech_driver = litetalkDriver.driver()
|
||||||
|
|
||||||
|
with pytest.raises(RuntimeError, match="hardware speech device"):
|
||||||
|
speech_driver.initialize(build_environment("auto"))
|
||||||
|
|
||||||
|
debug_manager = speech_driver.env["runtime"]["DebugManager"]
|
||||||
|
debug_manager.write_debug_out.assert_called_with(
|
||||||
|
"Hardware speech device not found",
|
||||||
|
ANY,
|
||||||
|
on_any_level=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("driver_class", [doubletalkDriver, tripletalkDriver])
|
@pytest.mark.parametrize("driver_class", [doubletalkDriver, tripletalkDriver])
|
||||||
def test_litetalk_compatible_alias_drivers(driver_class, serial_pair):
|
def test_litetalk_compatible_alias_drivers(driver_class, serial_pair):
|
||||||
speech_driver, master_fd = initialized_driver(driver_class, serial_pair)
|
speech_driver, master_fd = initialized_driver(driver_class, serial_pair)
|
||||||
|
|||||||
Reference in New Issue
Block a user