Compare commits

..
4 Commits
Author SHA1 Message Date
ssmith f1dce0746a Update gitignore 2026-09-18 16:57:59 -06:00
ssmith 607680792a Defining messages from protobuf 2026-09-18 16:57:20 -06:00
pdxlocationsandGitHub b0f260ad3d Fix formatting in README diagram
Updated diagram formatting for clarity.
2026-08-27 11:12:06 -07:00
pdxlocations c0be23cf5a Update installation instructions in README files for clarity 2026-08-01 08:44:00 -07:00
29 changed files with 153 additions and 19 deletions
+2
View File
@@ -4,3 +4,5 @@ __pycache__/
build/
dist/
*.egg-info/
protobuf/
.idea/
+17 -16
View File
@@ -2,6 +2,8 @@
**A tiny, dependency-free Meshtastic client for MicroPython.**
[![PyPI](https://img.shields.io/pypi/v/micromesh.svg)](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?
@@ -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
View File
@@ -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
```
View File
View File
View File
View File
+30
View File
@@ -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
)
View File
View File
+101
View File
@@ -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
)
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File