diff --git a/meshtastic/serial_interface.py b/meshtastic/serial_interface.py index b91e9b8..a9d5dd7 100644 --- a/meshtastic/serial_interface.py +++ b/meshtastic/serial_interface.py @@ -4,6 +4,7 @@ import logging import sys import time +from io import TextIOWrapper from typing import List, Optional @@ -44,7 +45,10 @@ class SerialInterface(StreamInterface): logger.debug(f"Connecting to {self.devPath}") - self._set_hupcl_with_termios() + if sys.platform != "win32": + with open(self.devPath, encoding="utf8") as f: + self._set_hupcl_with_termios(f) + time.sleep(0.1) self.stream = serial.Serial( self.devPath, 115200, exclusive=True, timeout=0.5, write_timeout=0 @@ -56,21 +60,17 @@ class SerialInterface(StreamInterface): self, debugOut=debugOut, noProto=noProto, connectNow=connectNow, noNodes=noNodes ) - def _set_hupcl_with_termios(self): + def _set_hupcl_with_termios(self, f: TextIOWrapper): """first we need to set the HUPCL so the device will not reboot based on RTS and/or DTR see https://github.com/pyserial/pyserial/issues/124 """ if sys.platform == "win32": return - with open(self.devPath, encoding="utf8") as f: - import termios # pylint: disable=C0415,E0401 - attrs = termios.tcgetattr(f) - attrs[2] = attrs[2] & ~termios.HUPCL - termios.tcsetattr(f, termios.TCSAFLUSH, attrs) - f.close() - - time.sleep(0.1) + import termios # pylint: disable=C0415,E0401 + attrs = termios.tcgetattr(f) + attrs[2] = attrs[2] & ~termios.HUPCL + termios.tcsetattr(f, termios.TCSAFLUSH, attrs) def __repr__(self): rep = f"SerialInterface(devPath={self.devPath!r}" diff --git a/meshtastic/slog/slog.py b/meshtastic/slog/slog.py index 766139b..28e79f6 100644 --- a/meshtastic/slog/slog.py +++ b/meshtastic/slog/slog.py @@ -32,7 +32,7 @@ def root_dir() -> str: app_author = "meshtastic" app_dir = platformdirs.user_data_dir(app_name, app_author) dir_name = Path(app_dir, "slogs") - dir_name.mkdir(exist_ok=True) + dir_name.mkdir(exist_ok=True, parents=True) return str(dir_name) diff --git a/meshtastic/tests/test_main.py b/meshtastic/tests/test_main.py index 75ec5c1..251de98 100644 --- a/meshtastic/tests/test_main.py +++ b/meshtastic/tests/test_main.py @@ -979,10 +979,11 @@ def test_main_set_valid(mocked_findports, mocked_serial, mocked_open, mocked_hup @pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") +@patch("meshtastic.serial_interface.SerialInterface._set_hupcl_with_termios") @patch("builtins.open", new_callable=mock_open, read_data="data") @patch("serial.Serial") @patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"]) -def test_main_set_valid_wifi_psk(mocked_findports, mocked_serial, mocked_open, capsys): +def test_main_set_valid_wifi_psk(mocked_findports, mocked_serial, mocked_open, mocked_hupcl, capsys): """Test --set with valid field""" sys.argv = ["", "--set", "network.wifi_psk", "123456789"] mt_config.args = sys.argv diff --git a/meshtastic/tests/test_serial_interface.py b/meshtastic/tests/test_serial_interface.py index b902234..cb5b3e2 100644 --- a/meshtastic/tests/test_serial_interface.py +++ b/meshtastic/tests/test_serial_interface.py @@ -1,8 +1,8 @@ """Meshtastic unit tests for serial_interface.py""" -import platform # pylint: disable=R0917 import re +import sys from unittest.mock import mock_open, patch import pytest @@ -10,7 +10,6 @@ import pytest from ..serial_interface import SerialInterface from ..protobuf import config_pb2 - @pytest.mark.unit @patch("time.sleep") @patch("meshtastic.serial_interface.SerialInterface._set_hupcl_with_termios") @@ -28,11 +27,11 @@ def test_SerialInterface_single_port( iface.close() mocked_findPorts.assert_called() mocked_serial.assert_called() - mock_hupcl.assert_called() - # doesn't get called in SerialInterface._set_hupcl_with_termios on windows - if platform.system() != "Windows": + # doesn't get called in SerialInterface on windows + if sys.platform != "win32": mocked_open.assert_called() + mock_hupcl.assert_called() mock_sleep.assert_called() out, err = capsys.readouterr()