vnode 0.1.7__tar.gz → 0.1.10__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {vnode-0.1.7 → vnode-0.1.10}/PKG-INFO +7 -3
- {vnode-0.1.7 → vnode-0.1.10}/README.md +5 -1
- {vnode-0.1.7 → vnode-0.1.10}/pyproject.toml +2 -2
- {vnode-0.1.7 → vnode-0.1.10}/vnode/vnode/runtime.py +18 -8
- {vnode-0.1.7 → vnode-0.1.10}/LICENSE +0 -0
- {vnode-0.1.7 → vnode-0.1.10}/vnode/vnode/__init__.py +0 -0
- {vnode-0.1.7 → vnode-0.1.10}/vnode/vnode/__main__.py +0 -0
- {vnode-0.1.7 → vnode-0.1.10}/vnode/vnode/cli.py +0 -0
- {vnode-0.1.7 → vnode-0.1.10}/vnode/vnode/config.py +0 -0
- {vnode-0.1.7 → vnode-0.1.10}/vnode/vnode/crypto.py +0 -0
- {vnode-0.1.7 → vnode-0.1.10}/vnode/vnode/example-node.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vnode
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.10
|
|
4
4
|
Summary: Virtual Meshtastic node using mudp transport and meshdb storage.
|
|
5
5
|
License-Expression: GPL-3.0-only
|
|
6
6
|
License-File: LICENSE
|
|
@@ -17,7 +17,7 @@ Classifier: Programming Language :: Python :: 3.14
|
|
|
17
17
|
Requires-Dist: cryptography (>=43,<45)
|
|
18
18
|
Requires-Dist: meshdb (>=0.1.9)
|
|
19
19
|
Requires-Dist: meshtastic (>=2.7,<3.0)
|
|
20
|
-
Requires-Dist: mudp (>=1.1.
|
|
20
|
+
Requires-Dist: mudp (>=1.1.5)
|
|
21
21
|
Project-URL: Homepage, https://github.com/pdxlocations/vnode
|
|
22
22
|
Project-URL: Issues, https://github.com/pdxlocations/vnode/issues
|
|
23
23
|
Description-Content-Type: text/markdown
|
|
@@ -106,6 +106,10 @@ Supported `VirtualNode` calls:
|
|
|
106
106
|
- MeshInterface-compatible sends: `sendText()`, `sendAlert()`, `sendData()`, `sendPosition()`
|
|
107
107
|
- Packet helpers: `is_direct_message_for_me()`, `is_text_message()`, `get_text_message()`, `reply_to_packet()`
|
|
108
108
|
|
|
109
|
+
`receive(callback)` is deduplicated. Repeated multicast copies stay on `mudp`'s wire-level
|
|
110
|
+
topics, while `vnode` publishes `meshtastic.receive` from `mesh.rx.unique_packet` so
|
|
111
|
+
application callbacks run once per logical packet.
|
|
112
|
+
|
|
109
113
|
## Examples
|
|
110
114
|
|
|
111
115
|
Use these as small runnable references for common tasks:
|
|
@@ -117,7 +121,7 @@ Use these as small runnable references for common tasks:
|
|
|
117
121
|
- `examples/serial_or_vnode.py`: try a serial Meshtastic node first, then fall back to `VirtualNode`
|
|
118
122
|
- `examples/send_dm.py`: minimal one-shot direct-message sender
|
|
119
123
|
- `examples/library_embed.py`: minimal application-style embedding example using `VirtualNode` directly
|
|
120
|
-
- `examples/watch_reliability.py`: watcher for ACK, NAK, retry, and retransmit-failure events
|
|
124
|
+
- `examples/watch_reliability.py`: watcher for unique ACK, NAK, retry, and retransmit-failure events
|
|
121
125
|
|
|
122
126
|
```bash
|
|
123
127
|
.venv/bin/python examples/autoresponder.py
|
|
@@ -82,6 +82,10 @@ Supported `VirtualNode` calls:
|
|
|
82
82
|
- MeshInterface-compatible sends: `sendText()`, `sendAlert()`, `sendData()`, `sendPosition()`
|
|
83
83
|
- Packet helpers: `is_direct_message_for_me()`, `is_text_message()`, `get_text_message()`, `reply_to_packet()`
|
|
84
84
|
|
|
85
|
+
`receive(callback)` is deduplicated. Repeated multicast copies stay on `mudp`'s wire-level
|
|
86
|
+
topics, while `vnode` publishes `meshtastic.receive` from `mesh.rx.unique_packet` so
|
|
87
|
+
application callbacks run once per logical packet.
|
|
88
|
+
|
|
85
89
|
## Examples
|
|
86
90
|
|
|
87
91
|
Use these as small runnable references for common tasks:
|
|
@@ -93,7 +97,7 @@ Use these as small runnable references for common tasks:
|
|
|
93
97
|
- `examples/serial_or_vnode.py`: try a serial Meshtastic node first, then fall back to `VirtualNode`
|
|
94
98
|
- `examples/send_dm.py`: minimal one-shot direct-message sender
|
|
95
99
|
- `examples/library_embed.py`: minimal application-style embedding example using `VirtualNode` directly
|
|
96
|
-
- `examples/watch_reliability.py`: watcher for ACK, NAK, retry, and retransmit-failure events
|
|
100
|
+
- `examples/watch_reliability.py`: watcher for unique ACK, NAK, retry, and retransmit-failure events
|
|
97
101
|
|
|
98
102
|
```bash
|
|
99
103
|
.venv/bin/python examples/autoresponder.py
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "vnode"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.10"
|
|
4
4
|
description = "Virtual Meshtastic node using mudp transport and meshdb storage."
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Ben Lipsey",email = "ben@pdxlocations.com"}
|
|
@@ -12,7 +12,7 @@ dependencies = [
|
|
|
12
12
|
"cryptography>=43,<45",
|
|
13
13
|
"meshdb>=0.1.9",
|
|
14
14
|
"meshtastic>=2.7,<3.0",
|
|
15
|
-
"mudp>=1.1.
|
|
15
|
+
"mudp>=1.1.5",
|
|
16
16
|
]
|
|
17
17
|
|
|
18
18
|
[project.urls]
|
|
@@ -63,7 +63,10 @@ def resolve_role(value: Union[str, int]) -> int:
|
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
class VirtualNode:
|
|
66
|
+
RAW_PACKET_TOPIC = "mesh.rx.packet"
|
|
66
67
|
PACKET_TOPIC = "mesh.rx.unique_packet"
|
|
68
|
+
ACK_TOPIC = "mesh.rx.ack"
|
|
69
|
+
NAK_TOPIC = "mesh.rx.nak"
|
|
67
70
|
DUPLICATE_TOPIC = "mesh.rx.duplicate"
|
|
68
71
|
RECEIVE_TOPIC = "meshtastic.receive"
|
|
69
72
|
|
|
@@ -142,11 +145,11 @@ class VirtualNode:
|
|
|
142
145
|
def start(self) -> None:
|
|
143
146
|
if self.stream is not None:
|
|
144
147
|
return
|
|
145
|
-
pub.subscribe(self._handle_raw_packet,
|
|
148
|
+
pub.subscribe(self._handle_raw_packet, self.RAW_PACKET_TOPIC)
|
|
146
149
|
pub.subscribe(self._handle_unique_packet, self.PACKET_TOPIC)
|
|
147
150
|
pub.subscribe(self._handle_compat_response_packet, self.RECEIVE_TOPIC)
|
|
148
|
-
pub.subscribe(self._handle_compat_ack,
|
|
149
|
-
pub.subscribe(self._handle_compat_nak,
|
|
151
|
+
pub.subscribe(self._handle_compat_ack, self.ACK_TOPIC)
|
|
152
|
+
pub.subscribe(self._handle_compat_nak, self.NAK_TOPIC)
|
|
150
153
|
self.stream = UDPPacketStream(
|
|
151
154
|
self.config.udp.mcast_group,
|
|
152
155
|
int(self.config.udp.mcast_port),
|
|
@@ -169,7 +172,7 @@ class VirtualNode:
|
|
|
169
172
|
self.stream.stop()
|
|
170
173
|
self.stream = None
|
|
171
174
|
try:
|
|
172
|
-
pub.unsubscribe(self._handle_raw_packet,
|
|
175
|
+
pub.unsubscribe(self._handle_raw_packet, self.RAW_PACKET_TOPIC)
|
|
173
176
|
except KeyError:
|
|
174
177
|
pass
|
|
175
178
|
try:
|
|
@@ -178,8 +181,8 @@ class VirtualNode:
|
|
|
178
181
|
pass
|
|
179
182
|
for topic, listener in (
|
|
180
183
|
(self.RECEIVE_TOPIC, self._handle_compat_response_packet),
|
|
181
|
-
(
|
|
182
|
-
(
|
|
184
|
+
(self.ACK_TOPIC, self._handle_compat_ack),
|
|
185
|
+
(self.NAK_TOPIC, self._handle_compat_nak),
|
|
183
186
|
):
|
|
184
187
|
try:
|
|
185
188
|
pub.unsubscribe(listener, topic)
|
|
@@ -364,8 +367,13 @@ class VirtualNode:
|
|
|
364
367
|
if getattr(conn, "socket", None) is None:
|
|
365
368
|
conn.setup_multicast(self.config.udp.mcast_group, int(self.config.udp.mcast_port))
|
|
366
369
|
|
|
367
|
-
def send_nodeinfo(
|
|
368
|
-
|
|
370
|
+
def send_nodeinfo(
|
|
371
|
+
self,
|
|
372
|
+
destination: int = BROADCAST_NUM,
|
|
373
|
+
*,
|
|
374
|
+
want_response: bool = False,
|
|
375
|
+
) -> int:
|
|
376
|
+
return self._send_nodeinfo(destination, want_response=want_response)
|
|
369
377
|
|
|
370
378
|
def _send_nodeinfo(
|
|
371
379
|
self,
|
|
@@ -373,6 +381,7 @@ class VirtualNode:
|
|
|
373
381
|
*,
|
|
374
382
|
request_id: Optional[int] = None,
|
|
375
383
|
want_ack: bool = False,
|
|
384
|
+
want_response: bool = False,
|
|
376
385
|
) -> int:
|
|
377
386
|
user = mesh_pb2.User(
|
|
378
387
|
id=self.config.node_id,
|
|
@@ -389,6 +398,7 @@ class VirtualNode:
|
|
|
389
398
|
data.payload = user.SerializeToString()
|
|
390
399
|
data.source = self.node_num
|
|
391
400
|
data.dest = int(destination)
|
|
401
|
+
data.want_response = bool(want_response)
|
|
392
402
|
if request_id is not None:
|
|
393
403
|
data.request_id = int(request_id)
|
|
394
404
|
packet_id = self._send_data(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|