{"id":46401185,"url":"https://github.com/d4rkmen/plai","last_synced_at":"2026-03-06T12:01:09.349Z","repository":{"id":341766124,"uuid":"1169090650","full_name":"d4rkmen/plai","owner":"d4rkmen","description":"Standalone Meshtastic node for CardPuter ADV","archived":false,"fork":false,"pushed_at":"2026-03-05T13:13:41.000Z","size":48304,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-05T13:36:23.257Z","etag":null,"topics":["cardputer","esp32-s3","meshtastic"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/d4rkmen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-28T06:50:21.000Z","updated_at":"2026-03-05T13:13:44.000Z","dependencies_parsed_at":null,"dependency_job_id":"dc0dd442-70cf-441b-9437-d5c8146b659c","html_url":"https://github.com/d4rkmen/plai","commit_stats":null,"previous_names":["d4rkmen/plai"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/d4rkmen/plai","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d4rkmen%2Fplai","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d4rkmen%2Fplai/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d4rkmen%2Fplai/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d4rkmen%2Fplai/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/d4rkmen","download_url":"https://codeload.github.com/d4rkmen/plai/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d4rkmen%2Fplai/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30175862,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T11:48:51.886Z","status":"ssl_error","status_checked_at":"2026-03-06T11:48:51.460Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cardputer","esp32-s3","meshtastic"],"created_at":"2026-03-05T11:05:15.830Z","updated_at":"2026-03-06T12:01:09.339Z","avatar_url":"https://github.com/d4rkmen.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Plai\n\n**A standalone Meshtastic communicator for M5Stack CardPuter**\n\n\u003e _Plai_ is the Ukrainian word for a mountain trail — a reliable path for your data to travel when you're off the beaten track.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"pics/nodes_list.png\" width=\"480\" alt=\"Plai Node List\"\u003e\n\u003c/p\u003e\n\nMost Meshtastic nodes rely on a phone via BLE or WiFi. Plai takes a different approach: it turns the CardPuter into a **self-contained messaging terminal**. No phone required — just you, the LoRa CAP, and the keyboard.\n\n## Why Plai?\n\n- **Full standalone operation** — No WiFi, no BLE. Direct LoRa mesh communication with on-device UI.\n- **Unlimited message history** — The entire profile, message history, and node database live on the SD card. Storage is limited only by your card size.\n- **Swap and survive** — Reboot or switch firmwares without losing your place in the mesh. Everything persists on SD.\n- **Pro navigation** — PgUp / PgDown / Home / End for fast scrolling through long threads and node lists.\n- **Debug tools** — Built-in Packet Monitor (last 50 packets) and Trace Route history (last 50 attempts per node).\n- **Custom alerts** — Individual channel notifications with distinct sounds.\n- **Fully compatible** with Meshtastic network v2.7+\n- **Ping auto-reply**: respond automatically when someone #ping's the channel\n- **New node greetings**: send a welcome broadcast to the channel and/or a Direct Message when a new node appears\n\n## Apps\n\n### Nodes\n\nFull node management with up to 1000 nodes persisted on SD card.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"pics/nodes.png\" width=\"480\" alt=\"Node Detail\"\u003e\n  \u003cimg src=\"pics/nodes_list.png\" width=\"480\" alt=\"Node List\"\u003e\n\u003c/p\u003e\n\n- Node list with signal strength, hops, battery, role, encryption indicators\n- 8 sorting modes (name, role, signal, hops, last heard, favorites, etc.) _hotkey_ for sorting [1..8], [TAB] to select sorting mode\n- Relay node display — see which node relayed each packet _hotkey_ [R] to jump to relay node\n- Favorite marking and quick-jump navigation _hotkey_ [F] to toggle favorite\n- Node detail view with hardware model, position, and metrics _hotkey_ [Fn] + [ENTER] to open\n- Direct Messages _hotkey_ [ENTER] to open\n- Traceroute _hotkey_ [T] to open recent traceroute logs. [Fn] + [T] to start traceroute immediately\n\n#### Direct Messages\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"pics/nodes_dm.png\" width=\"480\" alt=\"Direct Messages\"\u003e\n  \u003cimg src=\"pics/input.png\" width=\"480\" alt=\"Message Input\"\u003e\n\u003c/p\u003e\n\n- Direct messaging with delivery status (pending → sent → ACK → delivered → failed)\n- Channel invitation _hotkey_ [I] — invite the node to a channel (sends `#invite name=key` DM)\n- Full keyboard input with Cyrillic layout support\n- File-backed message history on SD card\n- Clear chat _hotkey_ [BACKSPACE] to clear all messages\n- Hold [CTRL] to display message info (timestamp, will be more soon...)\n\n#### Traceroute\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"pics/nodes_tr_log.png\" width=\"480\" alt=\"Traceroute Log\"\u003e\n  \u003cimg src=\"pics/nodes_tr_details.png\" width=\"480\" alt=\"Traceroute Details\"\u003e\n\u003c/p\u003e\n\n- Traceroute with hop-by-hop detail, round-trip duration, and SNR at each hop\n- Last 50 traceroute attempts stored per node\n- Visual route map with color-coded signal quality\n- Press [T] to start new traceroute\n\n### Channels\n\nMulti-channel group chat supporting up to 8 channels.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"pics/channels.png\" width=\"480\" alt=\"Channel Chat\"\u003e\n  \u003cimg src=\"pics/channels_list.png\" width=\"480\" alt=\"Channel List\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"pics/channel_chat_info.png\" width=\"480\" alt=\"Channel Chat Info\"\u003e\n\u003c/p\u003e\n\n- Channel list with unread message counts\n- Channel creation _hotkey_ [Fn] + [SPACE] to open channel creation dialog\n- Channel editing _hotkey_ [Fn] + [ENTER] to open channel editing dialog\n- Channel chat _hotkey_ [ENTER] to open channel chat\n- Individual notification sounds per channel\n\n#### New node greetings \u0026 #ping auto-reply\n\nMany of us send \"test test\" and get no reply. Now Plai can reply automatically when you add **#ping** in your channel message — no more wondering if anyone's listening.\n\n- **#ping auto-reply** — Add `#ping` anywhere in a channel message; Plai responds with a configurable template. Macros: `#short`, `#long`, `#id`, `#hops`, `#snr`, `#rssi`\n- **New node greetings** — When a node appears for the first time (after receiving their NodeInfo), Plai can send a welcome broadcast to the channel and/or a Direct Message. Same macros apply.\n- **Per-channel settings** — Each of the 8 channels has its own greeting and ping reply templates.\n\nThere are predefined templates for the greetings and ping reply. You can use them or enter your own custom text, holding [Fn] key.\n\nExample: _\"Look who is here! #long, welcome to HAM Community of Smartwill city. I can see you with #hops hops #snr/#rssi\"_\n\n#### Channel invitation\n\nShare a channel with another node via Direct Message.\n\n- **Sending** — In DM with a node, press [I]. Select a channel; Plai sends a DM in format `#invite name=base64_psk` (name max 11 chars, key base64-encoded). If the node has no public key, a confirmation is shown before sending unencrypted.\n- **Receiving** — Enable **Settings → Security → Invitations**. When a DM starts with `#invite ` and matches `#invite channel_name=base64_psk`, Plai creates a new channel at the first free slot. Duplicate channels (same name and key) are ignored.\n- Requires at least one free channel slot to accept an invitation.\n\n### Monitor\n\nLive radio packet feed for debugging and network analysis.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"pics/monitor.png\" width=\"480\" alt=\"Packet Detail\"\u003e\n  \u003cimg src=\"pics/monitor_list.png\" width=\"480\" alt=\"Packet List\"\u003e\n\u003c/p\u003e\n\n- Real-time TX/RX packet display with port labels (TEXT, POS, NODE, TELE, ROUT, TRAC, etc.)\n- Color-coded direction, node badges, and SNR indicators\n- Color-coded packet ID for easy relay identification\n- From/To node name resolution from NodeDB\n- Scrollable packet list with detail drill-down view\n- Last 50 packets in a static ring buffer\n- Select first item for autoscroll\n\n### Settings\n\nComplete device and mesh configuration stores in NVS. You can export and import settings to SD card for backup and restore it later.\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003e\u003cspan style=\"color:red;\"\u003e\u0026#x26A0;️\u003c/span\u003e \u003cspan style=\"color:red;\"\u003eMesh keys are in NVS. Don't forget to backup them to SD card if you want to keep them after firmware update!\u003c/span\u003e\u003c/b\u003e\n\u003c/p\u003e\n\nNode database and chat history are stored on SD card and not affected by firmware updates.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"pics/settings.png\" width=\"480\" alt=\"Settings\"\u003e\n\u003c/p\u003e\n\n- System: brightness, volume, timezone\n- LoRa: region, modem preset, TX power, hop limit\n- Security: channel PSK management, invitations (auto-add channels from `#invite` DMs)\n- Node info: name, short name, role\n- Position: GPS enable, fixed position, broadcast interval\n- Telemetry: device metrics broadcast\n- Export/Import settings to SD card\n- Clear all nodes\n\n## Hardware\n\n### Required\n\n| Component                 | Description                              |\n| ------------------------- | ---------------------------------------- |\n| **M5Stack CardPuter ADV** | ESP32-S3 portable terminal with keyboard |\n| **LoRa CAP**              | M5Stack SX1262 LoRa module (868/915 MHz) |\n| **SD Card**               | For profile, messages, and node database |\n\n## Install\n\nBeta version is available in **M5Apps** (Installer → Cloud → Beta tests).\n\nStandalone version will be added to **M5Burner** soon.\n\n\u003e Look for M5Apps in M5Burner.\n\n## Mesh Protocol\n\nBuilt from scratch on ESP-IDF — not a fork of the Meshtastic firmware.\n\n- **Encryption**: AES-CTR with channel PSK, X25519 public-key cryptography\n- **Multi-channel**: Up to 8 channels with individual PSKs\n- **Routing**: Hop-limit flooding (1–7 hops) with Meshtastic-compatible duplicate detection\n- **Reliability**: ACK/NACK with automatic retries, implicit ACK via rebroadcast\n- **Priority TX queue**: ACK \u003e Routing \u003e Admin \u003e Reliable \u003e Default \u003e Background\n- **Duty cycle**: Channel and air utilization tracking\n- **Multi-region**: US, EU_433, EU_868, CN, JP, ANZ, KR, TW, RU, IN, and more\n- **Packet encoding**: Nanopb (Protocol Buffers) for full Meshtastic wire compatibility\n\n## Building from Source\n\n### Prerequisites\n\n- [ESP-IDF v5.5.x](https://docs.espressif.com/projects/esp-idf/en/v5.5.2/esp32s3/get-started/)\n- ESP32-S3 target\n\n### Build \u0026 Flash\n\n```bash\nidf.py set-target esp32s3\nidf.py build\nidf.py -p COMx flash monitor\n```\n\n### HAL Configuration\n\nHardware components can be individually toggled via menuconfig:\n\n```bash\nidf.py menuconfig\n# Navigate to: HAL Configuration\n```\n\n| Option             | Default | Description                   |\n| ------------------ | ------- | ----------------------------- |\n| `HAL_USE_DISPLAY`  | on      | ST7789 display via LovyanGFX  |\n| `HAL_USE_KEYBOARD` | on      | Keyboard input (requires I2C) |\n| `HAL_USE_RADIO`    | on      | SX1262 LoRa radio             |\n| `HAL_USE_SDCARD`   | on      | SD card (FAT)                 |\n| `HAL_USE_GPS`      | on      | ATGM336H GPS                  |\n| `HAL_USE_SPEAKER`  | on      | I2S audio output              |\n| `HAL_USE_LED`      | on      | WS2812 RGB LED                |\n| `HAL_USE_BAT`      | on      | Battery voltage monitor       |\n| `HAL_USE_I2C`      | on      | I2C master bus                |\n| `HAL_USE_BUTTON`   | on      | Home button                   |\n| `HAL_USE_USB`      | on      | USB MSC host                  |\n| `HAL_USE_WIFI`     | on      | WiFi                          |\n| `HAL_USE_BLE`      | on      | Bluetooth Low Energy          |\n\n## Project Structure\n\n```\nPlai/\n├── main/\n│   ├── apps/                  # Application layer\n│   │   ├── launcher/          # Home screen \u0026 system bar\n│   │   ├── app_nodes/         # Node list, DM, traceroute\n│   │   ├── app_channels/      # Channel group chat\n│   │   ├── app_monitor/       # Live packet feed\n│   │   ├── app_settings/      # Configuration UI\n│   │   └── utils/             # Shared UI components\n│   ├── hal/                   # Hardware Abstraction Layer\n│   │   ├── hal.h              # Base HAL class\n│   │   ├── hal_cardputer.*    # M5Cardputer implementation\n│   │   ├── display/           # LovyanGFX display driver\n│   │   ├── keyboard/          # TCA8418 / IOMatrix drivers\n│   │   ├── radio/             # SX1262 LoRa driver\n│   │   └── ...                # GPS, speaker, LED, battery, etc.\n│   ├── mesh/                  # Meshtastic protocol\n│   │   ├── mesh_service.*     # Core mesh service\n│   │   ├── node_db.*          # Node database (SD-backed)\n│   │   ├── mesh_data.*        # Message store \u0026 packet log\n│   │   └── packet_router.*    # Priority TX/RX queues\n│   ├── meshtastic/            # Protobuf definitions (Nanopb)\n│   ├── settings/              # NVS settings with cache\n│   └── main.cpp               # Entry point\n├── components/\n│   ├── LovyanGFX/             # Display graphics library\n│   ├── mooncake/              # App framework\n│   └── Nanopb/                # Protocol Buffers\n└── Kconfig.projbuild          # menuconfig HAL options\n```\n\n## Credits\n\n- Fonts: [efont](https://openlab.ring.gr.jp/efont/) Unicode bitmap fonts from the Linux distribution\n- Icons: Free icons by [Icons8](https://icons8.com)\n- Platform: [M5Stack](https://m5stack.com/) M5Cardputer\n\n## License\n\nThis project is licensed under the [GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.html) — see [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fd4rkmen%2Fplai","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fd4rkmen%2Fplai","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fd4rkmen%2Fplai/lists"}