Compare commits

...

7 Commits
2.6.1 ... 2.6.2

Author SHA1 Message Date
github-actions
c3973117c8 bump version to 2.6.2 2025-04-23 16:49:59 +00:00
Ian McEwen
d456e4ce30 protobufs: v2.6.6 2025-04-23 09:47:13 -07:00
Ben Meadors
ec78f62992 Merge pull request #763 from meshtastic/revert-753-fix-rtsdtr-windows
Revert "Work around RTS/DTR serial reset issues on Windows"
2025-04-15 16:37:23 -05:00
Ben Meadors
dfc9547ffc Revert "Work around RTS/DTR serial reset issues on Windows" 2025-04-15 16:03:33 -05:00
Ian McEwen
ee0f73a20e Merge pull request #761 from derekn/master
fixing tcp_interface 100% cpu usage bug (#709)
2025-04-15 13:56:28 -07:00
Derek Nicol
2e73fe310c fixing tcp_interface 100% cpu usage bug (#709) 2025-04-15 15:23:09 -05:00
Ian McEwen
d4bc39153a bump to 2.6.2a0 2025-04-05 23:01:43 -07:00
9 changed files with 144 additions and 76 deletions

View File

File diff suppressed because one or more lines are too long

View File

@@ -956,20 +956,24 @@ class Config(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
OLED_AUTO: Config.DisplayConfig._OledType.ValueType # 0 OLED_AUTO: Config.DisplayConfig._OledType.ValueType # 0
""" """
Default / Auto Default / Autodetect
""" """
OLED_SSD1306: Config.DisplayConfig._OledType.ValueType # 1 OLED_SSD1306: Config.DisplayConfig._OledType.ValueType # 1
""" """
Default / Auto Default / Autodetect
""" """
OLED_SH1106: Config.DisplayConfig._OledType.ValueType # 2 OLED_SH1106: Config.DisplayConfig._OledType.ValueType # 2
""" """
Default / Auto Default / Autodetect
""" """
OLED_SH1107: Config.DisplayConfig._OledType.ValueType # 3 OLED_SH1107: Config.DisplayConfig._OledType.ValueType # 3
""" """
Can not be auto detected but set by proto. Used for 128x128 screens Can not be auto detected but set by proto. Used for 128x128 screens
""" """
OLED_SH1107_128_64: Config.DisplayConfig._OledType.ValueType # 4
"""
Can not be auto detected but set by proto. Used for 128x64 screens
"""
class OledType(_OledType, metaclass=_OledTypeEnumTypeWrapper): class OledType(_OledType, metaclass=_OledTypeEnumTypeWrapper):
""" """
@@ -978,20 +982,24 @@ class Config(google.protobuf.message.Message):
OLED_AUTO: Config.DisplayConfig.OledType.ValueType # 0 OLED_AUTO: Config.DisplayConfig.OledType.ValueType # 0
""" """
Default / Auto Default / Autodetect
""" """
OLED_SSD1306: Config.DisplayConfig.OledType.ValueType # 1 OLED_SSD1306: Config.DisplayConfig.OledType.ValueType # 1
""" """
Default / Auto Default / Autodetect
""" """
OLED_SH1106: Config.DisplayConfig.OledType.ValueType # 2 OLED_SH1106: Config.DisplayConfig.OledType.ValueType # 2
""" """
Default / Auto Default / Autodetect
""" """
OLED_SH1107: Config.DisplayConfig.OledType.ValueType # 3 OLED_SH1107: Config.DisplayConfig.OledType.ValueType # 3
""" """
Can not be auto detected but set by proto. Used for 128x128 screens Can not be auto detected but set by proto. Used for 128x128 screens
""" """
OLED_SH1107_128_64: Config.DisplayConfig.OledType.ValueType # 4
"""
Can not be auto detected but set by proto. Used for 128x64 screens
"""
class _DisplayMode: class _DisplayMode:
ValueType = typing.NewType("ValueType", builtins.int) ValueType = typing.NewType("ValueType", builtins.int)

View File

File diff suppressed because one or more lines are too long

View File

@@ -421,6 +421,26 @@ class _HardwareModelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._
""" """
Heltec HRI-3621 industrial probe Heltec HRI-3621 industrial probe
""" """
RESERVED_FRIED_CHICKEN: _HardwareModel.ValueType # 93
"""
Reserved Fried Chicken ID for future use
"""
HELTEC_MESH_POCKET: _HardwareModel.ValueType # 94
"""
Heltec Magnetic Power Bank with Meshtastic compatible
"""
SEEED_SOLAR_NODE: _HardwareModel.ValueType # 95
"""
Seeed Solar Node
"""
NOMADSTAR_METEOR_PRO: _HardwareModel.ValueType # 96
"""
NomadStar Meteor Pro https://nomadstar.ch/
"""
CROWPANEL: _HardwareModel.ValueType # 97
"""
Elecrow CrowPanel Advance models, ESP32-S3 and TFT with SX1262 radio plugin
"""
PRIVATE_HW: _HardwareModel.ValueType # 255 PRIVATE_HW: _HardwareModel.ValueType # 255
""" """
------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------
@@ -825,6 +845,26 @@ HELTEC_SENSOR_HUB: HardwareModel.ValueType # 92
""" """
Heltec HRI-3621 industrial probe Heltec HRI-3621 industrial probe
""" """
RESERVED_FRIED_CHICKEN: HardwareModel.ValueType # 93
"""
Reserved Fried Chicken ID for future use
"""
HELTEC_MESH_POCKET: HardwareModel.ValueType # 94
"""
Heltec Magnetic Power Bank with Meshtastic compatible
"""
SEEED_SOLAR_NODE: HardwareModel.ValueType # 95
"""
Seeed Solar Node
"""
NOMADSTAR_METEOR_PRO: HardwareModel.ValueType # 96
"""
NomadStar Meteor Pro https://nomadstar.ch/
"""
CROWPANEL: HardwareModel.ValueType # 97
"""
Elecrow CrowPanel Advance models, ESP32-S3 and TFT with SX1262 radio plugin
"""
PRIVATE_HW: HardwareModel.ValueType # 255 PRIVATE_HW: HardwareModel.ValueType # 255
""" """
------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------
@@ -1068,6 +1108,14 @@ class _ExcludedModulesEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper
""" """
Paxcounter module Paxcounter module
""" """
BLUETOOTH_CONFIG: _ExcludedModules.ValueType # 8192
"""
Bluetooth config (not technically a module, but used to indicate bluetooth capabilities)
"""
NETWORK_CONFIG: _ExcludedModules.ValueType # 16384
"""
Network config (not technically a module, but used to indicate network capabilities)
"""
class ExcludedModules(_ExcludedModules, metaclass=_ExcludedModulesEnumTypeWrapper): class ExcludedModules(_ExcludedModules, metaclass=_ExcludedModulesEnumTypeWrapper):
""" """
@@ -1132,6 +1180,14 @@ PAXCOUNTER_CONFIG: ExcludedModules.ValueType # 4096
""" """
Paxcounter module Paxcounter module
""" """
BLUETOOTH_CONFIG: ExcludedModules.ValueType # 8192
"""
Bluetooth config (not technically a module, but used to indicate bluetooth capabilities)
"""
NETWORK_CONFIG: ExcludedModules.ValueType # 16384
"""
Network config (not technically a module, but used to indicate network capabilities)
"""
global___ExcludedModules = ExcludedModules global___ExcludedModules = ExcludedModules
@typing.final @typing.final

View File

@@ -723,7 +723,7 @@ class AirQualityMetrics(google.protobuf.message.Message):
""" """
co2: builtins.int co2: builtins.int
""" """
10.0um Particle Count CO2 concentration in ppm
""" """
def __init__( def __init__(
self, self,

View File

@@ -46,12 +46,7 @@ class SerialInterface(StreamInterface):
logging.debug(f"Connecting to {self.devPath}") logging.debug(f"Connecting to {self.devPath}")
# set port to None to prevent automatically opening # first we need to set the HUPCL so the device will not reboot based on RTS and/or DTR
self.stream = serial.Serial(
port=None, baudrate=115200, exclusive=True, timeout=0.5, write_timeout=0
)
# first we need to clear HUPCL (UNIX) or clear RTS/DTR (Windows) so the device will not reboot based on RTS and/or DTR
# see https://github.com/pyserial/pyserial/issues/124 # see https://github.com/pyserial/pyserial/issues/124
if platform.system() != "Windows": if platform.system() != "Windows":
with open(self.devPath, encoding="utf8") as f: with open(self.devPath, encoding="utf8") as f:
@@ -60,14 +55,10 @@ class SerialInterface(StreamInterface):
termios.tcsetattr(f, termios.TCSAFLUSH, attrs) termios.tcsetattr(f, termios.TCSAFLUSH, attrs)
f.close() f.close()
time.sleep(0.1) time.sleep(0.1)
else:
self.stream.rts = 0
self.stream.dtr = 0
# set proper port and open now that we've worked-around RTS/DTR issues
self.stream.port = self.devPath
self.stream.open()
self.stream = serial.Serial(
self.devPath, 115200, exclusive=True, timeout=0.5, write_timeout=0
)
self.stream.flush() # type: ignore[attr-defined] self.stream.flush() # type: ignore[attr-defined]
time.sleep(0.1) time.sleep(0.1)

View File

@@ -1,9 +1,11 @@
"""TCPInterface class for interfacing with http endpoint """TCPInterface class for interfacing with http endpoint
""" """
# pylint: disable=R0917 # pylint: disable=R0917
import contextlib
import logging import logging
import socket import socket
from typing import Optional, cast import time
from typing import Optional
from meshtastic.stream_interface import StreamInterface from meshtastic.stream_interface import StreamInterface
@@ -35,52 +37,63 @@ class TCPInterface(StreamInterface):
self.socket: Optional[socket.socket] = None self.socket: Optional[socket.socket] = None
if connectNow: if connectNow:
logging.debug(f"Connecting to {hostname}") # type: ignore[str-bytes-safe] self.myConnect()
server_address: tuple[str, int] = (hostname, portNumber)
sock: Optional[socket.socket] = socket.create_connection(server_address)
self.socket = sock
else: else:
self.socket = None self.socket = None
StreamInterface.__init__( super().__init__(debugOut=debugOut, noProto=noProto, connectNow=connectNow, noNodes=noNodes)
self, debugOut=debugOut, noProto=noProto, connectNow=connectNow, noNodes=noNodes
)
def _socket_shutdown(self) -> None: def _socket_shutdown(self) -> None:
"""Shutdown the socket. """Shutdown the socket.
Note: Broke out this line so the exception could be unit tested. Note: Broke out this line so the exception could be unit tested.
""" """
if self.socket: #mian: please check that this should be "if self.socket:" if self.socket is not None:
cast(socket.socket, self.socket).shutdown(socket.SHUT_RDWR) self.socket.shutdown(socket.SHUT_RDWR)
def myConnect(self) -> None: def myConnect(self) -> None:
"""Connect to socket""" """Connect to socket"""
server_address: tuple[str, int] = (self.hostname, self.portNumber) logging.debug(f"Connecting to {self.hostname}") # type: ignore[str-bytes-safe]
sock: Optional[socket.socket] = socket.create_connection(server_address) server_address = (self.hostname, self.portNumber)
self.socket = sock self.socket = socket.create_connection(server_address)
def close(self) -> None: def close(self) -> None:
"""Close a connection to the device""" """Close a connection to the device"""
logging.debug("Closing TCP stream") logging.debug("Closing TCP stream")
StreamInterface.close(self) super().close()
# Sometimes the socket read might be blocked in the reader thread. # Sometimes the socket read might be blocked in the reader thread.
# Therefore we force the shutdown by closing the socket here # Therefore we force the shutdown by closing the socket here
self._wantExit: bool = True self._wantExit = True
if not self.socket is None: if self.socket is not None:
try: with contextlib.suppress(Exception): # Ignore errors in shutdown, because we might have a race with the server
self._socket_shutdown() self._socket_shutdown()
except:
pass # Ignore errors in shutdown, because we might have a race with the server
self.socket.close() self.socket.close()
self.socket = None
def _writeBytes(self, b: bytes) -> None: def _writeBytes(self, b: bytes) -> None:
"""Write an array of bytes to our stream and flush""" """Write an array of bytes to our stream and flush"""
if self.socket: if self.socket is not None:
self.socket.send(b) self.socket.send(b)
def _readBytes(self, length) -> Optional[bytes]: def _readBytes(self, length) -> Optional[bytes]:
"""Read an array of bytes from our stream""" """Read an array of bytes from our stream"""
if self.socket: if self.socket is not None:
return self.socket.recv(length) data = self.socket.recv(length)
else: # empty byte indicates a disconnected socket,
return None # we need to handle it to avoid an infinite loop reading from null socket
if data == b'':
logging.debug("dead socket, re-connecting")
# cleanup and reconnect socket without breaking reader thread
with contextlib.suppress(Exception):
self._socket_shutdown()
self.socket.close()
self.socket = None
time.sleep(1)
self.myConnect()
self._startConfig()
return None
return data
# no socket, break reader thread
self._wantExit = True
return None

View File

@@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "meshtastic" name = "meshtastic"
version = "2.6.1" version = "2.6.2"
description = "Python API & client shell for talking to Meshtastic devices" description = "Python API & client shell for talking to Meshtastic devices"
authors = ["Meshtastic Developers <contact@meshtastic.org>"] authors = ["Meshtastic Developers <contact@meshtastic.org>"]
license = "GPL-3.0-only" license = "GPL-3.0-only"