mirror of
https://github.com/meshtastic/python.git
synced 2026-01-01 12:27:59 -05:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
022a8a1017 | ||
|
|
21f6e25ab0 | ||
|
|
243e297505 | ||
|
|
9fc86f9450 | ||
|
|
e5999f5be6 | ||
|
|
3886bc16d7 | ||
|
|
7fe98bc266 | ||
|
|
2f9307fd99 |
@@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18meshtastic/channel.proto\x12\nmeshtastic\"\xb8\x01\n\x0f\x43hannelSettings\x12\x17\n\x0b\x63hannel_num\x18\x01 \x01(\rB\x02\x18\x01\x12\x0b\n\x03psk\x18\x02 \x01(\x0c\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\n\n\x02id\x18\x04 \x01(\x07\x12\x16\n\x0euplink_enabled\x18\x05 \x01(\x08\x12\x18\n\x10\x64ownlink_enabled\x18\x06 \x01(\x08\x12\x33\n\x0fmodule_settings\x18\x07 \x01(\x0b\x32\x1a.meshtastic.ModuleSettings\",\n\x0eModuleSettings\x12\x1a\n\x12position_precision\x18\x01 \x01(\r\"\xa1\x01\n\x07\x43hannel\x12\r\n\x05index\x18\x01 \x01(\x05\x12-\n\x08settings\x18\x02 \x01(\x0b\x32\x1b.meshtastic.ChannelSettings\x12&\n\x04role\x18\x03 \x01(\x0e\x32\x18.meshtastic.Channel.Role\"0\n\x04Role\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07PRIMARY\x10\x01\x12\r\n\tSECONDARY\x10\x02\x42\x62\n\x13\x63om.geeksville.meshB\rChannelProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18meshtastic/channel.proto\x12\nmeshtastic\"\xb8\x01\n\x0f\x43hannelSettings\x12\x17\n\x0b\x63hannel_num\x18\x01 \x01(\rB\x02\x18\x01\x12\x0b\n\x03psk\x18\x02 \x01(\x0c\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\n\n\x02id\x18\x04 \x01(\x07\x12\x16\n\x0euplink_enabled\x18\x05 \x01(\x08\x12\x18\n\x10\x64ownlink_enabled\x18\x06 \x01(\x08\x12\x33\n\x0fmodule_settings\x18\x07 \x01(\x0b\x32\x1a.meshtastic.ModuleSettings\"E\n\x0eModuleSettings\x12\x1a\n\x12position_precision\x18\x01 \x01(\r\x12\x17\n\x0fis_client_muted\x18\x02 \x01(\x08\"\xa1\x01\n\x07\x43hannel\x12\r\n\x05index\x18\x01 \x01(\x05\x12-\n\x08settings\x18\x02 \x01(\x0b\x32\x1b.meshtastic.ChannelSettings\x12&\n\x04role\x18\x03 \x01(\x0e\x32\x18.meshtastic.Channel.Role\"0\n\x04Role\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07PRIMARY\x10\x01\x12\r\n\tSECONDARY\x10\x02\x42\x62\n\x13\x63om.geeksville.meshB\rChannelProtosZ\"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.channel_pb2', globals())
|
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.channel_pb2', globals())
|
||||||
@@ -26,9 +26,9 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
|||||||
_CHANNELSETTINGS._serialized_start=41
|
_CHANNELSETTINGS._serialized_start=41
|
||||||
_CHANNELSETTINGS._serialized_end=225
|
_CHANNELSETTINGS._serialized_end=225
|
||||||
_MODULESETTINGS._serialized_start=227
|
_MODULESETTINGS._serialized_start=227
|
||||||
_MODULESETTINGS._serialized_end=271
|
_MODULESETTINGS._serialized_end=296
|
||||||
_CHANNEL._serialized_start=274
|
_CHANNEL._serialized_start=299
|
||||||
_CHANNEL._serialized_end=435
|
_CHANNEL._serialized_end=460
|
||||||
_CHANNEL_ROLE._serialized_start=387
|
_CHANNEL_ROLE._serialized_start=412
|
||||||
_CHANNEL_ROLE._serialized_end=435
|
_CHANNEL_ROLE._serialized_end=460
|
||||||
# @@protoc_insertion_point(module_scope)
|
# @@protoc_insertion_point(module_scope)
|
||||||
|
|||||||
@@ -125,16 +125,23 @@ class ModuleSettings(google.protobuf.message.Message):
|
|||||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||||
|
|
||||||
POSITION_PRECISION_FIELD_NUMBER: builtins.int
|
POSITION_PRECISION_FIELD_NUMBER: builtins.int
|
||||||
|
IS_CLIENT_MUTED_FIELD_NUMBER: builtins.int
|
||||||
position_precision: builtins.int
|
position_precision: builtins.int
|
||||||
"""
|
"""
|
||||||
Bits of precision for the location sent in position packets.
|
Bits of precision for the location sent in position packets.
|
||||||
"""
|
"""
|
||||||
|
is_client_muted: builtins.bool
|
||||||
|
"""
|
||||||
|
Controls whether or not the phone / clients should mute the current channel
|
||||||
|
Useful for noisy public channels you don't necessarily want to disable
|
||||||
|
"""
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
position_precision: builtins.int = ...,
|
position_precision: builtins.int = ...,
|
||||||
|
is_client_muted: builtins.bool = ...,
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
def ClearField(self, field_name: typing_extensions.Literal["position_precision", b"position_precision"]) -> None: ...
|
def ClearField(self, field_name: typing_extensions.Literal["is_client_muted", b"is_client_muted", "position_precision", b"position_precision"]) -> None: ...
|
||||||
|
|
||||||
global___ModuleSettings = ModuleSettings
|
global___ModuleSettings = ModuleSettings
|
||||||
|
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ class MeshInterface:
|
|||||||
self.mask: Optional[int] = None # used in gpio read and gpio watch
|
self.mask: Optional[int] = None # used in gpio read and gpio watch
|
||||||
self.queueStatus: Optional[mesh_pb2.QueueStatus] = None
|
self.queueStatus: Optional[mesh_pb2.QueueStatus] = None
|
||||||
self.queue: collections.OrderedDict = collections.OrderedDict()
|
self.queue: collections.OrderedDict = collections.OrderedDict()
|
||||||
|
self._localChannels = None
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
"""Shutdown this interface"""
|
"""Shutdown this interface"""
|
||||||
@@ -133,7 +134,7 @@ 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"]
|
||||||
nodes[nodeid] = n2
|
nodes[nodeid] = n2
|
||||||
infos = owner + myinfo + metadata + mesh + json.dumps(nodes)
|
infos = owner + myinfo + metadata + mesh + json.dumps(nodes, indent=2)
|
||||||
print(infos)
|
print(infos)
|
||||||
return infos
|
return infos
|
||||||
|
|
||||||
@@ -682,6 +683,7 @@ class MeshInterface:
|
|||||||
self.heartbeatTimer = threading.Timer(i, callback)
|
self.heartbeatTimer = threading.Timer(i, callback)
|
||||||
self.heartbeatTimer.start()
|
self.heartbeatTimer.start()
|
||||||
p = mesh_pb2.ToRadio()
|
p = mesh_pb2.ToRadio()
|
||||||
|
p.heartbeat.CopyFrom(mesh_pb2.Heartbeat())
|
||||||
self._sendToRadio(p)
|
self._sendToRadio(p)
|
||||||
|
|
||||||
callback() # run our periodic callback now, it will make another timer if necessary
|
callback() # run our periodic callback now, it will make another timer if necessary
|
||||||
@@ -705,6 +707,7 @@ class MeshInterface:
|
|||||||
self.myInfo = None
|
self.myInfo = None
|
||||||
self.nodes = {} # nodes keyed by ID
|
self.nodes = {} # nodes keyed by ID
|
||||||
self.nodesByNum = {} # nodes keyed by nodenum
|
self.nodesByNum = {} # nodes keyed by nodenum
|
||||||
|
self._localChannels = [] # empty until we start getting channels pushed from the device (during config)
|
||||||
|
|
||||||
startConfig = mesh_pb2.ToRadio()
|
startConfig = mesh_pb2.ToRadio()
|
||||||
self.configId = random.randint(0, 0xFFFFFFFF)
|
self.configId = random.randint(0, 0xFFFFFFFF)
|
||||||
@@ -786,7 +789,12 @@ class MeshInterface:
|
|||||||
Done with initial config messages, now send regular MeshPackets
|
Done with initial config messages, now send regular MeshPackets
|
||||||
to ask for settings and channels
|
to ask for settings and channels
|
||||||
"""
|
"""
|
||||||
self.localNode.requestChannels()
|
# This is no longer necessary because the current protocol statemachine has already proactively sent us the locally visible channels
|
||||||
|
# self.localNode.requestChannels()
|
||||||
|
self.localNode.setChannels(self._localChannels)
|
||||||
|
|
||||||
|
# the following should only be called after we have settings and channels
|
||||||
|
self._connected() # Tell everyone else we are ready to go
|
||||||
|
|
||||||
def _handleQueueStatusFromRadio(self, queueStatus) -> None:
|
def _handleQueueStatusFromRadio(self, queueStatus) -> None:
|
||||||
self.queueStatus = queueStatus
|
self.queueStatus = queueStatus
|
||||||
@@ -859,7 +867,8 @@ class MeshInterface:
|
|||||||
# stream API fromRadio.config_complete_id
|
# stream API fromRadio.config_complete_id
|
||||||
logging.debug(f"Config complete ID {self.configId}")
|
logging.debug(f"Config complete ID {self.configId}")
|
||||||
self._handleConfigComplete()
|
self._handleConfigComplete()
|
||||||
|
elif fromRadio.HasField("channel"):
|
||||||
|
self._handleChannel(fromRadio.channel)
|
||||||
elif fromRadio.HasField("packet"):
|
elif fromRadio.HasField("packet"):
|
||||||
self._handlePacketFromRadio(fromRadio.packet)
|
self._handlePacketFromRadio(fromRadio.packet)
|
||||||
|
|
||||||
@@ -986,6 +995,10 @@ class MeshInterface:
|
|||||||
self.nodesByNum[nodeNum] = n
|
self.nodesByNum[nodeNum] = n
|
||||||
return n
|
return n
|
||||||
|
|
||||||
|
def _handleChannel(self, channel):
|
||||||
|
"""During initial config the local node will proactively send all N (8) channels it knows"""
|
||||||
|
self._localChannels.append(channel)
|
||||||
|
|
||||||
def _handlePacketFromRadio(self, meshPacket, hack=False):
|
def _handlePacketFromRadio(self, meshPacket, hack=False):
|
||||||
"""Handle a MeshPacket that just arrived from the radio
|
"""Handle a MeshPacket that just arrived from the radio
|
||||||
|
|
||||||
|
|||||||
@@ -64,14 +64,19 @@ class Node:
|
|||||||
"""Show human readable description of our node"""
|
"""Show human readable description of our node"""
|
||||||
prefs = ""
|
prefs = ""
|
||||||
if self.localConfig:
|
if self.localConfig:
|
||||||
prefs = message_to_json(self.localConfig)
|
prefs = message_to_json(self.localConfig, multiline=True)
|
||||||
print(f"Preferences: {prefs}\n")
|
print(f"Preferences: {prefs}\n")
|
||||||
prefs = ""
|
prefs = ""
|
||||||
if self.moduleConfig:
|
if self.moduleConfig:
|
||||||
prefs = message_to_json(self.moduleConfig)
|
prefs = message_to_json(self.moduleConfig, multiline=True)
|
||||||
print(f"Module preferences: {prefs}\n")
|
print(f"Module preferences: {prefs}\n")
|
||||||
self.showChannels()
|
self.showChannels()
|
||||||
|
|
||||||
|
def setChannels(self, channels):
|
||||||
|
"""Set the channels for this node"""
|
||||||
|
self.channels = channels
|
||||||
|
self._fixupChannels()
|
||||||
|
|
||||||
def requestChannels(self):
|
def requestChannels(self):
|
||||||
"""Send regular MeshPackets to ask channels."""
|
"""Send regular MeshPackets to ask channels."""
|
||||||
logging.debug(f"requestChannels for nodeNum:{self.nodeNum}")
|
logging.debug(f"requestChannels for nodeNum:{self.nodeNum}")
|
||||||
@@ -654,7 +659,7 @@ class Node:
|
|||||||
"""Fixup indexes and add disabled channels as needed"""
|
"""Fixup indexes and add disabled channels as needed"""
|
||||||
|
|
||||||
# Add extra disabled channels as needed
|
# Add extra disabled channels as needed
|
||||||
# TODO: These 2 lines seem to not do anything.
|
# This is needed because the protobufs will have index **missing** if the channel number is zero
|
||||||
for index, ch in enumerate(self.channels):
|
for index, ch in enumerate(self.channels):
|
||||||
ch.index = index # fixup indexes
|
ch.index = index # fixup indexes
|
||||||
|
|
||||||
@@ -726,9 +731,6 @@ class Node:
|
|||||||
|
|
||||||
self.channels = self.partialChannels
|
self.channels = self.partialChannels
|
||||||
self._fixupChannels()
|
self._fixupChannels()
|
||||||
|
|
||||||
# FIXME, the following should only be called after we have settings and channels
|
|
||||||
self.iface._connected() # Tell everyone else we are ready to go
|
|
||||||
else:
|
else:
|
||||||
self._requestChannel(index + 1)
|
self._requestChannel(index + 1)
|
||||||
|
|
||||||
|
|||||||
@@ -627,6 +627,8 @@ def check_if_newer_version():
|
|||||||
|
|
||||||
return pypi_version
|
return pypi_version
|
||||||
|
|
||||||
def message_to_json(message):
|
|
||||||
"Return protobuf message as JSON. Always print all fields, even when not present in data."
|
def message_to_json(message, multiline=False):
|
||||||
return stripnl(MessageToJson(message, always_print_fields_with_no_presence=True))
|
"""Return protobuf message as JSON. Always print all fields, even when not present in data."""
|
||||||
|
json = MessageToJson(message, always_print_fields_with_no_presence=True)
|
||||||
|
return stripnl(json) if not multiline else json
|
||||||
|
|||||||
Submodule protobufs updated: 86640f20db...e21899aa6b
2
setup.py
2
setup.py
@@ -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.6",
|
version="2.3.7",
|
||||||
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",
|
||||||
|
|||||||
Reference in New Issue
Block a user