diff --git a/.pylintrc b/.pylintrc index fb20869..c7e6475 100644 --- a/.pylintrc +++ b/.pylintrc @@ -23,7 +23,7 @@ ignore-patterns=mqtt_pb2.py,channel_pb2.py,environmental_measurement_pb2.py,admi # no Warning level messages displayed, use"--disable=all --enable=classes # --disable=W" # -disable=invalid-name,fixme,logging-fstring-interpolation,too-many-statements,too-many-branches,too-many-locals,no-member,f-string-without-interpolation,protected-access,no-self-use,pointless-string-statement,too-few-public-methods,consider-using-f-string +disable=invalid-name,fixme,logging-fstring-interpolation,too-many-statements,too-many-branches,too-many-locals,no-member,f-string-without-interpolation,protected-access,no-self-use,pointless-string-statement,too-few-public-methods,consider-using-f-string,broad-except,no-else-return,unused-argument,global-statement,global-variable-not-assigned,too-many-boolean-expressions,no-else-raise,bare-except [BASIC] diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 7a5fc19..331adab 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -17,6 +17,7 @@ from .tcp_interface import TCPInterface from .ble_interface import BLEInterface from . import test, remote_hardware from . import portnums_pb2, channel_pb2, mesh_pb2, radioconfig_pb2 +from . import tunnel from .util import support_info, our_exit """We only import the tunnel code if we are on a platform that can run it""" @@ -162,7 +163,7 @@ def setPref(attributes, name, valStr): val = fromStr(valStr) enumType = field.enum_type - if enumType and type(val) == str: + if enumType and isinstance(val) == str: # We've failed so far to convert this string into an enum, try to find it by reflection e = enumType.values_by_name.get(val) if e: @@ -212,7 +213,7 @@ def onConnected(interface): alt = 0 lat = 0.0 lon = 0.0 - time = 0 # always set time, but based on the local clock + timeval = 0 # always set time, but based on the local clock prefs = interface.localNode.radioConfig.preferences if args.setalt: alt = int(args.setalt) @@ -229,7 +230,7 @@ def onConnected(interface): print("Setting device position") # can include lat/long/alt etc: latitude = 37.5, longitude = -122.1 - interface.sendPosition(lat, lon, alt, time) + interface.sendPosition(lat, lon, alt, timeval) interface.localNode.writeConfig() elif not args.no_time: # We normally provide a current time to the mesh when we connect @@ -358,7 +359,7 @@ def onConnected(interface): getNode().writeConfig() if args.configure: - with open(args.configure[0]) as file: + with open(args.configure[0], encoding='utf8') as file: configuration = yaml.safe_load(file) closeNow = True @@ -374,7 +375,7 @@ def onConnected(interface): alt = 0 lat = 0.0 lon = 0.0 - time = 0 # always set time, but based on the local clock + timeval = 0 # always set time, but based on the local clock prefs = interface.localNode.radioConfig.preferences if 'alt' in configuration['location']: @@ -390,7 +391,7 @@ def onConnected(interface): prefs.fixed_position = True print(f"Fixing longitude at {lon} degrees") print("Setting device position") - interface.sendPosition(lat, lon, alt, time) + interface.sendPosition(lat, lon, alt, timeval) interface.localNode.writeConfig() if 'user_prefs' in configuration: @@ -531,7 +532,6 @@ def onConnected(interface): print(qr.terminal()) if have_tunnel and args.tunnel: - from . import tunnel # Even if others said we could close, stay open if the user asked for a tunnel closeNow = False tunnel.Tunnel(interface, subnet=args.tunnel_net) @@ -612,8 +612,10 @@ def common(): logfile = None else: logging.info(f"Logging serial output to {args.seriallog}") + # Note: using "line buffering" + # pylint: disable=R1732 logfile = open(args.seriallog, 'w+', - buffering=1) # line buffering + buffering=1, encoding='utf8') subscribe() if args.ble: @@ -764,7 +766,9 @@ def initParser(): "--setlon", help="Set device longitude (allows use without GPS)") parser.add_argument( - "--pos-fields", help="Specify position message fields. Use '0' for list of valid values. Can pass multiple values as a space separated list like this: '--pos-fields POS_ALTITUDE POS_ALT_MSL'", + "--pos-fields", help="Specify position message fields. Use '0' for list of valid values. "\ + "Can pass multiple values as a space separated list like "\ + "this: '--pos-fields POS_ALTITUDE POS_ALT_MSL'", nargs="*", action="store") parser.add_argument("--debug", help="Show API library debug log messages", diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index 5165547..6228028 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -53,6 +53,8 @@ class MeshInterface: self.heartbeatTimer = None random.seed() # FIXME, we should not clobber the random seedval here, instead tell user they must call it self.currentPacketId = random.randint(0, 0xffffffff) + self.nodesByNum = None + self.configId = None def close(self): """Shutdown this interface""" @@ -540,12 +542,12 @@ class MeshInterface: asDict["raw"] = meshPacket # from might be missing if the nodenum was zero. - if not "from" in asDict: + if "from" not in asDict: asDict["from"] = 0 logging.error( f"Device returned a packet we sent, ignoring: {stripnl(asDict)}") return - if not "to" in asDict: + if "to" not in asDict: asDict["to"] = 0 # /add fromId and toId fields based on the node ID diff --git a/meshtastic/node.py b/meshtastic/node.py index 05fd722..4b2bd4a 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -21,6 +21,7 @@ class Node: self.radioConfig = None self.channels = None self._timeout = Timeout(maxSecs=60) + self.partialChannels = None def showChannels(self): """Show human readable description of our channels""" @@ -165,8 +166,8 @@ class Node: for c in self.channels: if c.role == channel_pb2.Channel.Role.PRIMARY or (includeAll and c.role == channel_pb2.Channel.Role.SECONDARY): channelSet.settings.append(c.settings) - bytes = channelSet.SerializeToString() - s = base64.urlsafe_b64encode(bytes).decode('ascii') + some_bytes = channelSet.SerializeToString() + s = base64.urlsafe_b64encode(some_bytes).decode('ascii') return f"https://www.meshtastic.org/d/#{s}".replace("=", "") def setURL(self, url): diff --git a/meshtastic/stream_interface.py b/meshtastic/stream_interface.py index a7ce471..eaad34c 100644 --- a/meshtastic/stream_interface.py +++ b/meshtastic/stream_interface.py @@ -75,8 +75,11 @@ class StreamInterface(MeshInterface): MeshInterface._disconnected(self) logging.debug("Closing our port") + # pylint: disable=E0203 if not self.stream is None: + # pylint: disable=E0203 self.stream.close() + # pylint: disable=W0201 self.stream = None def _writeBytes(self, b): diff --git a/meshtastic/test.py b/meshtastic/test.py index 3607bf7..20eced2 100644 --- a/meshtastic/test.py +++ b/meshtastic/test.py @@ -137,7 +137,7 @@ def openDebugLog(portName): """Open the debug log file""" debugname = "log" + portName.replace("/", "_") logging.info(f"Writing serial debugging to {debugname}") - return open(debugname, 'w+', buffering=1) + return open(debugname, 'w+', buffering=1, encoding='utf8') def testAll(numTests=50): @@ -174,7 +174,7 @@ def testSimulator(): Run with python3 -c 'from meshtastic.test import testSimulator; testSimulator()' """ - logging.basicConfig(level=logging.DEBUG if False else logging.INFO) + logging.basicConfig(level=logging.DEBUG) logging.info("Connecting to simulator on localhost!") try: iface = TCPInterface("localhost") diff --git a/meshtastic/tunnel.py b/meshtastic/tunnel.py index 17e0805..3dd0fa3 100644 --- a/meshtastic/tunnel.py +++ b/meshtastic/tunnel.py @@ -18,6 +18,9 @@ import logging import threading from pubsub import pub + +from pytap2 import TapDevice + from . import portnums_pb2 # A new non standard log level that is lower level than DEBUG @@ -98,7 +101,6 @@ class Tunnel: logging.debug("creating TUN device with MTU=200") # FIXME - figure out real max MTU, it should be 240 - the overhead bytes for SubPacket and Data - from pytap2 import TapDevice self.tun = TapDevice(name="mesh") self.tun.up() self.tun.ifconfig(address=myAddr, netmask=netmask, mtu=200) @@ -108,6 +110,7 @@ class Tunnel: self._rxThread.start() def onReceive(self, packet): + """onReceive""" p = packet["decoded"]["payload"] if packet["from"] == self.iface.myInfo.my_node_num: logging.debug("Ignoring message we sent") @@ -206,4 +209,5 @@ class Tunnel: f"Dropping packet because no node found for destIP={ipstr(destAddr)}") def close(self): + """Close""" self.tun.close()