Compare commits
4
Commits
0.1.0
..
f1dce0746a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1dce0746a | ||
|
|
607680792a | ||
|
|
b0f260ad3d | ||
|
|
c0be23cf5a |
@@ -4,3 +4,5 @@ __pycache__/
|
||||
build/
|
||||
dist/
|
||||
*.egg-info/
|
||||
protobuf/
|
||||
.idea/
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
**A tiny, dependency-free Meshtastic client for MicroPython.**
|
||||
|
||||
[](https://pypi.org/project/micromesh/)
|
||||
|
||||
MicroMesh lets a small MicroPython board talk to a Meshtastic radio over UART. Use it
|
||||
to receive messages, send text and position packets, inspect the node list, or power a
|
||||
full-screen terminal dashboard.
|
||||
@@ -9,10 +11,9 @@ full-screen terminal dashboard.
|
||||
No protobuf compiler runs on the board. No threads. No `google.protobuf`. Just a UART,
|
||||
three wires, and regular Python.
|
||||
|
||||
> [!NOTE]
|
||||
> MicroMesh is young and intentionally small. It supports the most useful Meshtastic
|
||||
> client operations, but it is not yet a complete replacement for the official desktop
|
||||
> [`meshtastic`](https://github.com/meshtastic/python) package.
|
||||
MicroMesh intentionally provides a focused, lightweight client for embedded projects.
|
||||
For the complete desktop feature set, use the official
|
||||
[`meshtastic`](https://github.com/meshtastic/python) package.
|
||||
|
||||
## What can it do?
|
||||
|
||||
@@ -41,8 +42,8 @@ three wires, and regular Python.
|
||||
The XIAO is the computer running MicroMesh. The Meshtastic device is the LoRa radio.
|
||||
|
||||
```text
|
||||
Mac / PC XIAO RP2040 Meshtastic radio
|
||||
┌─────────┐ USB/REPL ┌────────────────┐ UART ┌─────────────────┐
|
||||
Mac / PC XIAO RP2040 Meshtastic radio
|
||||
┌─────────┐ USB/REPL ┌────────────────┐ UART ┌─────────────────┐
|
||||
│ terminal│◀─────────────▶│ MicroPython + │◀────────▶│ Meshtastic │◀──▶ LoRa
|
||||
│ or UI │ │ MicroMesh │ 3 wires │ firmware │
|
||||
└─────────┘ └────────────────┘ └─────────────────┘
|
||||
@@ -204,7 +205,7 @@ package is present on the board.
|
||||
|
||||
```sh
|
||||
source .venv/bin/activate
|
||||
python -m pip install -e . pyserial
|
||||
python -m pip install micromesh pyserial
|
||||
```
|
||||
|
||||
Windows users also need:
|
||||
@@ -255,7 +256,7 @@ If the Meshtastic radio itself is connected to your computer over USB, the deskt
|
||||
talk directly to it. Do not use `--xiao-bridge` in this mode.
|
||||
|
||||
```sh
|
||||
python -m pip install -e . pyserial
|
||||
python -m pip install micromesh pyserial
|
||||
python -m serial.tools.list_ports -v
|
||||
python examples/curses_dashboard.py /dev/cu.YOUR_RADIO_PORT
|
||||
```
|
||||
@@ -426,18 +427,18 @@ Or copy the package directory manually:
|
||||
mpremote fs cp -r micromesh :lib/
|
||||
```
|
||||
|
||||
For CPython development:
|
||||
|
||||
```sh
|
||||
python -m pip install -e .
|
||||
```
|
||||
|
||||
After the first PyPI release:
|
||||
Install the published package from PyPI:
|
||||
|
||||
```sh
|
||||
python -m pip install micromesh
|
||||
```
|
||||
|
||||
For editable CPython development from a repository checkout:
|
||||
|
||||
```sh
|
||||
python -m pip install -e .
|
||||
```
|
||||
|
||||
## Supported scope
|
||||
|
||||
MicroMesh currently models the most useful portions of the Meshtastic API:
|
||||
@@ -469,8 +470,8 @@ sending, input validation, and configuration state.
|
||||
|
||||
## Releasing to PyPI
|
||||
|
||||
Maintainers publish with GitHub Trusted Publishing; no long-lived PyPI token is stored
|
||||
in the repository. Configure the pending publisher with:
|
||||
MicroMesh publishes with GitHub Trusted Publishing, so no long-lived PyPI token is
|
||||
stored in the repository. The publisher configuration is:
|
||||
|
||||
| Setting | Value |
|
||||
| --- | --- |
|
||||
@@ -481,7 +482,7 @@ in the repository. Configure the pending publisher with:
|
||||
| Environment | `pypi` |
|
||||
|
||||
Keep the version in `pyproject.toml`, `package.json`, and `micromesh/__init__.py` in
|
||||
sync. Publishing a matching GitHub release, such as `v0.1.0`, builds, validates, and
|
||||
sync. Publishing a matching GitHub release, such as `0.1.0`, builds, validates, and
|
||||
uploads the wheel and source distribution.
|
||||
|
||||
## License
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ connection statistics, known nodes, and received messages, and it can send broad
|
||||
messages. It can connect directly to a radio or through a XIAO RP2040 UART bridge.
|
||||
|
||||
```sh
|
||||
python -m pip install -e . pyserial
|
||||
python -m pip install micromesh pyserial
|
||||
python examples/curses_dashboard.py /dev/cu.usbmodem123456
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
from micromesh.protobuf import Field, ProtoMessage, fields
|
||||
|
||||
class Role:
|
||||
DISABLED = 0
|
||||
PRIMARY = 1
|
||||
SECONDARY = 2
|
||||
|
||||
class ModuleSettings(ProtoMessage):
|
||||
FIELDS = fields(
|
||||
position_precision=Field(1, "uint32"),
|
||||
is_muted=Field(2, "bool")
|
||||
)
|
||||
|
||||
class ChannelSettings(ProtoMessage):
|
||||
FIELDS = fields(
|
||||
channel_num=Field(1, "uint32"), # Deprecated in favor of LoraConfig.channel_num
|
||||
psk=Field(2, "bytes"),
|
||||
name=Field(3, "string"),
|
||||
id=Field(4, "fixed32"),
|
||||
uplink_enabled=Field(5, "bool"),
|
||||
downlink_enabled=Field(6, "bool"),
|
||||
module_settings=Field(7, "message", ModuleSettings)
|
||||
)
|
||||
|
||||
class Channel(ProtoMessage):
|
||||
FIELDS = fields(
|
||||
index=Field(1, "int32"),
|
||||
settings=Field(2, "message", ChannelSettings),
|
||||
role=Field(3) # Role
|
||||
)
|
||||
@@ -0,0 +1,101 @@
|
||||
from micromesh.protobuf import Field, ProtoMessage, fields
|
||||
|
||||
class GpsCoordinateFormat:
|
||||
DEC = 0
|
||||
DMS = 1
|
||||
UTM = 2
|
||||
MGRS = 3
|
||||
OLC = 4
|
||||
OSGR = 5
|
||||
MLS = 6
|
||||
|
||||
class CompassMode:
|
||||
DYNAMIC = 0
|
||||
FIXED_RING = 1
|
||||
FREEZE_HEADING = 2
|
||||
|
||||
class Theme:
|
||||
DARK = 0
|
||||
LIGHT = 1
|
||||
RED = 2
|
||||
|
||||
class Language:
|
||||
ENGLISH = 0
|
||||
FRENCH = 1
|
||||
GERMAN = 2
|
||||
ITALIAN = 3
|
||||
PORTUGUESE = 4
|
||||
SPANISH = 5
|
||||
SWEDISH = 6
|
||||
FINNISH = 7
|
||||
POLISH = 8
|
||||
TURKISH = 9
|
||||
SERBIAN = 10
|
||||
RUSSIAN = 11
|
||||
DUTCH = 12
|
||||
GREEK = 13
|
||||
NORWEGIAN = 14
|
||||
SLOVENIAN = 15
|
||||
UKRAINIAN = 16
|
||||
BULGARIAN = 17
|
||||
CZECH = 18
|
||||
DANISH = 19
|
||||
SIMPLIFIED_CHINESE = 30
|
||||
TRADITIONAL_CHINESE = 31
|
||||
|
||||
class GeoPoint(ProtoMessage):
|
||||
FIELDS = fields(
|
||||
zoom=Field(1, "int32"),
|
||||
latitude=Field(2, "int32"),
|
||||
longitude=Field(3, "int32")
|
||||
)
|
||||
|
||||
class Map(ProtoMessage):
|
||||
FIELDS = fields(
|
||||
home=Field(1, "message", GeoPoint),
|
||||
style=Field(2, "string"),
|
||||
follow_gps=Field(3, 'bool')
|
||||
)
|
||||
|
||||
class NodeHighlight(ProtoMessage):
|
||||
FIELDS = fields(
|
||||
chat_switch=Field(1, "bool"),
|
||||
position_switch=Field(2, "bool"),
|
||||
telemetry_switch=Field(3, "bool"),
|
||||
iaq_switch=Field(4, "bool"),
|
||||
node_name=Field(5, "string")
|
||||
)
|
||||
|
||||
class NodeFilter(ProtoMessage):
|
||||
FIELDS = fields(
|
||||
unknown_switch=Field(1, "bool"),
|
||||
offline_switch=Field(2, "bool"),
|
||||
public_key_switch=Field(3, "bool"),
|
||||
hops_away=Field(4, "int32"),
|
||||
position_switch=Field(5, "bool"),
|
||||
node_name=Field(6, "string"),
|
||||
channel=Field(7, "int32"),
|
||||
)
|
||||
|
||||
class DeviceUIConfig(ProtoMessage):
|
||||
FIELDS = fields(
|
||||
version=Field(1, "uint32"),
|
||||
screen_brightness=Field(2, "uint32"),
|
||||
screen_timeout=Field(3, "uint32"),
|
||||
screen_lock=Field(4, "bool"),
|
||||
settings_lock=Field(5, "bool"),
|
||||
pin_code=Field(6, "uint32"),
|
||||
theme=Field(7), # Theme
|
||||
alert_enabled=Field(8, "bool"),
|
||||
banner_enabled=Field(9, "bool"),
|
||||
ring_tone_id=Field(10, "uint32"),
|
||||
language=Field(11), # Language
|
||||
node_filter=Field(12, "message", NodeFilter),
|
||||
node_highlight=Field(13, "message", NodeHighlight),
|
||||
calibration_data=Field(14, "bytes"),
|
||||
map_data=Field(15, "message", Map),
|
||||
compass_mode=Field(16), # CompassMode
|
||||
screen_rgb_color=Field(17, "uint32"),
|
||||
is_clockface_analog=Field(18, "bool"),
|
||||
gps_format=Field(19) # GpsCoordinateFormat
|
||||
)
|
||||
Reference in New Issue
Block a user