Metadata-Version: 2.4
Name: mushtastic
Version: 0.1.3
Summary: Meshtastic live logger with an interactive command prompt
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: click>=8.1
Requires-Dist: click-aliases>=1.0.6
Requires-Dist: meshtastic>=2.5
Requires-Dist: peewee>=3.17
Requires-Dist: prompt-toolkit>=3.0.36
Requires-Dist: PyPubSub>=4.0
Requires-Dist: rich>=13.0
Requires-Dist: wcwidth>=0.2

# mushtastic

`mushtastic` installs the `mush` command: a Meshtastic live packet logger
with an interactive prompt. It connects to a radio over serial, TCP, or BLE;
stores received and locally sent packets in SQLite; and provides tools to
inspect nodes and packets, send messages, configure the radio, and manage
channels.

## Requirements

- Python 3.10 or newer
- A Meshtastic-capable radio reachable over USB/serial, TCP, or BLE

## Install

```bash
pip install mushtastic
```

Run either entry point after installation:

```bash
mush --help
python -m mushtastic --help
```

## Start a live session

```bash
mush live                         # auto-detect a serial radio
mush live --dev /dev/ttyUSB0
mush live --tcp 192.168.1.50:4403
mush live --ble AA:BB:CC:DD:EE:FF
```

Choose at most one of `--dev`, `--tcp`, and `--ble`. A TCP address without a
port uses port `4403`. Serial connections automatically try to reconnect after
a radio restart.

Use `Ctrl+D` to leave the prompt. BLE shutdown is limited to five seconds, so
`mush` may print a warning and exit if the underlying Bluetooth library stalls.

The prompt shows the radio's default hop limit, local node identity, and the
current message target, for example:

```text
🐰3 !deadbeef MUSH @ primary>
```

## Global options

Place global options before the command:

| Option | Description |
| --- | --- |
| `-v`, `--version` | Show the installed version. |
| `-d`, `--debug` | Enable radio device log output. |
| `--database PATH` | Use a specific SQLite database file. |
| `--pos-fmt {latlon,google,osm}` | Select position display format. |

Without `--database`, `mush` uses `mush.db` in the current directory.

## Messaging in the prompt

Commands begin with `/`. Any other nonempty line sends a text message to the
current target, which starts as the primary channel. Set the target with
`/target`:

```text
/target !deadbeef       # a node ID
/target NORTH           # a unique node short name, or a channel name
/target #1              # channel 1
Hello from the field!   # sent to the selected target
```

Channel names take precedence when a channel name and node short name match.
`!xxxxxxxx`, `^local`, and `^all` identify nodes. `#0` through `#7` identify
enabled channels.

Send one message to another target without changing the selection by prefixing
it with `@ENTITY`:

```text
@LongFast hello everyone
@!deadbeef are you there?
@#1 need assistance
```

Use a `#N` prefix to override the hop limit for one message, where `N` is 0
through 7. For a one-off target, it may appear before `@ENTITY` or immediately
after it:

```text
#3 hello there
@admin #2 need help
#2 @admin need help
```

Use `/hops` to view the default hop limit, or `/hops N` to change it. A literal
message cannot begin with `/`.

## Prompt commands

Type `/` then press Tab for completion, or use `/COMMAND --help` for full
syntax.

### Radio and configuration

| Command | Description |
| --- | --- |
| `/help` | Show prompt command help. |
| `/version` | Show the installed version, like `mush --version`. |
| `/debug` (`/d`) | Toggle device log output. |
| `/trace NODE [HOPS]` (`/t`, `/traceroute`) | Request a traceroute. |
| `/location NODE` (`/loc`) | Request a node's position. |
| `/target ENTITY` | Select the destination for ordinary message lines. |
| `/hops [N]` | Show or set the default hop limit, from 0 to 7. |
| `/conf list` | List writable radio configuration options. |
| `/conf get OPTION` | Show a configuration value and any staged value. |
| `/conf set OPTION VALUE` | Validate and stage a change. |
| `/conf apply` | Write staged changes to the radio. |

Configuration option names accept snake_case and camelCase. Repeated values
must be JSON arrays, such as `[1, 2]`.

### Nodes

`/node` (`/n`, `/nodes`) without a subcommand shows the local node's saved
record.

| Command | Description |
| --- | --- |
| `/node ls [COUNT]` | List up to 100 recently heard nodes by default. |
| `/node show NAME` | Show a saved node's details. |
| `/node rm ID` | Remove a node from the local database. |
| `/node fav [NAME]` | List favorites, or toggle a node favorite on the radio and locally. |
| `/node dls` | Print the radio's live NodeDB as JSON. |
| `/node pull` | Copy the radio's live NodeDB to the local database. |
| `/node count` | Count saved nodes. |

### Channels

`/channel` (`/c`, `/chan`) lists channels. Channel management is available only
inside a live session.

| Command | Description |
| --- | --- |
| `/channel add INDEX NAME [PSK] [--random-psk]` | Add or replace a channel. |
| `/channel rm INDEX` | Delete a secondary channel. |
| `/channel mv INDEX1 INDEX2` | Swap two secondary channel slots. |

Channel indexes are 0 through 7. Channel names are limited to 10 characters.
The primary channel (0) cannot be deleted or moved. A supplied PSK can use the
`base64:` prefix; `--random-psk` creates and displays a 32-byte key.

### Packets and filters

`/filter` limits displayed live packets and `/packet` results. `/filter-out`
hides matching packets. Neither prevents packets from being saved.

```text
/filter from NORTH SOUTH
/filter channel LongFast
/filter portnum POSITION_APP
/filter-out portnum TELEMETRY_APP
/filter clear
```

Each filter provides `clear`, `from [NODE ...]`, `to [NODE ...]`, `channel
[CHANNEL ...]`, and `portnum [PORTNUM ...]`. Values within one field are
alternatives; active inclusion fields are combined. An exclusion applies only
when all of its configured fields match.

`/packet` (`/p`, `/pkt`, `/packets`) operates on the active filtered set:

| Command | Description |
| --- | --- |
| `/packet ls [COUNT]` | List the latest 100 matching packets by default. |
| `/packet show [ID] [--raw]` | Show packet details or raw JSON. |
| `/packet process` | Reprocess matching packets. |
| `/packet reprocess` | Reprocess every stored packet, ignoring filters. |
| `/packet import [--merge=append\|overwrite\|skip]` | Read one JSON packet from standard input. |
| `/packet portnums` | Count stored packets by port number. |
| `/packet count` | Count matching packets. |

## One-shot shell commands

These commands query the local database without connecting to a radio:

```text
mush ble-scan
mush node ls [COUNT]
mush node show NAME
mush node rm ID
mush node count
mush packet [FILTERS] list [COUNT]
mush packet [FILTERS] show [ID] [--raw]
mush packet [FILTERS] process
mush packet [FILTERS] import [--merge=append|overwrite|skip]
mush packet [FILTERS] portnums
mush packet [FILTERS] count
```

`mush packet` supports `--id`, `--msg-id`, `--limit`, `--portnum`,
`--from-id`, `--to-id`, `--id-start`, `--id-end`, `--rx-time-start`, and
`--rx-time-end`. For example:

```bash
mush packet --portnum POSITION_APP list 20
```

Use `mush COMMAND --help` for command-specific options and aliases.

## Data and privacy

The SQLite database contains the `node`, `packet`, and `replhistory` tables.
It can contain node identities, messages, telemetry, and locations. Treat it
as sensitive data. To back it up or move it, copy the database while `mush` is
not running.
