Compare commits

...

10 Commits
2.3.1 ... 2.3.2

Author SHA1 Message Date
Ian McEwen
05e181dece protobufs: v2.3.2 2024-03-25 13:17:23 -07:00
Ben Meadors
ad02ce172d Merge pull request #524 from ianmcorvidae/make-tests-happy
Fix up or comment out broken tests, to get CI (hopefully) happy
2024-03-24 20:25:15 -05:00
Ian McEwen
daa5587443 re-fix pylint 2024-03-23 22:17:49 -07:00
Ian McEwen
a139d180b8 Fix up or comment out broken tests, to get CI (hopefully) happy 2024-03-23 22:07:17 -07:00
Ian McEwen
09f8405422 Remove --sendping as REPLY_APP portnum is disabled in firmware now 2024-03-23 21:25:38 -07:00
Ben Meadors
107629e581 Merge pull request #523 from ianmcorvidae/readme-roadmap
Add a rudimentary call for contributors & roadmap to README.md
2024-03-22 14:28:38 -05:00
Ian McEwen
39a2ecb439 improve README wording 2024-03-22 12:27:05 -07:00
Ian McEwen
1318225e27 Add a rudimentary call for contributors & roadmap to README.md 2024-03-22 12:05:40 -07:00
Ian McEwen
85a6d4c21b Remove stale device_metadata_pb2 whose .proto file no longer exists 2024-03-22 11:46:29 -07:00
github-actions
1088880f04 bump version 2024-03-21 12:47:22 +00:00
18 changed files with 707 additions and 716 deletions

View File

@@ -18,6 +18,35 @@ Events are delivered using a publish-subscribe model, and you can subscribe to o
**[Documentation/API Reference](https://python.meshtastic.org/)** **[Documentation/API Reference](https://python.meshtastic.org/)**
## Call for Contributors
This library and CLI has gone without a consistent maintainer for a while, and there's many improvements that could be made. We're all volunteers here and help is extremely appreciated, whether in implementing your own needs or helping maintain the library and CLI in general.
If you're interested in contributing but don't have specific things you'd like to work on, look at the roadmap below!
## Roadmap
This should always be considered a list in progress and flux -- inclusion doesn't guarantee implementation, and exclusion doesn't mean something's not wanted. GitHub issues are a great place to discuss ideas.
* Types
* type annotations throughout the codebase
* mypy running in CI to type-check new code
* async-friendliness
* CLI completeness & consistency
* the CLI should support all features of the firmware
* there should be a consistent output format available for shell scripting
* CLI input validation & documentation
* what arguments and options are compatible & incompatible with one another?
* can the options be restructured in a way that is more self-documenting?
* pubsub events should be documented clearly
* helpers for third-party code
* it should be easy to write a script that supports similar options to the CLI so many tools support the same ways of connecting to nodes
* interactive client
* data storage & processing
* there should be a standardized way of recording packets for later use, debugging, etc.
* a sqlite database schema and tools for writing to it may be a good starting point
* enable maps, charts, visualizations
## Stats ## Stats
![Alt](https://repobeats.axiom.co/api/embed/c71ee8fc4a79690402e5d2807a41eec5e96d9039.svg "Repobeats analytics image") ![Alt](https://repobeats.axiom.co/api/embed/c71ee8fc4a79690402e5d2807a41eec5e96d9039.svg "Repobeats analytics image")

View File

@@ -71,11 +71,11 @@ from datetime import datetime
from typing import * from typing import *
import google.protobuf.json_format import google.protobuf.json_format
import serial import serial # type: ignore[import-untyped]
import timeago import timeago # type: ignore[import-untyped]
from dotmap import DotMap from dotmap import DotMap # type: ignore[import-untyped]
from google.protobuf.json_format import MessageToJson from google.protobuf.json_format import MessageToJson
from pubsub import pub from pubsub import pub # type: ignore[import-untyped]
from tabulate import tabulate from tabulate import tabulate
from meshtastic import ( from meshtastic import (
@@ -127,9 +127,9 @@ class KnownProtocol(NamedTuple):
name: str name: str
# portnum: int, now a key # portnum: int, now a key
# If set, will be called to prase as a protocol buffer # If set, will be called to prase as a protocol buffer
protobufFactory: Callable = None protobufFactory: Optional[Callable] = None
# If set, invoked as onReceive(interface, packet) # If set, invoked as onReceive(interface, packet)
onReceive: Callable = None onReceive: Optional[Callable] = None
def _onTextReceive(iface, asDict): def _onTextReceive(iface, asDict):

View File

@@ -160,8 +160,8 @@ def setPref(config, comp_name, valStr) -> bool:
val = meshtastic.util.fromStr(valStr) val = meshtastic.util.fromStr(valStr)
logging.debug(f"valStr:{valStr} val:{val}") logging.debug(f"valStr:{valStr} val:{val}")
if snake_name == "psk" and len(valStr) < 8: if snake_name == "wifi_psk" and len(valStr) < 8:
print(f"Warning: wifi.psk must be 8 or more characters.") print(f"Warning: network.wifi_psk must be 8 or more characters.")
return False return False
enumType = pref.enum_type enumType = pref.enum_type
@@ -394,17 +394,6 @@ def onConnected(interface):
f"Warning: {channelIndex} is not a valid channel. Channel must not be DISABLED." f"Warning: {channelIndex} is not a valid channel. Channel must not be DISABLED."
) )
if args.sendping:
payload = str.encode("test string")
print(f"Sending ping message to {args.dest}")
interface.sendData(
payload,
args.dest,
portNum=portnums_pb2.PortNum.REPLY_APP,
wantAck=True,
wantResponse=True,
)
if args.traceroute: if args.traceroute:
loraConfig = getattr(interface.localNode.localConfig, "lora") loraConfig = getattr(interface.localNode.localConfig, "lora")
hopLimit = getattr(loraConfig, "hop_limit") hopLimit = getattr(loraConfig, "hop_limit")
@@ -649,6 +638,11 @@ def onConnected(interface):
def setSimpleConfig(modem_preset): def setSimpleConfig(modem_preset):
"""Set one of the simple modem_config""" """Set one of the simple modem_config"""
channelIndex = our_globals.get_channel_index()
if channelIndex is not None and channelIndex > 0:
meshtastic.util.our_exit(
"Warning: Cannot set modem preset for non-primary channel", 1
)
# Overwrite modem_preset # Overwrite modem_preset
prefs = interface.getNode(args.dest).localConfig prefs = interface.getNode(args.dest).localConfig
prefs.lora.modem_preset = modem_preset prefs.lora.modem_preset = modem_preset
@@ -1241,12 +1235,6 @@ def initParser():
help="Send a text message. Can specify a destination '--dest' and/or channel index '--ch-index'.", help="Send a text message. Can specify a destination '--dest' and/or channel index '--ch-index'.",
) )
parser.add_argument(
"--sendping",
help="Send a ping message (which requests a reply)",
action="store_true",
)
parser.add_argument( parser.add_argument(
"--traceroute", "--traceroute",
help="Traceroute from connected node to a destination. " help="Traceroute from connected node to a destination. "

View File

@@ -19,7 +19,7 @@ from meshtastic import mesh_pb2 as meshtastic_dot_mesh__pb2
from meshtastic import module_config_pb2 as meshtastic_dot_module__config__pb2 from meshtastic import module_config_pb2 as meshtastic_dot_module__config__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16meshtastic/admin.proto\x1a\x18meshtastic/channel.proto\x1a\x17meshtastic/config.proto\x1a\"meshtastic/connection_status.proto\x1a\x1bmeshtastic/deviceonly.proto\x1a\x15meshtastic/mesh.proto\x1a\x1emeshtastic/module_config.proto\"\xa2\x0f\n\x0c\x41\x64minMessage\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12(\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x08.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12#\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x05.UserH\x00\x12\x36\n\x12get_config_request\x18\x05 \x01(\x0e\x32\x18.AdminMessage.ConfigTypeH\x00\x12&\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x07.ConfigH\x00\x12\x43\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x1e.AdminMessage.ModuleConfigTypeH\x00\x12\x33\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32\r.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12\x37\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32\x0f.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12H\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32\x17.DeviceConnectionStatusH\x00\x12&\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\x0e.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12Q\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32\x1f.NodeRemoteHardwarePinsResponseH\x00\x12 \n\x16\x65nter_dfu_mode_request\x18\x15 \x01(\x08H\x00\x12\x1d\n\x13\x64\x65lete_file_request\x18\x16 \x01(\tH\x00\x12\x1a\n\tset_owner\x18 \x01(\x0b\x32\x05.UserH\x00\x12\x1f\n\x0bset_channel\x18! \x01(\x0b\x32\x08.ChannelH\x00\x12\x1d\n\nset_config\x18\" \x01(\x0b\x32\x07.ConfigH\x00\x12*\n\x11set_module_config\x18# \x01(\x0b\x32\r.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\x1b\n\x11remove_by_nodenum\x18& \x01(\rH\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x1c\n\x12reboot_ota_seconds\x18_ \x01(\x05H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x17\n\rfactory_reset\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x05H\x00\"\x95\x01\n\nConfigType\x12\x11\n\rDEVICE_CONFIG\x10\x00\x12\x13\n\x0fPOSITION_CONFIG\x10\x01\x12\x10\n\x0cPOWER_CONFIG\x10\x02\x12\x12\n\x0eNETWORK_CONFIG\x10\x03\x12\x12\n\x0e\x44ISPLAY_CONFIG\x10\x04\x12\x0f\n\x0bLORA_CONFIG\x10\x05\x12\x14\n\x10\x42LUETOOTH_CONFIG\x10\x06\"\xbb\x02\n\x10ModuleConfigType\x12\x0f\n\x0bMQTT_CONFIG\x10\x00\x12\x11\n\rSERIAL_CONFIG\x10\x01\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x02\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x03\x12\x14\n\x10RANGETEST_CONFIG\x10\x04\x12\x14\n\x10TELEMETRY_CONFIG\x10\x05\x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10\x06\x12\x10\n\x0c\x41UDIO_CONFIG\x10\x07\x12\x19\n\x15REMOTEHARDWARE_CONFIG\x10\x08\x12\x17\n\x13NEIGHBORINFO_CONFIG\x10\t\x12\x1a\n\x16\x41MBIENTLIGHTING_CONFIG\x10\n\x12\x1a\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x0b\x12\x15\n\x11PAXCOUNTER_CONFIG\x10\x0c\x42\x11\n\x0fpayload_variant\"[\n\rHamParameters\x12\x11\n\tcall_sign\x18\x01 \x01(\t\x12\x10\n\x08tx_power\x18\x02 \x01(\x05\x12\x11\n\tfrequency\x18\x03 \x01(\x02\x12\x12\n\nshort_name\x18\x04 \x01(\t\"[\n\x1eNodeRemoteHardwarePinsResponse\x12\x39\n\x19node_remote_hardware_pins\x18\x01 \x03(\x0b\x32\x16.NodeRemoteHardwarePinB`\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16meshtastic/admin.proto\x1a\x18meshtastic/channel.proto\x1a\x17meshtastic/config.proto\x1a\"meshtastic/connection_status.proto\x1a\x1bmeshtastic/deviceonly.proto\x1a\x15meshtastic/mesh.proto\x1a\x1emeshtastic/module_config.proto\"\xdf\x0f\n\x0c\x41\x64minMessage\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12(\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x08.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12#\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x05.UserH\x00\x12\x36\n\x12get_config_request\x18\x05 \x01(\x0e\x32\x18.AdminMessage.ConfigTypeH\x00\x12&\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x07.ConfigH\x00\x12\x43\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x1e.AdminMessage.ModuleConfigTypeH\x00\x12\x33\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32\r.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12\x37\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32\x0f.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12H\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32\x17.DeviceConnectionStatusH\x00\x12&\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\x0e.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12Q\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32\x1f.NodeRemoteHardwarePinsResponseH\x00\x12 \n\x16\x65nter_dfu_mode_request\x18\x15 \x01(\x08H\x00\x12\x1d\n\x13\x64\x65lete_file_request\x18\x16 \x01(\tH\x00\x12\x1a\n\tset_owner\x18 \x01(\x0b\x32\x05.UserH\x00\x12\x1f\n\x0bset_channel\x18! \x01(\x0b\x32\x08.ChannelH\x00\x12\x1d\n\nset_config\x18\" \x01(\x0b\x32\x07.ConfigH\x00\x12*\n\x11set_module_config\x18# \x01(\x0b\x32\r.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\x1b\n\x11remove_by_nodenum\x18& \x01(\rH\x00\x12\x1b\n\x11set_favorite_node\x18\' \x01(\rH\x00\x12\x1e\n\x14remove_favorite_node\x18( \x01(\rH\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x1c\n\x12reboot_ota_seconds\x18_ \x01(\x05H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x17\n\rfactory_reset\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x05H\x00\"\x95\x01\n\nConfigType\x12\x11\n\rDEVICE_CONFIG\x10\x00\x12\x13\n\x0fPOSITION_CONFIG\x10\x01\x12\x10\n\x0cPOWER_CONFIG\x10\x02\x12\x12\n\x0eNETWORK_CONFIG\x10\x03\x12\x12\n\x0e\x44ISPLAY_CONFIG\x10\x04\x12\x0f\n\x0bLORA_CONFIG\x10\x05\x12\x14\n\x10\x42LUETOOTH_CONFIG\x10\x06\"\xbb\x02\n\x10ModuleConfigType\x12\x0f\n\x0bMQTT_CONFIG\x10\x00\x12\x11\n\rSERIAL_CONFIG\x10\x01\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x02\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x03\x12\x14\n\x10RANGETEST_CONFIG\x10\x04\x12\x14\n\x10TELEMETRY_CONFIG\x10\x05\x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10\x06\x12\x10\n\x0c\x41UDIO_CONFIG\x10\x07\x12\x19\n\x15REMOTEHARDWARE_CONFIG\x10\x08\x12\x17\n\x13NEIGHBORINFO_CONFIG\x10\t\x12\x1a\n\x16\x41MBIENTLIGHTING_CONFIG\x10\n\x12\x1a\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x0b\x12\x15\n\x11PAXCOUNTER_CONFIG\x10\x0c\x42\x11\n\x0fpayload_variant\"[\n\rHamParameters\x12\x11\n\tcall_sign\x18\x01 \x01(\t\x12\x10\n\x08tx_power\x18\x02 \x01(\x05\x12\x11\n\tfrequency\x18\x03 \x01(\x02\x12\x12\n\nshort_name\x18\x04 \x01(\t\"[\n\x1eNodeRemoteHardwarePinsResponse\x12\x39\n\x19node_remote_hardware_pins\x18\x01 \x03(\x0b\x32\x16.NodeRemoteHardwarePinB`\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.admin_pb2', globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.admin_pb2', globals())
@@ -28,13 +28,13 @@ if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\013AdminProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\013AdminProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_ADMINMESSAGE._serialized_start=198 _ADMINMESSAGE._serialized_start=198
_ADMINMESSAGE._serialized_end=2152 _ADMINMESSAGE._serialized_end=2213
_ADMINMESSAGE_CONFIGTYPE._serialized_start=1666 _ADMINMESSAGE_CONFIGTYPE._serialized_start=1727
_ADMINMESSAGE_CONFIGTYPE._serialized_end=1815 _ADMINMESSAGE_CONFIGTYPE._serialized_end=1876
_ADMINMESSAGE_MODULECONFIGTYPE._serialized_start=1818 _ADMINMESSAGE_MODULECONFIGTYPE._serialized_start=1879
_ADMINMESSAGE_MODULECONFIGTYPE._serialized_end=2133 _ADMINMESSAGE_MODULECONFIGTYPE._serialized_end=2194
_HAMPARAMETERS._serialized_start=2154 _HAMPARAMETERS._serialized_start=2215
_HAMPARAMETERS._serialized_end=2245 _HAMPARAMETERS._serialized_end=2306
_NODEREMOTEHARDWAREPINSRESPONSE._serialized_start=2247 _NODEREMOTEHARDWAREPINSRESPONSE._serialized_start=2308
_NODEREMOTEHARDWAREPINSRESPONSE._serialized_end=2338 _NODEREMOTEHARDWAREPINSRESPONSE._serialized_end=2399
# @@protoc_insertion_point(module_scope) # @@protoc_insertion_point(module_scope)

View File

@@ -1,37 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: meshtastic/device_metadata.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
from meshtastic import config_pb2 as meshtastic_dot_config__pb2
from meshtastic import mesh_pb2 as meshtastic_dot_mesh__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/device_metadata.proto\x1a\x17meshtastic/config.proto\x1a\x15meshtastic/mesh.proto\"\xfc\x01\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12\'\n\x04role\x18\x07 \x01(\x0e\x32\x19.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12 \n\x08hw_model\x18\t \x01(\x0e\x32\x0e.HardwareModelBi\n\x13\x63om.geeksville.meshB\x14\x44\x65viceMetadataProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_DEVICEMETADATA = DESCRIPTOR.message_types_by_name['DeviceMetadata']
DeviceMetadata = _reflection.GeneratedProtocolMessageType('DeviceMetadata', (_message.Message,), {
'DESCRIPTOR' : _DEVICEMETADATA,
'__module__' : 'meshtastic.device_metadata_pb2'
# @@protoc_insertion_point(class_scope:DeviceMetadata)
})
_sym_db.RegisterMessage(DeviceMetadata)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\024DeviceMetadataProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_DEVICEMETADATA._serialized_start=85
_DEVICEMETADATA._serialized_end=337
# @@protoc_insertion_point(module_scope)

View File

@@ -16,30 +16,33 @@ from meshtastic import localonly_pb2 as meshtastic_dot_localonly__pb2
from meshtastic import mesh_pb2 as meshtastic_dot_mesh__pb2 from meshtastic import mesh_pb2 as meshtastic_dot_mesh__pb2
from meshtastic import telemetry_pb2 as meshtastic_dot_telemetry__pb2 from meshtastic import telemetry_pb2 as meshtastic_dot_telemetry__pb2
from meshtastic import module_config_pb2 as meshtastic_dot_module__config__pb2 from meshtastic import module_config_pb2 as meshtastic_dot_module__config__pb2
from . import nanopb_pb2 as nanopb__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bmeshtastic/deviceonly.proto\x1a\x18meshtastic/channel.proto\x1a\x1ameshtastic/localonly.proto\x1a\x15meshtastic/mesh.proto\x1a\x1ameshtastic/telemetry.proto\x1a\x1emeshtastic/module_config.proto\"\xca\x02\n\x0b\x44\x65viceState\x12\x1c\n\x07my_node\x18\x02 \x01(\x0b\x32\x0b.MyNodeInfo\x12\x14\n\x05owner\x18\x03 \x01(\x0b\x32\x05.User\x12\"\n\rreceive_queue\x18\x05 \x03(\x0b\x32\x0b.MeshPacket\x12\x0f\n\x07version\x18\x08 \x01(\r\x12$\n\x0frx_text_message\x18\x07 \x01(\x0b\x32\x0b.MeshPacket\x12\x13\n\x07no_save\x18\t \x01(\x08\x42\x02\x18\x01\x12\x15\n\rdid_gps_reset\x18\x0b \x01(\x08\x12 \n\x0brx_waypoint\x18\x0c \x01(\x0b\x32\x0b.MeshPacket\x12\x39\n\x19node_remote_hardware_pins\x18\r \x03(\x0b\x32\x16.NodeRemoteHardwarePin\x12#\n\x0cnode_db_lite\x18\x0e \x03(\x0b\x32\r.NodeInfoLite\"\xd0\x01\n\x0cNodeInfoLite\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x13\n\x04user\x18\x02 \x01(\x0b\x32\x05.User\x12\x1f\n\x08position\x18\x03 \x01(\x0b\x32\r.PositionLite\x12\x0b\n\x03snr\x18\x04 \x01(\x02\x12\x12\n\nlast_heard\x18\x05 \x01(\x07\x12&\n\x0e\x64\x65vice_metrics\x18\x06 \x01(\x0b\x32\x0e.DeviceMetrics\x12\x0f\n\x07\x63hannel\x18\x07 \x01(\r\x12\x10\n\x08via_mqtt\x18\x08 \x01(\x08\x12\x11\n\thops_away\x18\t \x01(\r\"\x85\x01\n\x0cPositionLite\x12\x12\n\nlatitude_i\x18\x01 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x02 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12,\n\x0flocation_source\x18\x05 \x01(\x0e\x32\x13.Position.LocSource\":\n\x0b\x43hannelFile\x12\x1a\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x08.Channel\x12\x0f\n\x07version\x18\x02 \x01(\r\"\xf6\x01\n\x08OEMStore\x12\x16\n\x0eoem_icon_width\x18\x01 \x01(\r\x12\x17\n\x0foem_icon_height\x18\x02 \x01(\r\x12\x15\n\roem_icon_bits\x18\x03 \x01(\x0c\x12\x1e\n\x08oem_font\x18\x04 \x01(\x0e\x32\x0c.ScreenFonts\x12\x10\n\x08oem_text\x18\x05 \x01(\t\x12\x13\n\x0boem_aes_key\x18\x06 \x01(\x0c\x12&\n\x10oem_local_config\x18\x07 \x01(\x0b\x32\x0c.LocalConfig\x12\x33\n\x17oem_local_module_config\x18\x08 \x01(\x0b\x32\x12.LocalModuleConfig\"J\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x1f\n\x03pin\x18\x02 \x01(\x0b\x32\x12.RemoteHardwarePin*>\n\x0bScreenFonts\x12\x0e\n\nFONT_SMALL\x10\x00\x12\x0f\n\x0b\x46ONT_MEDIUM\x10\x01\x12\x0e\n\nFONT_LARGE\x10\x02\x42_\n\x13\x63om.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bmeshtastic/deviceonly.proto\x1a\x18meshtastic/channel.proto\x1a\x1ameshtastic/localonly.proto\x1a\x15meshtastic/mesh.proto\x1a\x1ameshtastic/telemetry.proto\x1a\x1emeshtastic/module_config.proto\x1a\x0cnanopb.proto\"\xf6\x02\n\x0b\x44\x65viceState\x12\x1c\n\x07my_node\x18\x02 \x01(\x0b\x32\x0b.MyNodeInfo\x12\x14\n\x05owner\x18\x03 \x01(\x0b\x32\x05.User\x12\"\n\rreceive_queue\x18\x05 \x03(\x0b\x32\x0b.MeshPacket\x12\x0f\n\x07version\x18\x08 \x01(\r\x12$\n\x0frx_text_message\x18\x07 \x01(\x0b\x32\x0b.MeshPacket\x12\x13\n\x07no_save\x18\t \x01(\x08\x42\x02\x18\x01\x12\x15\n\rdid_gps_reset\x18\x0b \x01(\x08\x12 \n\x0brx_waypoint\x18\x0c \x01(\x0b\x32\x0b.MeshPacket\x12\x39\n\x19node_remote_hardware_pins\x18\r \x03(\x0b\x32\x16.NodeRemoteHardwarePin\x12O\n\x0cnode_db_lite\x18\x0e \x03(\x0b\x32\r.NodeInfoLiteB*\x92?\'\x92\x01$std::vector<meshtastic_NodeInfoLite>\"\xe5\x01\n\x0cNodeInfoLite\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x13\n\x04user\x18\x02 \x01(\x0b\x32\x05.User\x12\x1f\n\x08position\x18\x03 \x01(\x0b\x32\r.PositionLite\x12\x0b\n\x03snr\x18\x04 \x01(\x02\x12\x12\n\nlast_heard\x18\x05 \x01(\x07\x12&\n\x0e\x64\x65vice_metrics\x18\x06 \x01(\x0b\x32\x0e.DeviceMetrics\x12\x0f\n\x07\x63hannel\x18\x07 \x01(\r\x12\x10\n\x08via_mqtt\x18\x08 \x01(\x08\x12\x11\n\thops_away\x18\t \x01(\r\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\"\x85\x01\n\x0cPositionLite\x12\x12\n\nlatitude_i\x18\x01 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x02 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12,\n\x0flocation_source\x18\x05 \x01(\x0e\x32\x13.Position.LocSource\":\n\x0b\x43hannelFile\x12\x1a\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x08.Channel\x12\x0f\n\x07version\x18\x02 \x01(\r\"\xf6\x01\n\x08OEMStore\x12\x16\n\x0eoem_icon_width\x18\x01 \x01(\r\x12\x17\n\x0foem_icon_height\x18\x02 \x01(\r\x12\x15\n\roem_icon_bits\x18\x03 \x01(\x0c\x12\x1e\n\x08oem_font\x18\x04 \x01(\x0e\x32\x0c.ScreenFonts\x12\x10\n\x08oem_text\x18\x05 \x01(\t\x12\x13\n\x0boem_aes_key\x18\x06 \x01(\x0c\x12&\n\x10oem_local_config\x18\x07 \x01(\x0b\x32\x0c.LocalConfig\x12\x33\n\x17oem_local_module_config\x18\x08 \x01(\x0b\x32\x12.LocalModuleConfig\"J\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x1f\n\x03pin\x18\x02 \x01(\x0b\x32\x12.RemoteHardwarePin*>\n\x0bScreenFonts\x12\x0e\n\nFONT_SMALL\x10\x00\x12\x0f\n\x0b\x46ONT_MEDIUM\x10\x01\x12\x0e\n\nFONT_LARGE\x10\x02\x42m\n\x13\x63om.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x92?\x0b\xc2\x01\x08<vector>b\x06proto3')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.deviceonly_pb2', globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.deviceonly_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False: if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000\222?\013\302\001\010<vector>'
_DEVICESTATE.fields_by_name['no_save']._options = None _DEVICESTATE.fields_by_name['no_save']._options = None
_DEVICESTATE.fields_by_name['no_save']._serialized_options = b'\030\001' _DEVICESTATE.fields_by_name['no_save']._serialized_options = b'\030\001'
_SCREENFONTS._serialized_start=1233 _DEVICESTATE.fields_by_name['node_db_lite']._options = None
_SCREENFONTS._serialized_end=1295 _DEVICESTATE.fields_by_name['node_db_lite']._serialized_options = b'\222?\'\222\001$std::vector<meshtastic_NodeInfoLite>'
_DEVICESTATE._serialized_start=169 _SCREENFONTS._serialized_start=1312
_DEVICESTATE._serialized_end=499 _SCREENFONTS._serialized_end=1374
_NODEINFOLITE._serialized_start=502 _DEVICESTATE._serialized_start=183
_NODEINFOLITE._serialized_end=710 _DEVICESTATE._serialized_end=557
_POSITIONLITE._serialized_start=713 _NODEINFOLITE._serialized_start=560
_POSITIONLITE._serialized_end=846 _NODEINFOLITE._serialized_end=789
_CHANNELFILE._serialized_start=848 _POSITIONLITE._serialized_start=792
_CHANNELFILE._serialized_end=906 _POSITIONLITE._serialized_end=925
_OEMSTORE._serialized_start=909 _CHANNELFILE._serialized_start=927
_OEMSTORE._serialized_end=1155 _CHANNELFILE._serialized_end=985
_NODEREMOTEHARDWAREPIN._serialized_start=1157 _OEMSTORE._serialized_start=988
_NODEREMOTEHARDWAREPIN._serialized_end=1231 _OEMSTORE._serialized_end=1234
_NODEREMOTEHARDWAREPIN._serialized_start=1236
_NODEREMOTEHARDWAREPIN._serialized_end=1310
# @@protoc_insertion_point(module_scope) # @@protoc_insertion_point(module_scope)

View File

@@ -129,7 +129,6 @@ class MeshInterface:
# use id as dictionary key for correct json format in list of nodes # use id as dictionary key for correct json format in list of nodes
nodeid = n2["user"]["id"] nodeid = n2["user"]["id"]
n2["user"].pop("id")
nodes[nodeid] = n2 nodes[nodeid] = n2
infos = owner + myinfo + metadata + mesh + json.dumps(nodes) infos = owner + myinfo + metadata + mesh + json.dumps(nodes)
print(infos) print(infos)

View File

File diff suppressed because one or more lines are too long

View File

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,6 @@ from ..util import Timeout
def test_MeshInterface(capsys): def test_MeshInterface(capsys):
"""Test that we can instantiate a MeshInterface""" """Test that we can instantiate a MeshInterface"""
iface = MeshInterface(noProto=True) iface = MeshInterface(noProto=True)
anode = Node("foo", "bar")
nodes = { nodes = {
"!9388f81c": { "!9388f81c": {
@@ -38,7 +37,7 @@ def test_MeshInterface(capsys):
} }
} }
iface.nodesByNum = {1: anode} iface.nodesByNum = {2475227164: nodes["!9388f81c"]}
iface.nodes = nodes iface.nodes = nodes
myInfo = MagicMock() myInfo = MagicMock()
@@ -148,7 +147,7 @@ def test_getNode_not_local(caplog):
with patch("meshtastic.node.Node", return_value=anode): with patch("meshtastic.node.Node", return_value=anode):
another_node = iface.getNode("bar2") another_node = iface.getNode("bar2")
assert another_node != iface.localNode assert another_node != iface.localNode
assert re.search(r"About to requestConfig", caplog.text, re.MULTILINE) assert re.search(r"About to requestChannels", caplog.text, re.MULTILINE)
@pytest.mark.unit @pytest.mark.unit
@@ -164,7 +163,7 @@ def test_getNode_not_local_timeout(capsys):
assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1 assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert re.match(r"Error: Timed out waiting for node config", out) assert re.match(r"Error: Timed out waiting for channels", out)
assert err == "" assert err == ""
@@ -230,8 +229,8 @@ def test_handleFromRadio_with_my_info(caplog):
with caplog.at_level(logging.DEBUG): with caplog.at_level(logging.DEBUG):
iface._handleFromRadio(from_radio_bytes) iface._handleFromRadio(from_radio_bytes)
iface.close() iface.close()
assert re.search(r"Received myinfo", caplog.text, re.MULTILINE) assert re.search(r"Received from radio: my_info {", caplog.text, re.MULTILINE)
assert re.search(r"max_channels: 8", caplog.text, re.MULTILINE) assert re.search(r"my_node_num: 682584012", caplog.text, re.MULTILINE)
@pytest.mark.unit @pytest.mark.unit
@@ -258,15 +257,14 @@ def test_handleFromRadio_with_node_info(caplog, capsys):
with caplog.at_level(logging.DEBUG): with caplog.at_level(logging.DEBUG):
iface._startConfig() iface._startConfig()
iface._handleFromRadio(from_radio_bytes) iface._handleFromRadio(from_radio_bytes)
assert re.search(r"Received nodeinfo", caplog.text, re.MULTILINE) assert re.search(r"Received from radio: node_info {", caplog.text, re.MULTILINE)
assert re.search(r"682584012", caplog.text, re.MULTILINE) assert re.search(r"682584012", caplog.text, re.MULTILINE)
assert re.search(r"HELTEC_V2_1", caplog.text, re.MULTILINE)
# validate some of showNodes() output # validate some of showNodes() output
iface.showNodes() iface.showNodes()
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert re.search(r" 1 ", out, re.MULTILINE) assert re.search(r" 1 ", out, re.MULTILINE)
assert re.search(r"│ Unknown 67cc │ ", out, re.MULTILINE) assert re.search(r"│ Unknown 67cc │ ", out, re.MULTILINE)
assert re.search(r" !28af67cc │ N/A │ N/A │ N/A", out, re.MULTILINE) assert re.search(r"\s+!28af67cc\s+│\s+67cc\s+|", out, re.MULTILINE)
assert err == "" assert err == ""
iface.close() iface.close()
@@ -347,10 +345,10 @@ def test_sendData_too_long(caplog):
some_large_text += b"This is a long text that will be too long for send text." some_large_text += b"This is a long text that will be too long for send text."
some_large_text += b"This is a long text that will be too long for send text." some_large_text += b"This is a long text that will be too long for send text."
with caplog.at_level(logging.DEBUG): with caplog.at_level(logging.DEBUG):
with pytest.raises(Exception) as pytest_wrapped_e: with pytest.raises(MeshInterface.MeshInterfaceError) as pytest_wrapped_e:
iface.sendData(some_large_text) iface.sendData(some_large_text)
assert re.search("Data payload too big", caplog.text, re.MULTILINE) assert re.search("Data payload too big", caplog.text, re.MULTILINE)
assert pytest_wrapped_e.type == Exception assert pytest_wrapped_e.type == MeshInterface.MeshInterfaceError
iface.close() iface.close()
@@ -506,14 +504,14 @@ def test_generatePacketId(capsys):
# not sure when this condition would ever happen... but we can simulate it # not sure when this condition would ever happen... but we can simulate it
iface.currentPacketId = None iface.currentPacketId = None
assert iface.currentPacketId is None assert iface.currentPacketId is None
with pytest.raises(Exception) as pytest_wrapped_e: with pytest.raises(MeshInterface.MeshInterfaceError) as pytest_wrapped_e:
iface._generatePacketId() iface._generatePacketId()
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert re.search( assert re.search(
r"Not connected yet, can not generate packet", out, re.MULTILINE r"Not connected yet, can not generate packet", out, re.MULTILINE
) )
assert err == "" assert err == ""
assert pytest_wrapped_e.type == Exception assert pytest_wrapped_e.type == MeshInterface.MeshInterfaceError
@pytest.mark.unit @pytest.mark.unit
@@ -597,9 +595,9 @@ def test_getOrCreateByNum_not_found(iface_with_nodes):
"""Test _getOrCreateByNum()""" """Test _getOrCreateByNum()"""
iface = iface_with_nodes iface = iface_with_nodes
iface.myInfo.my_node_num = 2475227164 iface.myInfo.my_node_num = 2475227164
with pytest.raises(Exception) as pytest_wrapped_e: with pytest.raises(MeshInterface.MeshInterfaceError) as pytest_wrapped_e:
iface._getOrCreateByNum(0xFFFFFFFF) iface._getOrCreateByNum(0xFFFFFFFF)
assert pytest_wrapped_e.type == Exception assert pytest_wrapped_e.type == MeshInterface.MeshInterfaceError
@pytest.mark.unit @pytest.mark.unit
@@ -651,9 +649,9 @@ def test_waitForConfig(capsys):
iface = MeshInterface(noProto=True) iface = MeshInterface(noProto=True)
# override how long to wait # override how long to wait
iface._timeout = Timeout(0.01) iface._timeout = Timeout(0.01)
with pytest.raises(Exception) as pytest_wrapped_e: with pytest.raises(MeshInterface.MeshInterfaceError) as pytest_wrapped_e:
iface.waitForConfig() iface.waitForConfig()
assert pytest_wrapped_e.type == Exception assert pytest_wrapped_e.type == MeshInterface.MeshInterfaceError
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert re.search( assert re.search(
r"Exception: Timed out waiting for interface config", err, re.MULTILINE r"Exception: Timed out waiting for interface config", err, re.MULTILINE
@@ -665,10 +663,10 @@ def test_waitForConfig(capsys):
def test_waitConnected_raises_an_exception(capsys): def test_waitConnected_raises_an_exception(capsys):
"""Test waitConnected()""" """Test waitConnected()"""
iface = MeshInterface(noProto=True) iface = MeshInterface(noProto=True)
with pytest.raises(Exception) as pytest_wrapped_e: with pytest.raises(MeshInterface.MeshInterfaceError) as pytest_wrapped_e:
iface.failure = "warn about something" iface.failure = MeshInterface.MeshInterfaceError("warn about something")
iface._waitConnected(0.01) iface._waitConnected(0.01)
assert pytest_wrapped_e.type == Exception assert pytest_wrapped_e.type == MeshInterface.MeshInterfaceError
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert re.search(r"warn about something", err, re.MULTILINE) assert re.search(r"warn about something", err, re.MULTILINE)
assert out == "" assert out == ""
@@ -677,10 +675,10 @@ def test_waitConnected_raises_an_exception(capsys):
@pytest.mark.unit @pytest.mark.unit
def test_waitConnected_isConnected_timeout(capsys): def test_waitConnected_isConnected_timeout(capsys):
"""Test waitConnected()""" """Test waitConnected()"""
with pytest.raises(Exception) as pytest_wrapped_e: with pytest.raises(MeshInterface.MeshInterfaceError) as pytest_wrapped_e:
iface = MeshInterface() iface = MeshInterface()
iface._waitConnected(0.01) iface._waitConnected(0.01)
assert pytest_wrapped_e.type == Exception assert pytest_wrapped_e.type == MeshInterface.MeshInterfaceError
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert re.search(r"warn about something", err, re.MULTILINE) assert re.search(r"warn about something", err, re.MULTILINE)
assert out == "" assert out == ""

View File

@@ -10,6 +10,7 @@ import pytest
from ..channel_pb2 import Channel # pylint: disable=E0611 from ..channel_pb2 import Channel # pylint: disable=E0611
from ..node import Node from ..node import Node
from ..serial_interface import SerialInterface from ..serial_interface import SerialInterface
from ..mesh_interface import MeshInterface
# from ..config_pb2 import Config # from ..config_pb2 import Config
# from ..cannedmessages_pb2 import (CannedMessagePluginMessagePart1, CannedMessagePluginMessagePart2, # from ..cannedmessages_pb2 import (CannedMessagePluginMessagePart1, CannedMessagePluginMessagePart2,
@@ -234,7 +235,7 @@ def test_exitSimulator(caplog):
@pytest.mark.unit @pytest.mark.unit
def test_reboot(caplog): def test_reboot(caplog):
"""Test reboot""" """Test reboot"""
anode = Node("foo", "bar", noProto=True) anode = Node(MeshInterface(), 1234567890, noProto=True)
with caplog.at_level(logging.DEBUG): with caplog.at_level(logging.DEBUG):
anode.reboot() anode.reboot()
assert re.search(r"Telling node to reboot", caplog.text, re.MULTILINE) assert re.search(r"Telling node to reboot", caplog.text, re.MULTILINE)
@@ -243,7 +244,7 @@ def test_reboot(caplog):
@pytest.mark.unit @pytest.mark.unit
def test_shutdown(caplog): def test_shutdown(caplog):
"""Test shutdown""" """Test shutdown"""
anode = Node("foo", "bar", noProto=True) anode = Node(MeshInterface(), 1234567890, noProto=True)
with caplog.at_level(logging.DEBUG): with caplog.at_level(logging.DEBUG):
anode.shutdown() anode.shutdown()
assert re.search(r"Telling node to shutdown", caplog.text, re.MULTILINE) assert re.search(r"Telling node to shutdown", caplog.text, re.MULTILINE)
@@ -258,7 +259,7 @@ def test_setURL_empty_url(capsys):
assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1 assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert re.search(r"Warning: No RadioConfig has been read", out, re.MULTILINE) assert re.search(r"Warning: There were no settings.", out, re.MULTILINE)
assert err == "" assert err == ""
@@ -777,7 +778,8 @@ def test_writeConfig_with_no_radioConfig(capsys):
assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1 assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert re.search(r"Error: No RadioConfig has been read", out) print(out)
assert re.search(r"Error: No valid config with name foo", out)
assert err == "" assert err == ""

View File

@@ -41,13 +41,11 @@ def test_SerialInterface_single_port(
@patch("meshtastic.util.findPorts", return_value=[]) @patch("meshtastic.util.findPorts", return_value=[])
def test_SerialInterface_no_ports(mocked_findPorts, capsys): def test_SerialInterface_no_ports(mocked_findPorts, capsys):
"""Test that we can instantiate a SerialInterface with no ports""" """Test that we can instantiate a SerialInterface with no ports"""
with pytest.raises(SystemExit) as pytest_wrapped_e: serialInterface = SerialInterface(noProto=True)
SerialInterface(noProto=True)
mocked_findPorts.assert_called() mocked_findPorts.assert_called()
assert pytest_wrapped_e.type == SystemExit assert serialInterface.devPath is None
assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert re.search(r"Warning: No Meshtastic devices detected", out, re.MULTILINE) assert re.search(r"No.*Meshtastic.*device.*detected", out, re.MULTILINE)
assert err == "" assert err == ""

View File

@@ -40,15 +40,6 @@ def test_smoke1_info():
assert return_value == 0 assert return_value == 0
@pytest.mark.smoke1
def test_smoke1_sendping():
"""Test --sendping"""
return_value, out = subprocess.getstatusoutput("meshtastic --sendping")
assert re.match(r"Connected to radio", out)
assert re.search(r"^Sending ping message", out, re.MULTILINE)
assert return_value == 0
@pytest.mark.smoke1 @pytest.mark.smoke1
def test_get_with_invalid_setting(): def test_get_with_invalid_setting():
"""Test '--get a_bad_setting'.""" """Test '--get a_bad_setting'."""

View File

@@ -50,17 +50,6 @@ def test_smokevirt_info():
assert return_value == 0 assert return_value == 0
@pytest.mark.smokevirt
def test_smokevirt_sendping():
"""Test --sendping"""
return_value, out = subprocess.getstatusoutput(
"meshtastic --host localhost --sendping"
)
assert re.match(r"Connected to radio", out)
assert re.search(r"^Sending ping message", out, re.MULTILINE)
assert return_value == 0
@pytest.mark.smokevirt @pytest.mark.smokevirt
def test_get_with_invalid_setting(): def test_get_with_invalid_setting():
"""Test '--get a_bad_setting'.""" """Test '--get a_bad_setting'."""

View File

@@ -20,10 +20,10 @@ def test_Tunnel_on_non_linux_system(mock_platform_system):
a_mock.return_value = "notLinux" a_mock.return_value = "notLinux"
mock_platform_system.side_effect = a_mock mock_platform_system.side_effect = a_mock
with patch("socket.socket") as mock_socket: with patch("socket.socket") as mock_socket:
with pytest.raises(Exception) as pytest_wrapped_e: with pytest.raises(Tunnel.TunnelError) as pytest_wrapped_e:
iface = TCPInterface(hostname="localhost", noProto=True) iface = TCPInterface(hostname="localhost", noProto=True)
Tunnel(iface) Tunnel(iface)
assert pytest_wrapped_e.type == Exception assert pytest_wrapped_e.type == Tunnel.TunnelError
assert mock_socket.called assert mock_socket.called
@@ -34,9 +34,9 @@ def test_Tunnel_without_interface(mock_platform_system):
a_mock = MagicMock() a_mock = MagicMock()
a_mock.return_value = "Linux" a_mock.return_value = "Linux"
mock_platform_system.side_effect = a_mock mock_platform_system.side_effect = a_mock
with pytest.raises(Exception) as pytest_wrapped_e: with pytest.raises(Tunnel.TunnelError) as pytest_wrapped_e:
Tunnel(None) Tunnel(None)
assert pytest_wrapped_e.type == Exception assert pytest_wrapped_e.type == Tunnel.TunnelError
@pytest.mark.unitslow @pytest.mark.unitslow

View File

@@ -14,8 +14,8 @@ from queue import Queue
import packaging.version as pkg_version import packaging.version as pkg_version
import requests import requests
import serial import serial # type: ignore[import-untyped]
import serial.tools.list_ports import serial.tools.list_ports # type: ignore[import-untyped]
from meshtastic.supported_device import supported_devices from meshtastic.supported_device import supported_devices
from meshtastic.version import get_active_version from meshtastic.version import get_active_version
@@ -146,8 +146,8 @@ class dotdict(dict):
"""dot.notation access to dictionary attributes""" """dot.notation access to dictionary attributes"""
__getattr__ = dict.get __getattr__ = dict.get
__setattr__ = dict.__setitem__ __setattr__ = dict.__setitem__ # type: ignore[assignment]
__delattr__ = dict.__delitem__ __delattr__ = dict.__delitem__ # type: ignore[assignment]
class Timeout: class Timeout:

View File

@@ -13,7 +13,7 @@ with open("README.md", "r") as fh:
# This call to setup() does all the work # This call to setup() does all the work
setup( setup(
name="meshtastic", name="meshtastic",
version="2.3.0", version="2.3.1",
description="Python API & client shell for talking to Meshtastic devices", description="Python API & client shell for talking to Meshtastic devices",
long_description=long_description, long_description=long_description,
long_description_content_type="text/markdown", long_description_content_type="text/markdown",