镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content
pdxlocationsPublic

About

A Python library and CLI for creating virtual Meshtastic nodes that communicate over UDP transport, enabling testing and simulation without physical hardware.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Repository files navigation

vnode

Virtual Meshtastic node runtime built around:

  • mudp for multicast UDP send/receive
  • meshdb for packet and node persistence
  • Meshtastic-style PKI DM encryption using X25519 + SHA-256 + AES-CCM

Install

Install from PyPI:

pip install vnode

If you are working from this repository instead:

.venv/bin/pip install -e .

Config

Edit node.json (created locally and excluded from version control).

If node.json does not exist yet, the runtime will create it automatically from example-node.json.

The runtime derives node_id from the IEEE CRC-32 of its X25519 public key, matching Meshtastic 2.8 identity binding. It is a read-only property of NodeConfig, not a JSON setting. Existing node_id fields are removed on load while preserving the private key and configured names. Changing the private key changes the node ID and starts a new node database; the old database is preserved. With meshdb 0.3, each owner file uses channel-scoped tables for node records, broadcasts, positions, and telemetry, plus per-peer DM tables. Existing contact records are copied from the legacy owner node table on startup; old message and telemetry tables remain intact. If long_name or short_name are blank, the runtime will also generate them from the last 4 hex characters of the node ID, for example Meshtastic 691c and 691c.

The runtime will generate and persist a PKI private key into node.json on first run if the private key is blank.

The derived public key is written automatically to node.public.key next to node.json. That file is generated by the runtime and should not need manual edits.

Broadcasts and directed nodeinfo/position packets carry XEdDSA signatures using the existing X25519 identity key and the Meshtastic 2.8.1 signing format. Traceroutes and packets that cannot fit a signature within the 255-byte radio frame remain unsigned. Direct messages retain X25519/AES-CCM encryption.

Signed nodeinfo lets compatible receivers authenticate first contact without a handshake or a running vnode listener. Nodeinfo includes the fixed-length MAC field required by firmware's protobuf encoder so UDP-to-LoRa gateways can re-encode it without invalidating the signature. The iOS app may need to be closed and reopened to display the Signed Node badge after first receipt. This badge is separate from manual contact/key verification.

The position section in node.json controls periodic position broadcasts. Set position.enabled to true, then set position.latitude and position.longitude, and adjust position.position_interval_seconds to control how often the node sends POSITION_APP packets. You can also set position.altitude if you want altitude included in the payload. Leave position.enabled false or leave latitude/longitude as null to disable position broadcasts.

Run

.venv/bin/python -m vnode --vnode-file node.json run

Send a DM

.venv/bin/python -m vnode --vnode-file node.json send-text --to '!1234abcd' --message 'hello'

send-text uses PKI automatically for direct messages when the destination node has a stored public key in meshdb. Otherwise it falls back to channel encryption. --config is still accepted as a compatibility alias for --vnode-file.

Library

The installable package lives under vnode/vnode, and the public library surface is exported from vnode directly:

from vnode import NodeConfig, VirtualNode, generate_keypair

node = VirtualNode("node.json")
packet_id = node.send_text("!1234abcd", "hello")

Supported VirtualNode calls:

  • Lifecycle: start(), stop(), close(), run_forever()
  • Subscription: receive(callback), unreceive(callback)
  • Node identity: getLongName(), getShortName(), getPublicKey(), getMyUser(), getMyNodeInfo()
  • Native vnode sends: send_text(), send_reply(), send_nodeinfo(), send_position()
  • MeshInterface-compatible sends: sendText(), sendAlert(), sendData(), sendPosition()
  • Packet helpers: is_direct_message_for_me(), is_text_message(), get_text_message(), reply_to_packet()

receive(callback) is deduplicated. Repeated multicast copies stay on mudp's wire-level topics, while vnode publishes meshtastic.receive from mesh.rx.unique_packet so application callbacks run once per logical packet.

Examples

Use these as small runnable references for common tasks:

  • examples/autoresponder.py: DM-only reply bot for inbound direct text messages
  • examples/basic_subscriptions.py: minimal node.receive() subscription example
  • examples/listen_packets.py: packet logger for multicast traffic and decoded text
  • examples/mesh_interface_compat.py: examples of MeshInterface-style compatibility calls on VirtualNode
  • examples/serial_or_vnode.py: try a serial Meshtastic node first, then fall back to VirtualNode
  • examples/send_dm.py: minimal one-shot direct-message sender
  • examples/library_embed.py: minimal application-style embedding example using VirtualNode directly
  • examples/watch_reliability.py: watcher for unique ACK, NAK, retry, and retransmit-failure events
.venv/bin/python examples/autoresponder.py
.venv/bin/python examples/basic_subscriptions.py
.venv/bin/python examples/listen_packets.py
.venv/bin/python examples/mesh_interface_compat.py
.venv/bin/python examples/serial_or_vnode.py
.venv/bin/python examples/send_dm.py --to '!1234abcd' --message 'hello'
.venv/bin/python examples/library_embed.py
.venv/bin/python examples/watch_reliability.py --to '!1234abcd' --message 'hello'

See examples/README.md for the full list.

Tests

.venv/bin/python -m unittest discover -s vnode/tests -v

The signing tests cover identity migration, key rotation, the firmware signing layout, tamper rejection, radio frame limits, and nodeinfo gateway re-encoding.

License

GPL-3.0-only. See LICENSE.

Meshtastic® is a registered trademark of Meshtastic LLC. Meshtastic software components are released under various licenses, see GitHub for details. No warranty is provided - use at your own risk.

About

A Python library and CLI for creating virtual Meshtastic nodes that communicate over UDP transport, enabling testing and simulation without physical hardware.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages