TMAG 是一套使用 Node.js 打造的 Meshtastic → APRS Gateway,整合了 CallMesh 平台驗證、Mapping 同步、APRS uplink 與遙測統計。專案同時提供:
- CLI:適合在 macOS / Linux / Windows(或 Raspberry Pi)上以無頭模式執行,能透過 Meshtastic TCP 或 Serial 連線將封包轉換成 APRS uplink 並回報 CallMesh。
- Electron 桌面版:提供即時儀表板、封包/節點追蹤、APRS 狀態檢視等 GUI 功能,並支援 TCP / Serial 模式與裝置清單選取。
✅ 只要準備 CallMesh API Key 與 Meshtastic 連線(TCP 或 Serial),就能在任何支援 Node.js 的平台啟動整個 Gateway。
- Meshtastic 監控:解析 Meshtastic TCP / Serial 流中的 protobuf 封包,摘要顯示節點、SNR/RSSI、Hops、座標等資訊。
- CallMesh 整合:透過 Heartbeat/Mapping/Provision API 取得節點配置與 APRS 參數,並在 Key 驗證失敗時鎖定系統。
- APRS Uplink:依 Mapping 決定呼號、符號與註解,上傳位置/狀態/遙測資料到 APRS-IS,具備 Beacon、Status、Telemetry 定時器與互斥上傳控制。
- TenManMap 轉發:驗證成功後,會將 Meshtastic 摘要同步到 TenManMap 及其合作夥伴,佇列與重試機制常駐執行。
- @cm 自動回覆機器人:在 CH2
Signal Test頻道輸入@cm ...會觸發機器人,由最近(含本機)節點自動回覆測試訊息;需保持 TenManMap 分享為啟用狀態,停用分享時該機器人無法運作。 - 遙測統計:計算近 10 分鐘的封包數量、上傳比率、類型分佈(Position / Message / Control)。
- 彈性連線模式:CLI 與 GUI 皆支援
tcp://與serial://目標,可自動判讀serial:///dev/ttyUSB0類型字串並套用鮑率。 - 跨平台部署:可自行打包 macOS / Windows / Linux x64 CLI 或 Desktop 版;CLI 同時支援自動重連。
- 穩定時間戳:Telemetry 紀錄寫入時會使用收包當下的時間戳,避免裝置 RTC 漂移造成前端區間掛零。
- 節點資料庫共用:內建
nodeDatabase集中維護節點長短名、模型、座標等資訊,CLI / Electron / Web 透過node、node-snapshot事件共享同一份資料,節點清單支援座標搜尋與距離顯示。 - 訊息與 Relay 體驗:GUI/Web 會持久化 CH0~CH3 文字訊息(含節點暱稱、最後轉發資訊),同時提供 Relay 推測提示 UI,能追蹤候選節點與推測理由。
- APRS 去重:橋接層內建三層快取(feed 3 小時、本地與座標 30 秒),即使 Meshtastic 網路延遲 30 秒~10 分鐘,也能避免不同站重複 uplink 造成位置回朔或浪費 APRS-IS 配額。
- Node.js 22 以上(需支援內建
node:sqlite) - Meshtastic 裝置或 Gateway(TCP API 或 Serial 連線)
- CallMesh 平台有效的 API Key(環境變數
CALLMESH_API_KEY) - (若使用 APRS)穩定的網際網路連線
- (若使用 Serial)系統需對裝置節點具有讀寫權限,例如將使用者加入
dialout或uucp群組
# 1. 取得專案原始碼
git clone https://github.com/toodi0418/CMClient.git
cd CMClient
# 2. 安裝相依套件(CLI / GUI 共用)
npm install-
macOS / Linux
建議安裝 nvm:curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash source ~/.nvm/nvm.sh nvm install 22 nvm use 22
完成後
node -v、npm -v應該能顯示版本號。 -
Windows
前往 Node.js 官方網站 下載 Node.js 22 LTS 安裝程式,依指示完成安裝後重新開啟終端機(PowerShell / CMD)。
驗證:node -v npm -v
- 使用 nvm(macOS / Linux)
nvm install 22 --latest-npm # 安裝或更新 22.x 最新版 nvm alias default 22 # (可選)設為預設版本 nvm use 22 node -v && npm -v # 確認版本
- 使用 Homebrew(macOS)
brew update brew upgrade node@22 echo 'export PATH="/usr/local/opt/node@22/bin:$PATH"' >> ~/.zshrc source ~/.zshrc node -v && npm -v
- Windows
- 重新下載並執行 Node.js 22 LTS 安裝程式;或
- 若使用 nvm-windows,可執行:
nvm install 22.21.1 nvm use 22.21.1 node -v npm -v
export CALLMESH_API_KEY="你的 CallMesh API Key"
# 可選:變更快取與驗證檔案位置
export CALLMESH_VERIFICATION_FILE=~/.config/callmesh/monitor.json
export CALLMESH_ARTIFACTS_DIR=~/.config/callmesh/
# TenManMap 開關(預設啟用)
export TENMAN_DISABLE=1 # 設為 1 / true / yes / on 時停用 TenManMap 推播驗證成功後,TMAG 會沿用 CallMesh 的授權資訊,將 Meshtastic 之摘要資料同步至 TenManMap(以下稱「本服務」)。若你同意分享,本服務可能將部分資料提供予合作夥伴(例如共同營運、託管與分析服務供應商),以支援服務運作。
-
同步範圍
與節點狀態與現地觀測相關之摘要資訊,例如:位置(含時間戳)、遙測摘要、訊息摘要欄位、以及必要的連線/傳輸品質指標(如 RSSI/SNR、hop、節點狀態)。 -
使用目的
用於以下目的之必要範圍:- 服務提供與維運(含故障排除、通知、容量規劃)
- 效能與可靠度監測(含品質統計、異常偵測)
- 資安維護(含濫用偵測、稽核紀錄)
- 統計分析與研究(以彙總或去識別化方式為原則)
- 依營運所需之功能開發與產品改善
(若需將資料用於超出上述目的之新用途,將另行告知並取得必要同意)
-
分享對象
- TenManMap:用於本服務之提供與維運。
- 合作夥伴:限於協助本服務運作所必要之第三方(例如:雲端託管、資料儲存、訊息推播、監控分析、共同營運單位)。
- 依法令要求:於法律要求或有權機關合法程序下,可能提供予主管機關或其他有權單位。
-
保留期間
為達成上述目的所必要之期間,或依法律/合約要求之期間保存。到期後將刪除、匿名化或以其他方式降低識別風險(依實際作業與法規要求)。 -
你的選擇
你可選擇是否同步/分享:- 以環境變數停用:
TENMAN_DISABLE=1(支援true/yes/on) - CLI 參數停用:
--no-share-with-tenmanmap - 桌面版:設定頁底部之分享開關
停用後,本服務將不再接收新的同步資料;已產生之資料仍可能因備援、稽核或法規要求而於合理期間內保留。
- 以環境變數停用:
-
資料安全
我們採取合理之技術與管理措施(例如存取控管、傳輸保護、稽核與最小權限)以降低風險,但仍無法保證在所有情境下絕對安全。 -
跨區處理
資料可能在不同法域之間處理與儲存。我們將依適用法規與合理措施管理跨境處理風險。 -
權利行使與聯絡方式
如需查詢、請求刪除、或停止同步/處理,請依你的部署流程聯絡維運窗口或系統管理者;若你是自行部署者,請由部署者提供對應的聯絡方式或工單管道。 -
條款更新
本段內容可能依實際作業調整。我們會在版本更新說明、文件頁面或公告渠道揭露更新內容與生效日期。
若你的環境對資料揭露有額外規範,請在啟動前評估是否需要停用同步。更多結構與欄位示意請參考 new-api.md。
cd CMClient
git pull # 取得最新程式
npm install # 套件若有更新會同步安裝更新完成後即可照原流程啟動 npm start / npm run desktop 或重新執行 npm run build:* 產出新版套裝。
- 前往最新 Release:https://github.com/toodi0418/CMClient/releases
- 下載目標平台的 ZIP(GUI 或 CLI)。
- 解壓後直接覆蓋舊版本或以全新資料夾啟動;設定檔(CallMesh API Key、Mapping artifacts)仍沿用原本位置。
提醒:更新前請確認既有執行中的 CLI / GUI 已中止,避免 APRS uplink flowId 重複。
樹莓派預設沒有 Node.js,可依下列步驟一次完成:
# 系統更新 + 安裝 git / curl
sudo apt update && sudo apt install -y git curl
# 安裝 nvm 並使用 Node.js 22(建議 LTS)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash
source ~/.nvm/nvm.sh
nvm install 22
nvm use 22
# 取得 TMAG 並安裝依賴
git clone https://github.com/toodi0418/CMClient.git
cd CMClient
npm install
# 匯入 CallMesh API Key 後直接啟動 CLI
export CALLMESH_API_KEY="你的 Key"
node src/index.js --host <節點ip> --port 4403若想在 Pi 上打包成單一執行檔,可再執行:
npx pkg src/index.js \
--config package.json \
--targets node22-linux-arm64 \
--compress Brotli --public \
--output tmag-cli-linux-arm64若要以服務方式常駐並開機自動啟動,可使用 scripts/manage-service-linux.sh(會詢問 API Key,可重裝、重設 Key 或解除安裝)。
- 互動式選單:
bash scripts/manage-service-linux.sh - 直接指令:
bash scripts/manage-service-linux.sh install|set-key|start|stop|restart|status|enable|disable|logs|uninstall - 設定檔:
/etc/callmesh/callmesh.env(含CALLMESH_API_KEY、TMAG_ARGS) - 服務名稱:
callmesh-client.service - 查看最近 log:
bash scripts/manage-service-linux.sh logs 200 - 檢查/更新版本:
bash scripts/manage-service-linux.sh check-update、bash scripts/manage-service-linux.sh update(成功後自動重啟服務) - 自動更新:
bash scripts/manage-service-linux.sh auto-update-enable(預設每日 04:00,隨機延遲 ≤30 分鐘,可改環境變數UPDATE_SCHEDULE);停用/查詢:auto-update-disable/auto-update-status - 安裝時可選擇 TCP/IP 或 Serial;選 Serial 時會列出 /dev/ttyUSB* / /dev/ttyACM* / /dev/ttyS* / /dev/ttyAMA* 供選擇,並可輸入自訂路徑與鮑率
- 缺少 git / Node.js 22 會自動嘗試安裝(透過套件管理器或
scripts/install-linux.sh) - 全自動一行安裝(安裝依賴 + 建立服務,會互動詢問 API Key,會自動處理已存在目錄):
bash -c "curl -fsSL https://raw.githubusercontent.com/toodi0418/CMClient/main/scripts/bootstrap-linux.sh | bash"- 自訂目錄:
TMAG_DIR=/opt/CMClient;自訂分支:TMAG_BRANCH=main - 若無法互動輸入,可提前設定
CALLMESH_API_KEY=<你的 Key>
- 自訂目錄:
- 安裝完成後會寫入
/etc/profile.d/callmesh.sh(TMAG_HOME=<安裝路徑>),並建立快捷指令/usr/local/bin/callmesh-service與短指令/usr/local/bin/tmag,在任何目錄直接執行callmesh-service或tmag即可呼叫管理選單
CLI 預設會驗證 CallMesh API Key、啟動 heartbeat 與 Mapping 同步,再連線 Meshtastic 目標(TCP / Serial)並自動轉發到 APRS。
node src/index.js --host 172.16.8.91 --port 4403若裝置透過 USB / Serial 連線,也可以:
node src/index.js --connection serial --serial-path /dev/ttyUSB0 --serial-baud 115200
# 或直接使用 host=serial:/// 路徑(鮑率可搭配查詢字串或 @ 參數覆寫)
node src/index.js --host serial:///dev/ttyUSB0使用 pkg 打包後的 CLI 執行檔也支援完整的指令列參數,可透過 --help 查看:
./tmag-cli --help
Commands:
tmag-cli discover 自動搜尋區網內的 Meshtastic TCP 裝置
tmag-cli 連線並監看 Meshtastic 封包 [default]
Options:
--version Show version number [boolean]
--help Show help [boolean]
-K, --api-key CallMesh API Key(若未帶入將使用環境變數 CALLMESH_API_KEY)
[string]
-H, --host Meshtastic TCP 伺服器主機位置[string] [default: "127.0.0.1"]
-P, --port Meshtastic TCP 伺服器埠號 [number] [default: 4403]
-C, --connection Meshtastic 連線方式(未指定時會依 host 判斷)
[choices: "tcp", "serial"]
--serial-path Serial 連線時的裝置路徑(例如 /dev/ttyUSB0) [string]
--serial-baud Serial 連線時的鮑率 [number] [default: 115200]
-m, --max-length 允許的最大封包大小 (位元組) [number] [default: 512]
-r, --show-raw 在摘要輸出時同時列印 payload 十六進位
[boolean] [default: false]
--web-ui 啟用內建 Web Dashboard(預設關閉)
[boolean] [default: false]
-f, --format 輸出格式:summary 顯示表格,json 顯示完整資料
[choices: "summary", "json"] [default: "summary"]
-p, --pretty 搭配 --format json 時使用縮排輸出 [boolean] [default: true]
--no-share-with-tenmanmap 停用 TenManMap 分享 [boolean] [default: false]常用選項:
| 參數 | 預設 | 說明 |
|---|---|---|
--connection, -C |
自動偵測 | 指定 tcp 或 serial;未設定時會依 --host 內容判斷。 |
--host, -H |
127.0.0.1 |
Meshtastic 目標,可填入 IP(如 192.168.1.50)或 serial:///dev/ttyUSB0。 |
--port, -P |
4403 |
TCP 模式使用的連接埠。 |
--serial-path |
- | Serial 模式的裝置路徑(若 --host 已使用 serial:// 可省略)。 |
--serial-baud |
115200 |
Serial 模式鮑率。 |
--format, -f |
summary |
summary 表格、json 輸出完整 protobuf 內容。 |
--show-raw, -r |
false |
在 summary 下同時顯示十六進位 payload。 |
--web-ui |
false |
啟用內建 Web Dashboard(HTTP + SSE 伺服器)。 |
--no-share-with-tenmanmap |
false |
停用 TenManMap 分享。 |
--discover |
- | 搜尋區網內 _meshtastic._tcp 裝置。 |
CLI 具備自動重連:若 TCP 連線中斷會每 30 秒重試一次,直到 Ctrl+C 終止。
仍可透過 CLI 單獨執行 CallMesh API:
# 同步 Heartbeat + Mapping
node src/index.js callmesh sync \
--state-file ~/.config/callmesh/state.json \
--mappings-output ~/.config/callmesh/mappings.json指令詳情可見 docs/callmesh-client.md。
- 改善動機:Meshtastic 網路偶爾塞住,封包可能延遲 30 秒到 10 分鐘才送到另一個站台。若每站都再次 uplink,同一筆位置會在 APRS-IS 上「倒退」,也浪費配額。
- 三層快取(同步寫入
callmesh-data.sqlite,重啟會重新載入並套用 TTL)aprsPacketCache/aprsCallsignSummary:記錄 24 小時內 APRS-IS feed 已出現的 payload/呼號,只要再看到相同呼號+payload,就標記seen-on-feed並跳過上傳。aprsLocalTxHistory:保留本地 uplink 的 payload 30 秒,用來擋掉 UI/排程誤觸造成的重送。aprsLastPositionDigest:同一 Mesh ID 30 秒內座標+符號+註解完全相同就不再上傳,避免 GPS 靜止時不停重複。
- 使用方式:任何實例都可開
http://<host>:7080/debug檢視aprsDedup,快速判斷某筆為何被擋。例如packetCache命中代表 feed 已有、localTxHistory命中代表 30 秒內剛由本機上傳;這些欄位同時鏡射callmesh-data.sqlite內的aprs_*表,可跨重啟追蹤。 - 自訂與除錯:
TMAG_APRS_FEED_FILTER/TMAG_APRS_FEED_RADIUS_KM用來覆寫監聽範圍,未設定時會依 Provision 座標自動套用#filter r/<lat>/<lon>/300。TMAG_APRS_LOG_VERBOSE=1可恢復完整的 APRS tx/rx/keepalive log,預設靜音避免噴 log。
npm run desktopGUI 提供:
- 連線狀態、APRS 伺服器與登錄顯示
- 封包列表與 Mapping 封包追蹤(含「已上傳/待上傳」狀態)
- CallMesh Log、APRS Log 與遙測統計圖表
- 設定頁:輸入 CallMesh API Key、調整 APRS Beacon 間隔、掃描 Meshtastic 裝置,並可切換 TCP / Serial 模式與選擇 Serial 裝置
首次啟動需輸入並驗證 CallMesh API Key,通過後即可連線 Meshtastic。
- 遙測時間校正(升級前/JSONL):若早期資料受裝置時間影響,可在升級至 SQLite 版本前於專案根目錄執行
腳本會將每筆紀錄的
node scripts/fix-telemetry-timestamps.js ~/.config/callmesh/telemetry-records.jsonltimestampMs/sampleTimeMs/telemetry.timeMs對齊收包時刻,並保留.bak備份。 - 遙測資料儲存:自 v0.2.23 起改採
~/.config/callmesh/telemetry-records.sqlite(SQLite);首次啟動會自動匯入舊版 JSONL 並將原檔更名為.migrated。 - 遙測歷史復原:若 SQLite 已寫入新資料、但仍要再次匯入
telemetry-records.jsonl.migrated,只要在程式關閉後把它改回telemetry-records.jsonl(CLI 路徑~/.config/callmesh/,GUI 路徑~/Library/Application Support/TMAG Monitor/callmesh/),下次啟動會再次把整份 JSON 匯入資料庫,完成後檔案會自動改回.migrated備份。 - 共用資料庫:節點快照、Mapping/Provision 快取、訊息紀錄、Relay 統計與 APRS 去重快取統一儲存在
~/.config/callmesh/callmesh-data.sqlite(新增aprs_packet_cache/aprs_local_tx/aprs_callsign_summary/aprs_position_digest),升級時會自動匯入舊版node-database.json、message-log.jsonl、relay-link-stats.json。 - 打包工具:
scripts/pack-cli.sh、scripts/pack-desktop.sh可快速產出 CLI / GUI 可攜版(需安裝pkg、electron-packager)。
- CLI 旗標
在不啟動監控流程的情況下,會直接清空
node src/index.js --clear-nodedb
callmesh-data.sqlite的nodes與relay_stats表,並移除舊版node-database.json/relay-link-stats.json,完成後立即結束程式。指令會同時掃描 CLI 預設資料夾與 Electron(含開發模式)使用的userData路徑,macOS 例如~/Library/Application Support/Electron/callmesh/。 - Electron 桌面版
- 切換到「節點資料庫」分頁。
- 點擊右上角「清除節點資料庫」,會同時清空記憶體快取、
callmesh-data.sqlite中的nodes表,以及 relay link-state(relay_stats/relay-link-stats.json)。
- CLI / 服務模式
- 停止 TMAG 程式。
- 執行下列指令(若有自訂
CALLMESH_ARTIFACTS_DIR,請換成對應路徑):或直接刪除sqlite3 ~/.config/callmesh/callmesh-data.sqlite "DELETE FROM nodes; VACUUM;"
callmesh-data.sqlite,下次啟動時會自動重建並重新同步 Mapping / Provision。
| 目標 | 指令 | 輸出位置 |
|---|---|---|
| macOS CLI | npm run build:mac-cli |
dist/cli/tmag-cli |
| Windows x64 GUI | npm run build:win |
dist/TMAG Monitor-win32-x64/ |
| Linux x64 GUI | npm run build:linux |
dist/TMAG Monitor-linux-x64/ |
macOS 無法交叉編譯 Linux/ARM 執行檔,請在目標 Linux 主機(例如樹莓派)上執行:
git clone https://github.com/toodi0418/CMClient.git
cd CMClient
npm install
npx pkg src/index.js \
--config package.json \
--targets node22-linux-arm64 \
--compress Brotli --public \
--output tmag-cli-linux-arm64或針對 64 位元 Pi OS 使用 --targets node22-linux-arm64(Release 目前提供 macOS / Windows / Linux x64 / Linux arm64 版本)。
官方提供的 CLI 執行檔均以 Node.js 22 打包,請確保目標環境允許執行對應的靜態 binary。
GitHub Actions 會自動執行 Build & Publish Docker Image workflow,並把映像推送到 GitHub Container Registry(GHCR)。本專案的映像位置是 ghcr.io/toodi0418/cmclient:<tag>(例如 ghcr.io/toodi0418/cmclient:latest),現已提供 linux/amd64、linux/arm64、linux/arm/v7 三種架構;基底映像為 node:22-bookworm-slim,容器內預設即為 Node.js 22。常見流程如下:
-
取得映像
- 從 GHCR 下載:
docker pull ghcr.io/toodi0418/cmclient:latest
- 或在原始碼目錄自行建置:
docker build -t callmesh-client . - 若已透過
docker save callmesh-client:latest -o callmesh-client.tar匯出,可在其他主機使用docker load -i callmesh-client.tar匯入。
- 從 GHCR 下載:
-
準備環境與 compose
- 根目錄已有
.env範本,填入CALLMESH_API_KEY、MESHTASTIC_HOST、TMAG_WEB_PORT等參數。 docker-compose.yml會:- 以
.env中的參數建置/啟動callmesh-client; - 將
/data/callmesh透過 volumecallmesh-data持久化 CallMesh 驗證、歷史遙測與訊息記錄; - 預設開啟 Web Dashboard(7080 埠),如需停用可把
TMAG_WEB_DASHBOARD設為0。
- 以
- 根目錄已有
-
啟動
docker compose up -d --build
- 變更設定後重新載入:`docker compose up -d`。
- 查看日誌:`docker compose logs -f`.
- 需改用 Serial 裝置時,可在 `docker-compose.yml` 新增:
```yaml
devices:
- /dev/ttyUSB0:/dev/ttyUSB0
command:
- npm
- start
- --
- --connection
- serial
- --serial-path
- /dev/ttyUSB0
- --serial-baud
- "115200"
```
4. **群暉 NAS 提示**
- 在 DSM「Container Manager」建立專案時,直接匯入 repo 內的 `docker-compose.yml`,並把 `.env` 一併上傳。
- 若想把資料存進共享資料夾,可將 compose 內的 volume 改為 `./data:/data/callmesh`,確保資料夾具有讀寫權限。
- Serial 連線需要在 Container Manager → 編輯容器 → 裝置中勾選 `/dev/ttyUSB*`,同時於 compose 增加 `devices`。
- 開放 Web Dashboard 時,務必在 DSM 防火牆放行 `TMAG_WEB_PORT`(預設 7080)。
#### `.env` 範本與環境變數
```env
CALLMESH_API_KEY=cm_xxxxx # CallMesh 發放的 API Key,沒有就會一直卡在 locked
MESHTASTIC_HOST=meshtastic.local # 目標 Meshtastic TCP host,可填 IP 或 mDNS 名稱
MESHTASTIC_PORT=4403 # Meshtastic TCP 監聽 port,預設 4403
TMAG_WEB_PORT=7080 # Web Dashboard 映射到主機的 port
TMAG_WEB_DASHBOARD=1 # 設為 0 可完全關閉 Web Dashboard
TENMAN_DISABLE=0 # 1=停用 TenManMap 上傳
AUTO_UPDATE=1 # 1=啟動時自動 git pull 指定分支(main/dev)
AUTO_UPDATE_BRANCH=main # main(預設)或 dev,其他值會回退 main
AUTO_UPDATE_WORKDIR=/data/callmesh/app-src
AUTO_UPDATE_REPO=https://github.com/toodi0418/CMClient.git
AUTO_UPDATE_POLL_SECONDS=300 # 多少秒檢查一次遠端更新
.env會被docker-compose.yml自動讀取;如果部署在會commit 的環境,建議以cp .env .env.local再編輯以免誤傳敏感資訊。CALLMESH_API_KEY必填;MESHTASTIC_HOST/PORT需能被容器解析與連線,若 Meshtastic 裝置在同一主機可直接填host.docker.internal或本機 IP。- 修改
.env內容後重新套用docker compose up -d.
- 建置/更新映像:在 repo 根目錄執行
docker compose build(或docker compose pull直接拉 GHCR 版本)。 - 啟動服務:
docker compose up -d --build(會依AUTO_UPDATE決定是否在 entrypoint 重新 git pull)。 - 查看狀態/日誌:
docker compose logs -f callmesh-client,確認 CallMesh 驗證、Meshtastic 連線與 APRS 流程是否正常。 - 重啟或變更設定:更新
.env→docker compose up -d;如需乾淨重建可先docker compose down再up -d. - 除錯:
docker exec -it callmesh-client /bin/bash進入容器,可檢查/data/callmesh內的 artifacts 或執行npm start -- --help。
- Web Dashboard:啟動後在瀏覽器輸入
http://<部署主機IP>:<TMAG_WEB_PORT>(預設 7080),首次載入會要求 CallMesh API Key 通過驗證後才顯示資料。 - Meshtastic TCP:容器會依
.env的MESHTASTIC_HOST/PORT直接連線,請確保該 host/port 對 Docker network 可達;若目標在同一臺主機,可填host.docker.internal或實際 IP。 - Meshtastic Serial:在
docker-compose.yml的 service 內加入並確認宿主機已授權 Docker 存取該裝置(Linux 可能需要將使用者加入devices: - /dev/ttyUSB0:/dev/ttyUSB0 command: - npm - start - -- - --connection - serial - --serial-path - /dev/ttyUSB0 - --serial-baud - "115200"
dialout)。 - CallMesh / TenManMap:容器會將 artifacts 寫入 volume
/data/callmesh,可把callmesh-data綁到實體資料夾以便備份或跨版本沿用,確保 Key/Mapping/遙測都能持續。 - 映像更新:官方 GHCR 映像(
ghcr.io/toodi0418/cmclient:<tag>)基底為node:22-bookworm-slim。若要套用最新 runtime,請先docker compose pull(或docker pull ghcr.io/toodi0418/cmclient:latest)再docker compose up -d --build;若自己 build,記得在成功後執行docker compose up -d以重建容器。
容器本身在 docker-compose.yml 內已設定 restart: unless-stopped,只要 Docker daemon 在開機時啟動,就會自動還原 TMAG 服務。常見做法:
- 確認 Docker 服務開機自啟:
(或依系統使用
sudo systemctl enable --now dockerservice docker start) - 開機後若 Docker daemon 先啟動,compose 也會自動復原上一個狀態;若需要更明確的控制(例如先載入
.env、跑docker compose up -d)可加上 systemd unit,下方提供範例。
- 複製範例 unit 檔並依實際路徑調整
WorkingDirectory=(需指向含docker-compose.yml的資料夾):(或以sudo cp systemd/callmesh-client.service.example /etc/systemd/system/callmesh-client.service sudo sed -i 's#/opt/CMClient#/home/<user>/CMClient#g' /etc/systemd/system/callmesh-client.servicenano/vim編輯,並確認docker compose up -d指令沒有其他自訂參數) - 重新載入 systemd 並啟用服務:
sudo systemctl daemon-reload sudo systemctl enable --now callmesh-client.service - 之後主機開機時會先啟動 Docker,再由 systemd 執行
docker compose up -d。若需暫停服務可sudo systemctl stop callmesh-client,並於調整設定後sudo systemctl restart callmesh-client。
提醒:compose 內已設定
restart: unless-stopped,可確保 Docker daemon 重啟時自動復原;systemd unit 則負責在 OS 開機時立即執行 compose,適合長期部署。
- 觀察 GitHub Actions 的 Build & Publish Docker Image workflow(或手動
docker compose build),確認最新映像已產出。 - 在部署主機執行:
這會把容器換成最新的 Node 22 runtime,同時保留 volume 內資料。
docker compose pull # 或 docker pull ghcr.io/toodi0418/cmclient:latest docker compose up -d --build - 若想確認版本,可在容器內跑
node -v或使用docker inspect檢視Config.Image。 - entrypoint 仍會依
AUTO_UPDATE在背景同步 repo,更新映像後建議再docker compose restart,確保 runtime 與程式碼都重新載入。
docker-entrypoint.sh會先把指定分支同步到/data/callmesh/app-src,執行npm ci --omit=dev後啟動程式,並持續以AUTO_UPDATE_POLL_SECONDS(預設 300 秒)輪詢遠端。偵測到main/dev有新 commit 時,會優雅地停止目前的npm start、重新git pull + npm ci,再自動重啟服務,整個流程不需重建容器。- 預設
AUTO_UPDATE=1、AUTO_UPDATE_BRANCH=main。若希望跟進開發版可把.env設成AUTO_UPDATE_BRANCH=dev;若要完全依賴發佈映像,則把AUTO_UPDATE=0,entrypoint 會直接執行/app內的打包版本。 - 相關環境變數:
AUTO_UPDATE_REPO:Git repository URL(需可匿名讀取),預設https://github.com/toodi0418/CMClient.git。AUTO_UPDATE_BRANCH:同步分支(僅接受main或dev,其餘值會回退main)。AUTO_UPDATE_WORKDIR:同步與安裝依賴的目錄,預設/data/callmesh/app-src,與 artifacts 共用 volume 以節省重複下載。AUTO_UPDATE_REMOTE:git remote 名稱,預設origin。AUTO_UPDATE_POLL_SECONDS:背景輪詢間隔秒數,調越小更新越即時但git fetch會更頻繁。
- 當環境無法連網或使用私有 repo 時,可把
AUTO_UPDATE=0並手動執行docker pull/docker compose up -d --build來更新。
CMClient/
├── src/
│ ├── index.js # CLI 入口(Meshtastic/CallMesh 桥接)
│ ├── callmesh/ # CallMesh API 與 APRS 桥接核心
│ ├── aprs/client.js # APRS-IS TCP 客戶端
│ ├── meshtasticClient.js # Meshtastic TCP 流解析
│ └── electron/ # Electron 主行程、Renderer 與 UI
├── proto/meshtastic # 官方 protobuf 定義
├── docs/ # handover 與 CallMesh 技術說明
└── scripts/ # Windows / Linux 打包腳本
核心邏輯集中在 src/callmesh/aprsBridge.js,CLI 與 Electron 共用同一套橋接流程,確保兩邊行為一致。
- 更動程式後可直接執行
npm start(CLI summary 模式)。 - 若要觀察 APRS 上行內容,可同時開啟 Electron GUI 的「Mapping 封包追蹤」頁面,或在 CLI 監看 log。
- 修改 comment 等站台資訊時,Bridge 只會送出更新後的 Beacon,不會重連或干擾定時器;Mapping 中的「已上傳」狀態會在收到對應 flow 的 APRS uplink 後自動更新。
-
為何 GitHub Repo 只有原始碼沒有
dist/?
build 產物會破百 MB,已排除在 git 外。先npm install後再執行npm run build:*可在本機重新產出。 -
Meshtastic 斷線會自動重連嗎?
CLI 會自動重連;Electron 版由 GUI 控制,可手動重試或啟用背景重連。 -
APRS 不停重連怎麼辦?
通常是同一呼號在不同實例上登入或 comment 更新後頻繁重連;目前我們只在呼號/SSID 變更時才 teardown APRS,若仍被踢請確認無其他裝置使用相同呼號。
此專案依原作者設定的授權條款釋出;若需商用或替代授權,請聯絡 maintainer。