koishi-plugin-esp32-to-galaku
v0.3.0
Published
Koishi plugin that sends GALAKU control commands to an ESP32-S3 bridge through a local PowerShell TCP-to-serial bridge.
Maintainers
Readme
koishi-plugin-esp32-to-galaku
这是一个 Koishi 插件,用 Discord 机器人命令控制本机或远端的 ESP32-S3 GALAKU 桥。
完整链路:
Discord 消息
-> Koishi Discord adapter
-> koishi-plugin-esp32-to-galaku
-> TCP
-> tools/galaku-serial-bridge.ps1
-> ESP32-S3 USB Serial/JTAG
-> ESP32-S3 BLE
-> GALAKU 设备插件本身不直接打开 COM 串口。COM 口只由 PowerShell/.NET SerialPort 桥接脚本持有,Koishi 只走 TCP,这样能避开 Node.js/Koishi 直接控制 ESP32-S3 USB Serial/JTAG 时容易遇到的复位、占用和重连问题。
当前状态
- 插件命令已可用:
galaku status、galaku ping、galaku scan、galaku services、galaku set <0-100>、galaku hit <damage>、galaku stop、galaku messagehit <on|off|status>。 - PS1 桥脚本已放在
tools/galaku-serial-bridge.ps1,并且会把 ESP32-S3 串口回复写回 TCP 客户端。 - ESP32-S3 固件源码已放在
firmware/esp32s3-galaku-bridge/,可直接用 ESP-IDF 构建和烧录。 - GitHub Actions 已配置,依赖安装、TypeScript 构建、Node 测试、
npm pack --dry-run都在 Actions 里跑。 - 当前仓库开发机不需要执行
npm init、npm install、npm run build或测试。 - npm 包已发布:https://www.npmjs.com/package/koishi-plugin-esp32-to-galaku
- Koishi 插件市场会从 npm registry 自动索引符合规则的公开插件包,发布后可能需要等待同步。
准备 Discord 账号、服务器和机器人
1. 注册 Discord 账号
- 打开 Discord 官网并注册账号。
- 登录 Discord 客户端或网页版。
- 创建一个只用于测试的服务器,或者使用你已有的私人测试服务器。
建议先用私人服务器测试,不要一开始把机器人拉进公开服务器。
2. 创建 Discord Developer 应用
- 打开 Discord Developer Portal:https://discord.com/developers/applications
- 点击
New Application。 - 输入应用名称,例如
GALAKU Koishi Test Bot。 - 进入应用后,打开左侧
Bot页面。 - 点击
Add Bot,创建机器人用户。 - 在
Token区域点击Reset Token或View Token,复制 Bot Token。
Bot Token 等同于机器人账号密码,不要提交到 GitHub,不要发给别人。
3. 打开需要的 Bot Intents
在 Developer Portal 的 Bot 页面,找到 Privileged Gateway Intents:
- 打开
Message Content Intent。 - 如果你的 Koishi/Discord 配置需要读取成员相关事件,再打开
Server Members Intent;本插件的基本命令不强依赖它。 - 保存设置。
这个插件注册的是 Koishi 文本命令,不是 Discord 原生 slash command。要让机器人能读到普通频道消息里的 galaku status 这类文本命令,通常需要 Message Content Intent。
4. 邀请机器人进入服务器
- 在 Developer Portal 打开
OAuth2->URL Generator。 Scopes勾选:botapplications.commands
Bot Permissions至少勾选:View ChannelsSend MessagesRead Message History
- 复制生成的 URL,在浏览器打开。
- 选择你的测试服务器并授权。
如果只是用 Koishi 文本命令,核心权限是看频道和发消息;applications.commands 预留给 Discord/Koishi 侧后续需要注册交互命令的场景。
准备 Koishi 和 Discord 适配器
下面操作在真正运行机器人的 Koishi 项目里做,不是在本仓库开发目录里做。
方案 A:用 Koishi 控制台安装
- 启动你的 Koishi 实例。
- 打开 Koishi 控制台。
- 在插件市场安装 Discord 适配器,插件通常显示为
adapter-discord。 - 在 Discord 适配器配置里填入刚才复制的 Bot Token。
- 启用 Discord 适配器。
- 在插件市场或依赖管理里安装本插件。
如果本插件还没发布到 npm,Koishi 控制台可能搜不到它。这时用方案 B,从 GitHub 依赖安装。
方案 B:在 Koishi 项目中从 GitHub 安装本插件
在你的 Koishi 项目目录中添加依赖。示例:
{
"dependencies": {
"@koishijs/plugin-adapter-discord": "latest",
"koishi-plugin-esp32-to-galaku": "github:ra1nyxin/koishi-plugin-esp32-to-galaku"
}
}然后在 Koishi 项目目录运行安装命令。注意,这是部署 Koishi 的项目,不是本仓库开发目录。
npm install本仓库已经配置了 prepare,从 GitHub 安装时 npm 会自动编译 TypeScript。
3. 配置本插件
插件配置项:
| 配置项 | 默认值 | 说明 |
| --- | --- | --- |
| host | 127.0.0.1 | PS1 TCP 串口桥地址。 |
| port | 25363 | PS1 TCP 串口桥端口。 |
| timeoutMs | 3500 | 单次命令等待桥脚本回复的超时时间,单位毫秒。 |
| maxReplyBytes | 4096 | 单次最多读取的 TCP 回复字节数。 |
| allowRaw | false | 是否允许 galaku raw <command>。 |
| messageHitDefault | false | Koishi 启动时是否默认开启新消息自动 HIT。 |
| messageHitDamage | 10 | messagehit 开启后,每条新消息触发的 HIT <damage>。 |
本机 Koishi + 本机 ESP32-S3 时保持默认:
host: 127.0.0.1
port: 25363
timeoutMs: 3500
maxReplyBytes: 4096
allowRaw: false
messageHitDefault: false
messageHitDamage: 10朋友的 Koishi 机器人通过 frp 连回你的 ESP32-S3 时,把 host 和 port 改成 frp 暴露出来的地址和端口。
ESP32-S3 固件源码和烧录
固件源码在:
firmware/esp32s3-galaku-bridge/它是一个 ESP-IDF 工程,负责通过 BLE 连接 GALAKU/GK36 设备,并通过 ESP32-S3 USB Serial/JTAG 接收 PS1 桥转发来的控制命令。
在 ESP-IDF 终端进入固件目录:
cd .\firmware\esp32s3-galaku-bridge
idf.py set-target esp32s3
idf.py build
idf.py -p COMx flash monitor把 COMx 换成设备管理器里的实际 ESP32-S3 串口。烧录成功后,固件支持这些串口命令:
PING
STATUS
SCAN
SERVICES
SET <0-100>
HIT <damage>
STOP固件目录内有更完整的烧录说明:firmware/esp32s3-galaku-bridge/README.md。
Tip:本仓库只提交固件源码和 sdkconfig.defaults,不会提交 build/、sdkconfig、sdkconfig.old 等本机构建产物。
启动 ESP32-S3 串口桥
这一步在插着 ESP32-S3 的 Windows 机器上执行。
1. 确认 ESP32-S3 固件
ESP32-S3 固件需要支持这些串口命令:
PING
STATUS
SCAN
SERVICES
SET <0-100>
HIT <damage>
STOP如果你还没有烧录固件,先使用 firmware/esp32s3-galaku-bridge/ 里的 ESP-IDF 工程烧录。
当前 ESP32-S3 项目默认信息:
| 项目 | 值 |
| --- | --- |
| 串口 | COM3 |
| 波特率 | 115200 |
| TCP 桥默认监听 | 127.0.0.1:25363 |
如果你的设备管理器里 ESP32-S3 不是 COM3,启动脚本时改 -SerialPort。
2. 启动 PS1 桥
在本仓库目录运行:
powershell -ExecutionPolicy Bypass `
-File .\tools\galaku-serial-bridge.ps1 `
-SerialPort COM3 `
-Baud 115200 `
-ListenPort 25363正常启动后会看到类似:
GALAKU TCP bridge listening on 127.0.0.1:25363
COM <= PING
COM => PONG3. frp 场景
推荐让 PS1 桥继续只监听 127.0.0.1,再由 frpc 把本机 127.0.0.1:25363 映射出去。不要无保护地把桥脚本监听到公网。
示意:
[galaku-bridge]
type = tcp
local_ip = 127.0.0.1
local_port = 25363
remote_port = 25363frp server、token、访问控制、防火墙规则按你的实际环境配置。这个 TCP 端点收到命令就会控制设备,必须把它当作受信控制接口处理。
在 Discord 中发送控制命令
确认这三件事都已完成:
- Discord 机器人已在线。
- Koishi 已启用 Discord adapter 和本插件。
- PS1 桥脚本已连接到 ESP32-S3。
然后在 Discord 测试频道发送:
galaku ping期望回复:
GALAKU <= PING
GALAKU => PONG继续测试:
galaku status
galaku scan
galaku services
galaku set 30
galaku hit 1.5
galaku stop
galaku messagehit status
galaku messagehit on
galaku messagehit off直接发送 galaku、galaku help、galaku --help、galaku -h、galaku -?、galaku ? 会返回同一份帮助文本。帮助文本会附带当前设备 STATUS 和功能开关状态。
set 和 hit 的区别
galaku set <0-100> 是直接设定强度。
galaku set 30它会向 ESP32-S3 发送:
SET 30适合手动测试固定强度。插件会把数值限制在 0..100 范围内,例如 galaku set 200 会被夹到 SET 100。
galaku hit <damage> 是模拟一次“受击反馈”。
galaku hit 1它会向 ESP32-S3 发送:
HIT 1ESP32-S3 固件会把 damage 换算成强度增量,再叠加到当前强度。例如当前固件里 HIT 1 通常会得到约 level=10;连续 hit 会继续累加,但最高不会超过 100。
简单说:
set = 直接设定强度
hit = 按伤害值叠加强度messagehit 开关
messagehit 默认关闭。
开启:
galaku messagehit on关闭:
galaku messagehit off查看状态:
galaku messagehit status开启后,Koishi 每检测到一条新消息就会静默向 ESP32-S3 发送:
HIT 10私聊和群聊消息都会触发。当前版本不做用户白名单、频道白名单或权限限制;只要能向机器人发命令,就能开关这个功能。机器人自身发出的消息、以及 galaku ... 控制命令消息不会触发 messagehit,避免 galaku stop 这类控制命令额外触发一次自动 HIT。
如果要改变自动触发的 damage,改插件配置里的 messageHitDamage。
如果你的 Koishi 设置了全局命令前缀,例如 /、.、!,就在 Discord 里按该前缀发送:
!galaku status如果频道里机器人很多,也可以提及机器人后发送命令:
@你的机器人 galaku status可用别名:
galaku status
galaku-esp32s3 status帮助命令统一使用同一份输出:
galaku help
galaku --help
galaku -h
galaku -?galaku raw <command> 默认禁用。只有你明确打开 allowRaw 后才可用,例如:
galaku raw STATUS推荐测试顺序
- 先不连 GALAKU 设备,只插 ESP32-S3,启动 PS1 桥。
- 在 Discord 发
galaku ping,确认 Koishi -> TCP -> PS1 -> ESP32-S3 串口通。 - 发
galaku status,看 ESP32-S3 当前 BLE 状态。 - 打开 GALAKU 设备,确保手机 App 没占用 BLE 连接。
- 发
galaku scan,让 ESP32-S3 扫描/连接目标设备。 - 发
galaku set 10做低强度测试。 - 发
galaku stop停止。 - 确认稳定后再测试
galaku hit 1.5这类动态命令。 - 最后再测试
galaku messagehit on,因为它会让任何新消息触发HIT 10。
常见问题
机器人在线但不响应 galaku status
检查:
- Discord Developer Portal 里是否打开了
Message Content Intent。 - Koishi Discord adapter 是否填了正确 Bot Token。
- 机器人是否有当前频道的
View Channels和Send Messages权限。 - Koishi 是否设置了命令前缀;如果设置了,就要带前缀发送。
返回 GALAKU 命令失败:connect ECONNREFUSED
说明 Koishi 连不上 PS1 桥。
检查:
- PS1 桥脚本是否正在运行。
- 插件
host/port是否正确。 - 本机部署时是否使用
127.0.0.1:25363。 - frp 部署时远端端口是否开放,frpc 是否在线。
返回超时
说明 TCP 连接可能建立了,但桥脚本没有在 timeoutMs 内返回。
检查:
- ESP32-S3 是否插好。
SerialPort是否是正确 COM 口。- ESP32-S3 固件是否正在读 USB Serial/JTAG。
- PS1 桥窗口里是否有
COM <=和COM =>日志。
PS1 桥启动时报 COM 口错误
检查:
- 设备管理器里的实际 COM 口。
- 是否有 Arduino IDE、ESP-IDF monitor、串口助手占用了同一个 COM 口。
- 重新插拔 ESP32-S3 后 COM 口是否变化。
Discord 里 galaku set 200 为什么变成 SET 100
插件会把 SET 强度限制在 ESP32-S3 固件接受的 0..100 范围内,超出范围会自动夹紧。
开发和 CI
这个仓库的开发策略是:本机只写代码,不在本机缓存 Node.js 依赖。
本仓库不要执行:
npm init
npm install
npm run build
npm testGitHub Actions 会在云端执行:
npm install
npm run build
npm test
npm pack --dry-run当前 workflow 在 Node.js 22 和 24 上构建测试。
发布到 npm 和 Koishi 插件市场
Koishi 插件市场主要收录 npm registry 上符合 Koishi 插件规则的公开包。当前项目已经满足关键前提:
- 包名是
koishi-plugin-esp32-to-galaku。 peerDependencies里声明了koishi。package.json里有koishi元数据。- GitHub 仓库是公开仓库。
- GitHub Actions 能完成构建、测试和打包检查。
- npm registry 当前没有占用这个包名。
当前包已经发布到 npm。下面流程用于首次发布后的维护发版,或者以后更新版本时复用。
1. 创建 npm 账号
- 打开 https://www.npmjs.com/signup 注册 npm 账号。
- 登录后建议开启 2FA。
- 进入 Access Tokens 页面创建 token。
- token 类型建议选择可用于发布包的 Automation / Publish token。
2. 把 npm token 写入 GitHub Secrets
- 打开 GitHub 仓库:https://github.com/ra1nyxin/koishi-plugin-esp32-to-galaku
- 进入
Settings->Secrets and variables->Actions。 - 点击
New repository secret。 - 名称填:
NPM_TOKEN- 值填刚才从 npm 创建的 token。
3. 手动触发发布 workflow
- 打开 GitHub 仓库的
Actions页面。 - 选择
Publish to npmworkflow。 - 点击
Run workflow。 - workflow 会执行:
npm install
npm run build
npm test
npm pack --dry-run
npm publish --access public --provenance发布成功后,npm 包地址是:
https://www.npmjs.com/package/koishi-plugin-esp32-to-galaku4. 等待 Koishi 插件市场收录
发布到 npm 后,Koishi 插件市场通常会自动索引符合规则的包。不是 GitHub Actions 直接扫描 GitHub 仓库,而是 Koishi 市场侧扫描 npm 包。
如果发布后没有马上出现,先等一段时间,再检查:
- npm 包是否公开。
- 包名是否仍是
koishi-plugin-esp32-to-galaku。 peerDependencies.koishi是否存在。- README 和
package.json是否已随 npm 包发布。 - npm 页面是否能正常访问。
Tip:后续每次发布前都要先更新 package.json 里的版本号。修复 README 或小问题用 patch 版本,例如 0.1.1;增加功能用 minor 版本,例如 0.2.0。
实测记录
2026-06-16:Ubuntu VM -> 物理机 PS1 桥 -> ESP32-S3 -> GALAKU
实测环境:
| 项目 | 值 |
| --- | --- |
| 物理机 LAN IP | <物理机 LAN IP> |
| Ubuntu Desktop VM IP | <Ubuntu VM IP> |
| VM Node.js | v22.22.3 |
| VM npm | 10.9.8 |
| 物理机 ESP32-S3 串口 | COM3 |
| PS1 桥监听 | 0.0.0.0:25363 |
| 插件 npm 版本 | 0.1.1 实测,随后修复桥脚本并升到 0.1.4 |
物理机启动桥脚本:
powershell -ExecutionPolicy Bypass `
-File .\tools\galaku-serial-bridge.ps1 `
-SerialPort COM3 `
-Baud 115200 `
-ListenPort 25363 `
-ListenAddress 0.0.0.0VM 内创建一次性测试目录并安装:
mkdir -p ~/koishi-galaku-test
cd ~/koishi-galaku-test
npm init -y
npm install koishi koishi-plugin-esp32-to-galakuVM 下载 npm 包时使用了物理机 Clash 共享代理:
npm config set proxy http://<物理机 LAN IP>:46464
npm config set https-proxy http://<物理机 LAN IP>:46464用插件导出的 sendBridgeLine() 从 VM 直连物理机桥,结果:
<= PING
=> "PONG"
<= STATUS
=> "STATUS ble=1 host_synced=1 scanning=0 connecting=0 connected=1 service_ready=1 target=GK36 level=0 handle=10"
<= SET 10
=> "... OK SET 10"
<= STOP
=> "... OK STOP"同时验证 Koishi Context 能加载插件并注册命令:
plugin loaded: true
commander service: true
registered commands: galaku这次实测发现并修复了一个桥脚本细节:旧版 PS1 桥用默认 UTF-8 StreamWriter 时,TCP 客户端可能先收到 UTF-8 BOM。0.1.2 起改为无 BOM UTF-8,VM 端原始 TCP 回复确认为:
b'PONG\n'0.1.4 起机器人输出会过滤 ESP32-S3 NimBLE 调试日志,只返回 PONG、STATUS ...、OK ...、ERR ... 等协议结果行,避免连续 hit 后聊天里出现大量 BLE write 日志。
测试结论
- VM 可以通过物理机 LAN IP 访问 PS1 桥。
- PS1 桥使用
-ListenAddress 0.0.0.0时可被 VM 访问;默认仍是127.0.0.1,避免误暴露。 - npm 包可以在干净 Ubuntu 环境安装。
- 插件 TCP 客户端能从 VM 控制物理机上的 ESP32-S3。
- ESP32-S3 已连接到
GK36,并能执行SET 10和STOP。 - Koishi 插件入口能被 Koishi Context 加载,
galaku命令已注册。
Tip:跨 VM/物理机测试时,先用 PING 和 STATUS 验证链路;需要远程访问时再显式启用 -ListenAddress 0.0.0.0,不要把它作为默认值。
参考文档
- Koishi 模板项目:https://koishi.chat/zh-CN/manual/starter/boilerplate.html
- Koishi Discord 适配器:https://koishi.chat/zh-CN/plugins/adapter/discord.html
- Koishi 插件发布:https://koishi.chat/zh-CN/guide/develop/publish.html
- Discord Developer Portal:https://discord.com/developers/applications
- Discord Gateway / Intents 文档:https://discord.com/developers/docs/topics/gateway
- npm 注册账号:https://docs.npmjs.com/creating-a-new-npm-user-account
Tip:第一次端到端测试时,先用 galaku ping 和 galaku status 验证链路,不要直接从高强度 set 或复杂 frp 场景开始。
