Compare commits

...

30 Commits

Author SHA1 Message Date
yczpf2019
708bdc6bf0 feat(arduino-shell): 在前端过滤掉 serial1/undefined 错误提示 2026-01-24 21:47:45 +08:00
yczpf2019
44b02f4781 fix(shell-arduino): 将 --library 改回 --libraries 以正确加载库集合 2026-01-24 21:44:15 +08:00
yczpf2019
48ce7f35e1 chore(shell-arduino): 清理调试日志 2026-01-24 21:35:12 +08:00
yczpf2019
9b80cf73d3 fix(socket): 修复 arduino.upload 逻辑,只编译返回文件供前端烧录 2026-01-24 21:30:27 +08:00
yczpf2019
67a3a3bd78 fix(shell-arduino): 改用 execFileUntilClosed 避免 shell 引号解析问题 2026-01-24 21:23:25 +08:00
yczpf2019
e8de8f19c2 debug(shell-arduino): 添加调试日志查看 arduino-cli 命令格式 2026-01-24 21:19:08 +08:00
yczpf2019
7d2076f165 fix(shell-arduino): 修复 --libraries 参数格式,改用单独的 --library 参数 2026-01-24 21:13:46 +08:00
yczpf2019
10d5254a7e fix(websocket-arduino): 在 init 中同时初始化 WebCompiler.ArduShell 2026-01-24 21:09:00 +08:00
yczpf2019
a67284afe5 feat(websocket-arduino): 委托给 WebCompiler.ArduShell 处理本地上传 2026-01-24 21:04:10 +08:00
yczpf2019
4ac522ffc6 fix(websocket-bu): 修复 WebBU 模块加载顺序问题,改为动态获取 2026-01-24 20:55:31 +08:00
yczpf2019
5456419bb3 fix(socket): 添加 MicroPython 请求端口有效性检查,无效端口不报错 2026-01-24 20:44:03 +08:00
yczpf2019
9bcc49059e fix(ampy): 启用 exitREPL 软复位让设备执行上传的代码 2026-01-24 20:30:25 +08:00
yczpf2019
0c6199d8e4 fix(ampy): 添加 dispose 方法 null 检查防止重复调用报错 2026-01-24 20:28:38 +08:00
yczpf2019
c232332d69 feat(websocket-bu): MicroPython 上传/烧录委托给本地 Web Serial API 处理 2026-01-24 20:17:46 +08:00
yczpf2019
cc2a2714c3 fix(shell-micropython): 系统命令不加引号,修复 Linux shell 解析错误 2026-01-24 20:09:06 +08:00
yczpf2019
c32583e3f4 debug(shell-micropython): 添加详细调试日志以定位引号错误 2026-01-24 20:02:11 +08:00
yczpf2019
cc550ec5cc fix(shell-micropython): 修复 reset 数组参数序列化导致的引号错误 2026-01-24 19:57:25 +08:00
yczpf2019
ed9264bd70 fix(burn-upload): 修复 Boards 模块未导入导致的 ReferenceError 2026-01-24 19:52:28 +08:00
yczpf2019
0fc1d9c439 fix(mstring): 修复前端模板引擎正则错误并同步逻辑 2026-01-24 19:48:12 +08:00
yczpf2019
ef98c5e89f fix: core template engine and upload params to resolve Syntax error 2026-01-24 19:37:52 +08:00
yczpf2019
ec4814c208 fix: add missing baudrate and reset params to shell command interpolation 2026-01-24 19:10:03 +08:00
yczpf2019
6c6661c6c0 fix: make shell command robust against cached double quotes from frontend 2026-01-24 19:04:00 +08:00
yczpf2019
7cd59ef596 fix: batch fix invalid shell quotes in config files (safe python script) 2026-01-24 18:57:29 +08:00
yczpf2019
e76956c4bc fix: remove incorrect outer quotes in esp32c2 config to fix shell syntax error 2026-01-24 18:47:47 +08:00
yczpf2019
1e4d4247bf chore: add debug logging for shell commands 2026-01-24 18:44:15 +08:00
yczpf2019
d776e24d2f fix: syntax error in shell command by closing quotes for python and script paths 2026-01-24 18:41:25 +08:00
yczpf2019
c7d57d39a1 fix: init local device handlers even when connected to Socket Server 2026-01-24 18:37:54 +08:00
yczpf2019
8b59808c17 fix: use Web.BU.requestPort explicitly for Add Device button to support WebSocket mode 2026-01-24 18:34:30 +08:00
yczpf2019
aa85c7ef27 fix: show Add Device button in Web environment 2026-01-24 18:30:47 +08:00
yczpf2019
49d6ec88f0 fix: unify frontend and backend Socket.io protocol for WebSocket connection 2026-01-24 18:15:34 +08:00
35 changed files with 2407 additions and 2240 deletions

134
README.md
View File

@@ -64,72 +64,86 @@ pm2 startup
### 4.2 使用 Nginx 反代 (推荐) ### 4.2 使用 Nginx 反代 (推荐)
#### A. 传统 Nginx 配置 (命令行) #### 步骤 1: 安装 Nginx 和 Certbot
如果你使用原生 Nginx请参考以下配置 ```bash
apt update && apt install -y nginx certbot python3-certbot-nginx
```
```nginx #### 步骤 2: 创建 Nginx 配置文件
```bash
cat > /etc/nginx/sites-available/mixly << 'EOF'
server { server {
listen 80; listen 80;
server_name 你的域名; server_name 你的域名;
return 301 https://$host$request_uri;
}
server { # 主站点反代
listen 443 ssl;
server_name 你的域名;
ssl_certificate /path/to/your/cert.pem;
ssl_certificate_key /path/to/your/key.pem;
# 核心配置:处理 WebSocket 和大文件上传
location / { location / {
proxy_pass https://127.0.0.1:7100; proxy_pass https://127.0.0.1:7100;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
client_max_body_size 100M;
proxy_read_timeout 3600s;
}
# 处理 Socket.io 特殊路径
location /mixly-socket/ {
proxy_pass https://127.0.0.1:7100;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
```
#### B. Nginx Proxy Manager (NPM) 配置 (可视化)
如果你使用的是 NPM请按以下步骤配置
1. **Details 选项卡**
* **Domain Names**: `你的域名`
* **Scheme**: `https`
* **Forward Hostname/IP**: `127.0.0.1`
* **Forward Port**: `7100`
* **Websockets Support**: **必须勾选 (ON)**
2. **Custom Locations 选项卡**
* 点击 **Add Location**:
* **Define Location**: `/mixly-socket/`
* **Forward Scheme**: `https`
* **Forward Hostname/IP**: `127.0.0.1`
* **Forward Port**: `7100`
* 点击内置的齿轮图标或进入 **Advanced**,确保有以下配置(通常勾选 Websockets Support 后 NPM 会自动处理,但建议检查):
```nginx
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
```
3. **Advanced 选项卡** (可选)
* 建议添加以下配置以支持大文件上传并忽略自签名证书错误(重要!):
```nginx
client_max_body_size 100M;
# 忽略后端自签名证书错误 (必填,否则无法连接 wss)
proxy_ssl_verify off; proxy_ssl_verify off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 100M;
}
# WebSocket 反代 (关键配置)
location /mixly-socket/ {
proxy_pass https://127.0.0.1:7100/socket.io/;
proxy_ssl_verify off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 86400s;
}
}
EOF
```
> **注意**:将 `你的域名` 替换为实际域名,如 `mixly.example.com`
#### 步骤 3: 启用配置并测试
```bash
# 创建软链接启用配置
ln -sf /etc/nginx/sites-available/mixly /etc/nginx/sites-enabled/
# 删除默认站点 (可选)
rm -f /etc/nginx/sites-enabled/default
# 测试配置语法
nginx -t
# 重启 Nginx
systemctl restart nginx
```
#### 步骤 4: 自动申请 SSL 证书 (Let's Encrypt)
```bash
# 将 your-email@example.com 替换为你的邮箱
certbot --nginx -d 你的域名 --non-interactive --agree-tos -m your-email@example.com
```
Certbot 会自动修改 Nginx 配置并启用 HTTPS (443 端口)。
#### 步骤 5: 设置证书自动续期
```bash
# 测试自动续期
certbot renew --dry-run
# 证书默认每 90 天过期certbot 会自动配置定时任务续期
```
#### Nginx 常用管理命令
```bash
# 查看状态
systemctl status nginx
# 重载配置 (不中断服务)
systemctl reload nginx
# 查看错误日志
tail -f /var/log/nginx/error.log
``` ```
## 5. 跨平台特性说明 ## 5. 跨平台特性说明
@@ -163,3 +177,7 @@ pm2 reload mixly3
- **反向代理配置**:如果使用 Nginx 反代,请务必处理好的 WebSocket (Upgrade) 头,否则页面无法连接。 - **反向代理配置**:如果使用 Nginx 反代,请务必处理好的 WebSocket (Upgrade) 头,否则页面无法连接。
- **上传报错**:如果提示权限不足,请确认当前用户是否在 `dialout` 组,或尝试 `root` 运行(不推荐)。 - **上传报错**:如果提示权限不足,请确认当前用户是否在 `dialout` 组,或尝试 `root` 运行(不推荐)。
- **Python 命令**:系统必须能识别 `python3` 命令。 - **Python 命令**:系统必须能识别 `python3` 命令。
- **没有“添加设备”按钮**:这是因为 WebSocket 连接失败。
1. 检查 NPM 中是否勾选了 **Websockets Support**
2. 检查 NPM Advanced 配置中是否添加了 `proxy_ssl_verify off;` (关键)。
3. 尝试重启服务端:`pm2 reload mixly3`

View File

@@ -34,15 +34,15 @@
"type": "command", "type": "command",
"portSelect": "all", "portSelect": "all",
"micropython:educore:educore": { "micropython:educore:educore": {
"command": "\"{esptool}\" --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib-v1.23.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"", "command": "{esptool} --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib-v1.23.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"",
"special": [ "special": [
{ {
"name": "Firmware No Ble With SSL", "name": "Firmware No Ble With SSL",
"command": "\"{esptool}\" --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib-v1.23.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib-v1.23.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
{ {
"name": "Firmware With Ble No SSL", "name": "Firmware With Ble No SSL",
"command": "\"{esptool}\" --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib_ble-v1.23.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib_ble-v1.23.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
} }
] ]
} }
@@ -54,7 +54,7 @@
"{indexPath}/../micropython/build/lib", "{indexPath}/../micropython/build/lib",
"{indexPath}/build/lib" "{indexPath}/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": false, "copyLib": false,
"reset": [] "reset": []

View File

@@ -118,16 +118,16 @@
"type": "command", "type": "command",
"portSelect": "all", "portSelect": "all",
"micropython:esp32:mixgo": { "micropython:esp32:mixgo": {
"command": "\"{esptool}\" --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/Mixgo_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/Mixgo_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
"micropython:esp32:mixgo_pe": { "micropython:esp32:mixgo_pe": {
"command": "\"{esptool}\" --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/Mixgo_PE_lib-v1.25.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/Mixgo_PE_lib-v1.25.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
"micropython:esp32:generic": { "micropython:esp32:generic": {
"command": "\"{esptool}\" --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/Generic_ESP32_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/Generic_ESP32_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
"micropython:esp32:mpython": { "micropython:esp32:mpython": {
"command": "\"{esptool}\" --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/mPython_lib-v1.25.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/mPython_lib-v1.25.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK12.bin\""
} }
}, },
"upload": { "upload": {
@@ -137,7 +137,7 @@
"{indexPath}/build/lib", "{indexPath}/build/lib",
"{indexPath}/../micropython/build/lib" "{indexPath}/../micropython/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": false, "copyLib": false,
"reset": [] "reset": []

View File

@@ -62,20 +62,20 @@
"type": "command", "type": "command",
"portSelect": "all", "portSelect": "all",
"micropython:esp32c2:mixgo_mini": { "micropython:esp32c2:mixgo_mini": {
"command": "\"{esptool}\" --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"", "command": "{esptool} --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"",
"special": [ "special": [
{ {
"name": "Firmware For General Application", "name": "Firmware For General Application",
"command": "\"{esptool}\" --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
{ {
"name": "Firmware Optimize For V2.x Board", "name": "Firmware Optimize For V2.x Board",
"command": "\"{esptool}\" --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_v2_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_v2_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
} }
] ]
}, },
"micropython:esp32c2:generic_2M": { "micropython:esp32c2:generic_2M": {
"command": "\"{esptool}\" --chip esp32c2 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Generic_C2_lib-v1.25.0.bin\"" "command": "{esptool} --chip esp32c2 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Generic_C2_lib-v1.25.0.bin\""
} }
}, },
"upload": { "upload": {
@@ -85,7 +85,7 @@
"{indexPath}/../micropython/build/lib", "{indexPath}/../micropython/build/lib",
"{indexPath}/build/lib" "{indexPath}/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": false, "copyLib": false,
"reset": [] "reset": []

View File

@@ -118,16 +118,16 @@
"type": "command", "type": "command",
"portSelect": "all", "portSelect": "all",
"micropython:esp32c3:mixgo_cc": { "micropython:esp32c3:mixgo_cc": {
"command": "\"{esptool}\" --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Mixgo_CC_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Mixgo_CC_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
"micropython:esp32c3:mixgo_me": { "micropython:esp32c3:mixgo_me": {
"command": "\"{esptool}\" --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Mixgo_ME_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Mixgo_ME_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
"micropython:esp32c3:mixgocar_c3": { "micropython:esp32c3:mixgocar_c3": {
"command": "\"{esptool}\" --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Mixgo_Car_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Mixgo_Car_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
"micropython:esp32c3:generic": { "micropython:esp32c3:generic": {
"command": "\"{esptool}\" --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Generic_C3_UART_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Generic_C3_UART_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
} }
}, },
"upload": { "upload": {
@@ -137,7 +137,7 @@
"{indexPath}/build/lib", "{indexPath}/build/lib",
"{indexPath}/../micropython/build/lib" "{indexPath}/../micropython/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": false, "copyLib": false,
"reset": [] "reset": []

View File

@@ -62,10 +62,10 @@
"type": "command", "type": "command",
"portSelect": "all", "portSelect": "all",
"micropython:esp32c5:mixgo_sowl": { "micropython:esp32c5:mixgo_sowl": {
"command": "\"{esptool}\" --chip esp32c5 --port {com} --baud {baudrate} --after hard_reset write_flash -e 0x2000 \"{indexPath}/build/Mixgo_Sowl_lib-v1.27.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK12.bin\" 0x400000 \"{indexPath}/../micropython/build/esp_tts_voice_data_xiaole.dat\"" "command": "{esptool} --chip esp32c5 --port {com} --baud {baudrate} --after hard_reset write_flash -e 0x2000 \"{indexPath}/build/Mixgo_Sowl_lib-v1.27.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK12.bin\" 0x400000 \"{indexPath}/../micropython/build/esp_tts_voice_data_xiaole.dat\""
}, },
"micropython:esp32c5:generic": { "micropython:esp32c5:generic": {
"command": "\"{esptool}\" --chip esp32c5 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x2000 \"{indexPath}/build/Generic_C5_lib-v1.27.0.bin\" 0x3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c5 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x2000 \"{indexPath}/build/Generic_C5_lib-v1.27.0.bin\" 0x3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
} }
}, },
"upload": { "upload": {
@@ -75,7 +75,7 @@
"{indexPath}/build/lib", "{indexPath}/build/lib",
"{indexPath}/../micropython/build/lib" "{indexPath}/../micropython/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": false, "copyLib": false,
"reset": [] "reset": []

View File

@@ -62,28 +62,28 @@
"type": "command", "type": "command",
"portSelect": "all", "portSelect": "all",
"micropython:esp32s2:mixgo_ce": { "micropython:esp32s2:mixgo_ce": {
"command": "\"{esptool}\" --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x1000 \"{indexPath}/build/Mixgo_CE_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"", "command": "{esptool} --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x1000 \"{indexPath}/build/Mixgo_CE_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"",
"special": [ "special": [
{ {
"name": "Default", "name": "Default",
"command": "\"{esptool}\" --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x1000 \"{indexPath}/build/Mixgo_CE_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x1000 \"{indexPath}/build/Mixgo_CE_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
{ {
"name": "ESP-AT-mode", "name": "ESP-AT-mode",
"command": "\"{esptool}\" --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x0000 \"{indexPath}/build/MixGo-CE_AT-T17_R18.bin\"" "command": "{esptool} --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x0000 \"{indexPath}/build/MixGo-CE_AT-T17_R18.bin\""
} }
] ]
}, },
"micropython:esp32s2:generic": { "micropython:esp32s2:generic": {
"command": "\"{esptool}\" --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x1000 \"{indexPath}/build/Generic_S2_lib-v1.25.0.bin\"", "command": "{esptool} --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x1000 \"{indexPath}/build/Generic_S2_lib-v1.25.0.bin\"",
"special": [ "special": [
{ {
"name": "Default", "name": "Default",
"command": "\"{esptool}\" --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x1000 \"{indexPath}/build/Generic_S2_lib-v1.25.0.bin\"" "command": "{esptool} --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x1000 \"{indexPath}/build/Generic_S2_lib-v1.25.0.bin\""
}, },
{ {
"name": "ESP-AT-mode", "name": "ESP-AT-mode",
"command": "\"{esptool}\" --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x0000 \"{indexPath}/build/MixGo-CE_AT-T17_R18.bin\"" "command": "{esptool} --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x0000 \"{indexPath}/build/MixGo-CE_AT-T17_R18.bin\""
} }
] ]
} }
@@ -95,7 +95,7 @@
"{indexPath}/build/lib", "{indexPath}/build/lib",
"{indexPath}/../micropython/build/lib" "{indexPath}/../micropython/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": false, "copyLib": false,
"reset": [] "reset": []

View File

@@ -118,16 +118,16 @@
"type": "command", "type": "command",
"portSelect": "all", "portSelect": "all",
"micropython:esp32s3:mixgo_sant": { "micropython:esp32s3:mixgo_sant": {
"command": "\"{esptool}\" --chip esp32s3 --port {com} --baud {baudrate} --after hard_reset write_flash -e 0x0 \"{indexPath}/build/Mixgo_Sant_lib_DL-v1.25.0.bin\" 0xF00000 \"{indexPath}/../micropython/build/HZK16_GBK.bin\" 0xC00000 \"{indexPath}/../micropython/build/esp_tts_voice_data_xiaole.dat\"" "command": "{esptool} --chip esp32s3 --port {com} --baud {baudrate} --after hard_reset write_flash -e 0x0 \"{indexPath}/build/Mixgo_Sant_lib_DL-v1.25.0.bin\" 0xF00000 \"{indexPath}/../micropython/build/HZK16_GBK.bin\" 0xC00000 \"{indexPath}/../micropython/build/esp_tts_voice_data_xiaole.dat\""
}, },
"micropython:esp32s3:mixgo_nova": { "micropython:esp32s3:mixgo_nova": {
"command": "\"{esptool}\" --chip esp32s3 --port {com} --baud {baudrate} --after hard_reset write_flash -e 0x0 \"{indexPath}/build/Mixgo_Nova_lib-v1.25.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK12.bin\" 0x400000 \"{indexPath}/../micropython/build/esp_tts_voice_data_xiaole.dat\"" "command": "{esptool} --chip esp32s3 --port {com} --baud {baudrate} --after hard_reset write_flash -e 0x0 \"{indexPath}/build/Mixgo_Nova_lib-v1.25.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK12.bin\" 0x400000 \"{indexPath}/../micropython/build/esp_tts_voice_data_xiaole.dat\""
}, },
"micropython:esp32s3:mixgo_soar": { "micropython:esp32s3:mixgo_soar": {
"command": "\"{esptool}\" --chip esp32s3 --port {com} --baud {baudrate} --after hard_reset write_flash -e 0x0 \"{indexPath}/build/Mixgo_Soar_lib-v1.25.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK16_GBK.bin\" 0x400000 \"{indexPath}/../micropython/build/esp_tts_voice_data_xiaole.dat\"" "command": "{esptool} --chip esp32s3 --port {com} --baud {baudrate} --after hard_reset write_flash -e 0x0 \"{indexPath}/build/Mixgo_Soar_lib-v1.25.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK16_GBK.bin\" 0x400000 \"{indexPath}/../micropython/build/esp_tts_voice_data_xiaole.dat\""
}, },
"micropython:esp32s3:generic": { "micropython:esp32s3:generic": {
"command": "\"{esptool}\" --chip esp32s3 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x0 \"{indexPath}/build/Generic_S3_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32s3 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x0 \"{indexPath}/build/Generic_S3_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
} }
}, },
"upload": { "upload": {
@@ -137,7 +137,7 @@
"{indexPath}/build/lib", "{indexPath}/build/lib",
"{indexPath}/../micropython/build/lib" "{indexPath}/../micropython/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": false, "copyLib": false,
"reset": [] "reset": []

View File

@@ -21,7 +21,7 @@
"upload": { "upload": {
"type": "command", "type": "command",
"portSelect": "all", "portSelect": "all",
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": true, "copyLib": true,
"reset": [] "reset": []

View File

@@ -25,7 +25,7 @@
"libPath": [ "libPath": [
"{indexPath}/build/lib" "{indexPath}/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": true, "copyLib": true,
"reset": [] "reset": []

View File

@@ -19,7 +19,7 @@
"libPath": [ "libPath": [
"{indexPath}/build/lib" "{indexPath}/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": true, "copyLib": true,
"reset": [] "reset": []

View File

@@ -90,13 +90,13 @@
"type": "command", "type": "command",
"portSelect": "all", "portSelect": "all",
"micropython:esp32c3:feiyi": { "micropython:esp32c3:feiyi": {
"command": "\"{esptool}\" --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Mixgo_FeiYi_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Mixgo_FeiYi_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
"micropython:esp32:rm_e1": { "micropython:esp32:rm_e1": {
"command": "\"{esptool}\" --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/RM_E1_lib-v1.25.0.bin\"" "command": "{esptool} --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/RM_E1_lib-v1.25.0.bin\""
}, },
"micropython:esp32:mixbot": { "micropython:esp32:mixbot": {
"command": "\"{esptool}\" --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/MixBot_lib-v1.25.0.bin\"" "command": "{esptool} --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/MixBot_lib-v1.25.0.bin\""
} }
}, },
"upload": { "upload": {
@@ -106,7 +106,7 @@
"{indexPath}/build/lib", "{indexPath}/build/lib",
"{indexPath}/../micropython/build/lib" "{indexPath}/../micropython/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": false, "copyLib": false,
"reset": [], "reset": [],

View File

@@ -34,15 +34,15 @@
"type": "command", "type": "command",
"portSelect": "all", "portSelect": "all",
"micropython:educore:educore": { "micropython:educore:educore": {
"command": "\"{esptool}\" --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib-v1.23.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"", "command": "{esptool} --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib-v1.23.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"",
"special": [ "special": [
{ {
"name": "Firmware No Ble With SSL", "name": "Firmware No Ble With SSL",
"command": "\"{esptool}\" --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib-v1.23.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib-v1.23.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
{ {
"name": "Firmware With Ble No SSL", "name": "Firmware With Ble No SSL",
"command": "\"{esptool}\" --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib_ble-v1.23.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib_ble-v1.23.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
} }
] ]
} }
@@ -54,7 +54,7 @@
"{indexPath}/../micropython/build/lib", "{indexPath}/../micropython/build/lib",
"{indexPath}/build/lib" "{indexPath}/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": false, "copyLib": false,
"reset": [] "reset": []

View File

@@ -118,16 +118,16 @@
"type": "command", "type": "command",
"portSelect": "all", "portSelect": "all",
"micropython:esp32:mixgo": { "micropython:esp32:mixgo": {
"command": "\"{esptool}\" --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/Mixgo_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/Mixgo_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
"micropython:esp32:mixgo_pe": { "micropython:esp32:mixgo_pe": {
"command": "\"{esptool}\" --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/Mixgo_PE_lib-v1.25.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/Mixgo_PE_lib-v1.25.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
"micropython:esp32:generic": { "micropython:esp32:generic": {
"command": "\"{esptool}\" --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/Generic_ESP32_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/Generic_ESP32_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
"micropython:esp32:mpython": { "micropython:esp32:mpython": {
"command": "\"{esptool}\" --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/mPython_lib-v1.25.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/mPython_lib-v1.25.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK12.bin\""
} }
}, },
"upload": { "upload": {
@@ -137,7 +137,7 @@
"{indexPath}/build/lib", "{indexPath}/build/lib",
"{indexPath}/../micropython/build/lib" "{indexPath}/../micropython/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": false, "copyLib": false,
"reset": [] "reset": []

View File

@@ -62,20 +62,20 @@
"type": "command", "type": "command",
"portSelect": "all", "portSelect": "all",
"micropython:esp32c2:mixgo_mini": { "micropython:esp32c2:mixgo_mini": {
"command": "\"{esptool}\" --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"", "command": "{esptool} --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"",
"special": [ "special": [
{ {
"name": "Firmware For General Application", "name": "Firmware For General Application",
"command": "\"{esptool}\" --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
{ {
"name": "Firmware Optimize For V2.x Board", "name": "Firmware Optimize For V2.x Board",
"command": "\"{esptool}\" --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_v2_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c2 --port {com} --baud {baudrate} --after=no_reset_stub write_flash -e 0x0 \"{indexPath}/build/Mixgo_Mini_v2_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
} }
] ]
}, },
"micropython:esp32c2:generic_2M": { "micropython:esp32c2:generic_2M": {
"command": "\"{esptool}\" --chip esp32c2 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Generic_C2_lib-v1.25.0.bin\"" "command": "{esptool} --chip esp32c2 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Generic_C2_lib-v1.25.0.bin\""
} }
}, },
"upload": { "upload": {
@@ -85,7 +85,7 @@
"{indexPath}/../micropython/build/lib", "{indexPath}/../micropython/build/lib",
"{indexPath}/build/lib" "{indexPath}/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": false, "copyLib": false,
"reset": [] "reset": []

View File

@@ -118,16 +118,16 @@
"type": "command", "type": "command",
"portSelect": "all", "portSelect": "all",
"micropython:esp32c3:mixgo_cc": { "micropython:esp32c3:mixgo_cc": {
"command": "\"{esptool}\" --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Mixgo_CC_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Mixgo_CC_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
"micropython:esp32c3:mixgo_me": { "micropython:esp32c3:mixgo_me": {
"command": "\"{esptool}\" --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Mixgo_ME_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Mixgo_ME_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
"micropython:esp32c3:mixgocar_c3": { "micropython:esp32c3:mixgocar_c3": {
"command": "\"{esptool}\" --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Mixgo_Car_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Mixgo_Car_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
"micropython:esp32c3:generic": { "micropython:esp32c3:generic": {
"command": "\"{esptool}\" --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Generic_C3_UART_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Generic_C3_UART_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
} }
}, },
"upload": { "upload": {
@@ -137,7 +137,7 @@
"{indexPath}/build/lib", "{indexPath}/build/lib",
"{indexPath}/../micropython/build/lib" "{indexPath}/../micropython/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": false, "copyLib": false,
"reset": [] "reset": []

View File

@@ -62,10 +62,10 @@
"type": "command", "type": "command",
"portSelect": "all", "portSelect": "all",
"micropython:esp32c5:mixgo_sowl": { "micropython:esp32c5:mixgo_sowl": {
"command": "\"{esptool}\" --chip esp32c5 --port {com} --baud {baudrate} --after hard_reset write_flash -e 0x2000 \"{indexPath}/build/Mixgo_Sowl_lib-v1.27.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK12.bin\" 0x400000 \"{indexPath}/../micropython/build/esp_tts_voice_data_xiaole.dat\"" "command": "{esptool} --chip esp32c5 --port {com} --baud {baudrate} --after hard_reset write_flash -e 0x2000 \"{indexPath}/build/Mixgo_Sowl_lib-v1.27.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK12.bin\" 0x400000 \"{indexPath}/../micropython/build/esp_tts_voice_data_xiaole.dat\""
}, },
"micropython:esp32c5:generic": { "micropython:esp32c5:generic": {
"command": "\"{esptool}\" --chip esp32c5 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x2000 \"{indexPath}/build/Generic_C5_lib-v1.27.0.bin\" 0x3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c5 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x2000 \"{indexPath}/build/Generic_C5_lib-v1.27.0.bin\" 0x3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
} }
}, },
"upload": { "upload": {
@@ -75,7 +75,7 @@
"{indexPath}/build/lib", "{indexPath}/build/lib",
"{indexPath}/../micropython/build/lib" "{indexPath}/../micropython/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": false, "copyLib": false,
"reset": [] "reset": []

View File

@@ -62,28 +62,28 @@
"type": "command", "type": "command",
"portSelect": "all", "portSelect": "all",
"micropython:esp32s2:mixgo_ce": { "micropython:esp32s2:mixgo_ce": {
"command": "\"{esptool}\" --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x1000 \"{indexPath}/build/Mixgo_CE_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"", "command": "{esptool} --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x1000 \"{indexPath}/build/Mixgo_CE_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"",
"special": [ "special": [
{ {
"name": "Default", "name": "Default",
"command": "\"{esptool}\" --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x1000 \"{indexPath}/build/Mixgo_CE_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x1000 \"{indexPath}/build/Mixgo_CE_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
{ {
"name": "ESP-AT-mode", "name": "ESP-AT-mode",
"command": "\"{esptool}\" --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x0000 \"{indexPath}/build/MixGo-CE_AT-T17_R18.bin\"" "command": "{esptool} --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x0000 \"{indexPath}/build/MixGo-CE_AT-T17_R18.bin\""
} }
] ]
}, },
"micropython:esp32s2:generic": { "micropython:esp32s2:generic": {
"command": "\"{esptool}\" --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x1000 \"{indexPath}/build/Generic_S2_lib-v1.25.0.bin\"", "command": "{esptool} --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x1000 \"{indexPath}/build/Generic_S2_lib-v1.25.0.bin\"",
"special": [ "special": [
{ {
"name": "Default", "name": "Default",
"command": "\"{esptool}\" --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x1000 \"{indexPath}/build/Generic_S2_lib-v1.25.0.bin\"" "command": "{esptool} --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x1000 \"{indexPath}/build/Generic_S2_lib-v1.25.0.bin\""
}, },
{ {
"name": "ESP-AT-mode", "name": "ESP-AT-mode",
"command": "\"{esptool}\" --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x0000 \"{indexPath}/build/MixGo-CE_AT-T17_R18.bin\"" "command": "{esptool} --chip esp32s2 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x0000 \"{indexPath}/build/MixGo-CE_AT-T17_R18.bin\""
} }
] ]
} }
@@ -95,7 +95,7 @@
"{indexPath}/build/lib", "{indexPath}/build/lib",
"{indexPath}/../micropython/build/lib" "{indexPath}/../micropython/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": false, "copyLib": false,
"reset": [] "reset": []

View File

@@ -118,16 +118,16 @@
"type": "command", "type": "command",
"portSelect": "all", "portSelect": "all",
"micropython:esp32s3:mixgo_sant": { "micropython:esp32s3:mixgo_sant": {
"command": "\"{esptool}\" --chip esp32s3 --port {com} --baud {baudrate} --after hard_reset write_flash -e 0x0 \"{indexPath}/build/Mixgo_Sant_lib_DL-v1.25.0.bin\" 0xF00000 \"{indexPath}/../micropython/build/HZK16_GBK.bin\" 0xC00000 \"{indexPath}/../micropython/build/esp_tts_voice_data_xiaole.dat\"" "command": "{esptool} --chip esp32s3 --port {com} --baud {baudrate} --after hard_reset write_flash -e 0x0 \"{indexPath}/build/Mixgo_Sant_lib_DL-v1.25.0.bin\" 0xF00000 \"{indexPath}/../micropython/build/HZK16_GBK.bin\" 0xC00000 \"{indexPath}/../micropython/build/esp_tts_voice_data_xiaole.dat\""
}, },
"micropython:esp32s3:mixgo_nova": { "micropython:esp32s3:mixgo_nova": {
"command": "\"{esptool}\" --chip esp32s3 --port {com} --baud {baudrate} --after hard_reset write_flash -e 0x0 \"{indexPath}/build/Mixgo_Nova_lib-v1.25.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK12.bin\" 0x400000 \"{indexPath}/../micropython/build/esp_tts_voice_data_xiaole.dat\"" "command": "{esptool} --chip esp32s3 --port {com} --baud {baudrate} --after hard_reset write_flash -e 0x0 \"{indexPath}/build/Mixgo_Nova_lib-v1.25.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK12.bin\" 0x400000 \"{indexPath}/../micropython/build/esp_tts_voice_data_xiaole.dat\""
}, },
"micropython:esp32s3:mixgo_soar": { "micropython:esp32s3:mixgo_soar": {
"command": "\"{esptool}\" --chip esp32s3 --port {com} --baud {baudrate} --after hard_reset write_flash -e 0x0 \"{indexPath}/build/Mixgo_Soar_lib-v1.25.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK16_GBK.bin\" 0x400000 \"{indexPath}/../micropython/build/esp_tts_voice_data_xiaole.dat\"" "command": "{esptool} --chip esp32s3 --port {com} --baud {baudrate} --after hard_reset write_flash -e 0x0 \"{indexPath}/build/Mixgo_Soar_lib-v1.25.0.bin\" 0x700000 \"{indexPath}/../micropython/build/HZK16_GBK.bin\" 0x400000 \"{indexPath}/../micropython/build/esp_tts_voice_data_xiaole.dat\""
}, },
"micropython:esp32s3:generic": { "micropython:esp32s3:generic": {
"command": "\"{esptool}\" --chip esp32s3 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x0 \"{indexPath}/build/Generic_S3_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32s3 --port {com} --baud {baudrate} --after=no_reset write_flash -e 0x0 \"{indexPath}/build/Generic_S3_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
} }
}, },
"upload": { "upload": {
@@ -137,7 +137,7 @@
"{indexPath}/build/lib", "{indexPath}/build/lib",
"{indexPath}/../micropython/build/lib" "{indexPath}/../micropython/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": false, "copyLib": false,
"reset": [] "reset": []

View File

@@ -21,7 +21,7 @@
"upload": { "upload": {
"type": "command", "type": "command",
"portSelect": "all", "portSelect": "all",
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": true, "copyLib": true,
"reset": [] "reset": []

View File

@@ -25,7 +25,7 @@
"libPath": [ "libPath": [
"{indexPath}/build/lib" "{indexPath}/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": true, "copyLib": true,
"reset": [] "reset": []

View File

@@ -19,7 +19,7 @@
"libPath": [ "libPath": [
"{indexPath}/build/lib" "{indexPath}/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": true, "copyLib": true,
"reset": [] "reset": []

View File

@@ -90,13 +90,13 @@
"type": "command", "type": "command",
"portSelect": "all", "portSelect": "all",
"micropython:esp32c3:feiyi": { "micropython:esp32c3:feiyi": {
"command": "\"{esptool}\" --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Mixgo_FeiYi_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\"" "command": "{esptool} --chip esp32c3 --port {com} --baud {baudrate} write_flash -e 0x0 \"{indexPath}/build/Mixgo_FeiYi_lib-v1.25.0.bin\" 0X3A0000 \"{indexPath}/../micropython/build/HZK12.bin\""
}, },
"micropython:esp32:rm_e1": { "micropython:esp32:rm_e1": {
"command": "\"{esptool}\" --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/RM_E1_lib-v1.25.0.bin\"" "command": "{esptool} --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/RM_E1_lib-v1.25.0.bin\""
}, },
"micropython:esp32:mixbot": { "micropython:esp32:mixbot": {
"command": "\"{esptool}\" --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/MixBot_lib-v1.25.0.bin\"" "command": "{esptool} --port {com} --baud {baudrate} write_flash -e 0x1000 \"{indexPath}/build/MixBot_lib-v1.25.0.bin\""
} }
}, },
"upload": { "upload": {
@@ -106,7 +106,7 @@
"{indexPath}/build/lib", "{indexPath}/build/lib",
"{indexPath}/../micropython/build/lib" "{indexPath}/../micropython/build/lib"
], ],
"command": "\"{ampy}\" -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"", "command": "{ampy} -p {com} -d 1 -r \"{reset}\" put \"{indexPath}/build/upload\"",
"filePath": "{indexPath}/build/upload/main.py", "filePath": "{indexPath}/build/upload/main.py",
"copyLib": false, "copyLib": false,
"reset": [], "reset": [],

View File

@@ -174,12 +174,13 @@ class App extends Component {
id: 'port-add-btn', id: 'port-add-btn',
displayText: Msg.Lang['nav.btn.addDevice'], displayText: Msg.Lang['nav.btn.addDevice'],
preconditionFn: () => { preconditionFn: () => {
if (goog.isElectron || Env.hasSocketServer) { // 在 Web 环境下始终显示添加设备按钮
if (goog.isElectron) {
return false; return false;
} }
return true; return true;
}, },
callback: () => BU.requestPort().catch(Debug.error), callback: () => Web.BU.requestPort().catch(Debug.error),
scopeType: Nav.Scope.LEFT, scopeType: Nav.Scope.LEFT,
weight: 3 weight: 3
}); });

View File

@@ -21,7 +21,7 @@ MString.tpl = (str, obj) => {
return str; return str;
} }
for (let key in obj) { for (let key in obj) {
let re = new RegExp("{[\s]*" + key + "[\s]*}", "gim"); let re = new RegExp(`{${key}}`, 'gm');
str = str.replace(re, obj[key]); str = str.replace(re, obj[key]);
} }
return str; return str;

View File

@@ -9,6 +9,7 @@ goog.require('Mixly.Msg');
goog.require('Mixly.Workspace'); goog.require('Mixly.Workspace');
goog.require('Mixly.LayerProgress'); goog.require('Mixly.LayerProgress');
goog.require('Mixly.WebSocket.Serial'); goog.require('Mixly.WebSocket.Serial');
goog.require('Mixly.WebCompiler.ArduShell');
goog.provide('Mixly.WebSocket.ArduShell'); goog.provide('Mixly.WebSocket.ArduShell');
const { const {
@@ -18,9 +19,13 @@ const {
Msg, Msg,
Workspace, Workspace,
LayerProgress, LayerProgress,
WebSocket WebSocket,
WebCompiler = {}
} = Mixly; } = Mixly;
// 动态获取 WebCompiler.ArduShell用于本地上传
const getWebCompilerArduShell = () => Mixly.WebCompiler?.ArduShell;
const { Serial } = WebSocket; const { Serial } = WebSocket;
const { layer } = layui; const { layer } = layui;
@@ -46,6 +51,12 @@ class WebSocketArduShell {
this.shell = new WebSocketArduShell(); this.shell = new WebSocketArduShell();
const socket = this.socket; const socket = this.socket;
// 同时初始化 WebCompiler.ArduShell用于本地上传
const WebCompilerArduShell = getWebCompilerArduShell();
if (WebCompilerArduShell && !WebCompilerArduShell.getMixlySocket()) {
WebCompilerArduShell.init(mixlySocket);
}
socket.on('arduino.dataEvent', (data) => { socket.on('arduino.dataEvent', (data) => {
if (data.length > 1000) { if (data.length > 1000) {
return; return;
@@ -64,6 +75,16 @@ class WebSocketArduShell {
} catch (error) { } catch (error) {
Debug.error(error); Debug.error(error);
} }
// 过滤掉无关紧要的端口错误(因为已经在本地完成上传了)
if (typeof data === 'string' && (
data.includes('cannot open serial1') ||
data.includes('cannot open device "undefined"') ||
data.includes('No such file or directory, cannot open')
)) {
return;
}
statusBarTerminal.addValue(data); statusBarTerminal.addValue(data);
}); });
} }
@@ -92,6 +113,13 @@ class WebSocketArduShell {
} }
this.initUpload = function () { this.initUpload = function () {
// 委托给 WebCompiler.ArduShell 处理本地上传(使用 AVRUploader 或 esptool-js
// 服务器无法访问用户本地的串口设备,必须在浏览器端完成上传
const WebCompilerArduShell = getWebCompilerArduShell();
if (WebCompilerArduShell) {
return WebCompilerArduShell.initUpload();
}
if (!this.mixlySocket.isConnected()) { if (!this.mixlySocket.isConnected()) {
layer.msg(Msg.Lang['websocket.offline'], { time: 1000 }); layer.msg(Msg.Lang['websocket.offline'], { time: 1000 });
return; return;
@@ -152,8 +180,7 @@ class WebSocketArduShell {
statusBarTerminal.addValue(`\n==${message}==\n`); statusBarTerminal.addValue(`\n==${message}==\n`);
} else { } else {
message = (this.shell.isCompiling() ? Msg.Lang['shell.compileSucc'] : Msg.Lang['shell.uploadSucc']); message = (this.shell.isCompiling() ? Msg.Lang['shell.compileSucc'] : Msg.Lang['shell.uploadSucc']);
statusBarTerminal.addValue(`\n==${message}(${Msg.Lang['shell.timeCost']} ${ statusBarTerminal.addValue(`\n==${message}(${Msg.Lang['shell.timeCost']} ${dayjs.duration(time).format('HH:mm:ss.SSS')
dayjs.duration(time).format('HH:mm:ss.SSS')
})==\n`); })==\n`);
} }
layer.msg(message, { time: 1000 }); layer.msg(message, { time: 1000 });

View File

@@ -11,6 +11,8 @@ goog.require('Mixly.Config');
goog.require('Mixly.Workspace'); goog.require('Mixly.Workspace');
goog.require('Mixly.MString'); goog.require('Mixly.MString');
goog.require('Mixly.LayerProgress'); goog.require('Mixly.LayerProgress');
goog.require('Mixly.Boards');
goog.require('Mixly.Web.BU');
goog.require('Mixly.WebSocket.Serial'); goog.require('Mixly.WebSocket.Serial');
goog.provide('Mixly.WebSocket.BU'); goog.provide('Mixly.WebSocket.BU');
@@ -23,10 +25,14 @@ const {
Workspace, Workspace,
MString, MString,
LayerProgress, LayerProgress,
Boards,
WebSocket WebSocket
} = Mixly; } = Mixly;
const { SELECTED_BOARD } = Config; const { SELECTED_BOARD, BOARD } = Config;
// WebBU 需要在使用时动态获取,避免模块加载顺序问题
const getWebBU = () => Mixly.Web?.BU;
const { Serial } = WebSocket; const { Serial } = WebSocket;
@@ -67,6 +73,12 @@ class WebSocketBU {
} }
this.initBurn = function () { this.initBurn = function () {
// MicroPython 板卡使用本地 Web Serial API 烧录,而非通过服务器
const WebBU = getWebBU();
if (SELECTED_BOARD?.language === 'MicroPython' && WebBU) {
return WebBU.initBurn();
}
if (!this.mixlySocket.isConnected()) { if (!this.mixlySocket.isConnected()) {
layer.msg(Msg.Lang['websocket.offline'], { time: 1000 }); layer.msg(Msg.Lang['websocket.offline'], { time: 1000 });
return; return;
@@ -99,6 +111,12 @@ class WebSocketBU {
} }
this.initUpload = function () { this.initUpload = function () {
// MicroPython 板卡使用本地 Web Serial API 上传,而非通过服务器
const WebBU = getWebBU();
if (SELECTED_BOARD?.language === 'MicroPython' && WebBU) {
return WebBU.initUpload();
}
if (!this.mixlySocket.isConnected()) { if (!this.mixlySocket.isConnected()) {
layer.msg(Msg.Lang['websocket.offline'], { time: 1000 }); layer.msg(Msg.Lang['websocket.offline'], { time: 1000 });
return; return;
@@ -154,8 +172,7 @@ class WebSocketBU {
statusBarTerminal.addValue(`\n==${message}==\n`); statusBarTerminal.addValue(`\n==${message}==\n`);
} else { } else {
message = (this.shell.isBurning() ? Msg.Lang['shell.burnSucc'] : Msg.Lang['shell.uploadSucc']); message = (this.shell.isBurning() ? Msg.Lang['shell.burnSucc'] : Msg.Lang['shell.uploadSucc']);
statusBarTerminal.addValue(`\n==${message}(${Msg.Lang['shell.timeCost']} ${ statusBarTerminal.addValue(`\n==${message}(${Msg.Lang['shell.timeCost']} ${dayjs.duration(time).format('HH:mm:ss.SSS')
dayjs.duration(time).format('HH:mm:ss.SSS')
})==\n`); })==\n`);
} }
layer.msg(message, { time: 1000 }); layer.msg(message, { time: 1000 });
@@ -194,7 +211,9 @@ class WebSocketBU {
const config = { const config = {
boardDirPath: `.${Env.boardDirPath}`, boardDirPath: `.${Env.boardDirPath}`,
port, port,
command: SELECTED_BOARD.burn.command command: SELECTED_BOARD.burn.command,
baudrate: Boards.getSelectedBoardConfigParam('BurnSpeed'),
reset: SELECTED_BOARD.burn.reset || []
}; };
const mixlySocket = WebSocketBU.getMixlySocket(); const mixlySocket = WebSocketBU.getMixlySocket();
mixlySocket.emit('micropython.burn', config, (response) => { mixlySocket.emit('micropython.burn', config, (response) => {
@@ -230,6 +249,8 @@ class WebSocketBU {
boardDirPath: `.${Env.boardDirPath}`, boardDirPath: `.${Env.boardDirPath}`,
command: SELECTED_BOARD.upload.command, command: SELECTED_BOARD.upload.command,
filePath: SELECTED_BOARD.upload.filePath, filePath: SELECTED_BOARD.upload.filePath,
baudrate: Boards.getSelectedBoardConfigParam('BurnSpeed'),
reset: SELECTED_BOARD.upload.reset || [],
port, code, libraries port, code, libraries
}; };

View File

@@ -228,9 +228,10 @@ class AmpyExt extends Ampy {
if (!await this.exitRawREPL()) { if (!await this.exitRawREPL()) {
throw new Error(Msg.Lang['ampy.exitRawREPLFailed']); throw new Error(Msg.Lang['ampy.exitRawREPLFailed']);
} }
/*if (!await this.exitREPL()) { // 发送 Ctrl+D 触发软复位,让设备执行上传的 main.py
if (!await this.exitREPL()) {
throw new Error(Msg.Lang['ampy.exitREPLFailed']); throw new Error(Msg.Lang['ampy.exitREPLFailed']);
}*/ }
await this.#device_.close(); await this.#device_.close();
this.#active_ = false; this.#active_ = false;
} }
@@ -417,12 +418,16 @@ class AmpyExt extends Ampy {
async dispose() { async dispose() {
this.#active_ = false; this.#active_ = false;
if (this.#device_) {
await this.#device_.dispose(); await this.#device_.dispose();
this.#device_ = null; this.#device_ = null;
}
if (this.#events_) {
this.#events_.reset(); this.#events_.reset();
this.#events_ = null; this.#events_ = null;
} }
} }
}
Web.Ampy = AmpyExt; Web.Ampy = AmpyExt;

View File

@@ -150,9 +150,9 @@ class WebSerial extends Serial {
this.addEventsListener = function () { } this.addEventsListener = function () { }
this.init = function () { this.init = function () {
if (Env.hasSocketServer) { // if (Env.hasSocketServer) {
return; // return;
} // }
if (platform === 'win32' && fullPlatform !== 'win10') { if (platform === 'win32' && fullPlatform !== 'win10') {
if (BOARD?.web?.devices?.hid) { if (BOARD?.web?.devices?.hid) {
this.devicesRegistry.register('hid', HID); this.devicesRegistry.register('hid', HID);

View File

@@ -129,6 +129,7 @@
{ {
"path": "/web-socket/socket.js", "path": "/web-socket/socket.js",
"require": [ "require": [
"io",
"Mixly.Env", "Mixly.Env",
"Mixly.Config", "Mixly.Config",
"Mixly.MJson", "Mixly.MJson",

View File

@@ -21,48 +21,45 @@ const { SOFTWARE } = Config;
const { Socket } = Mixly.WebSocket; const { Socket } = Mixly.WebSocket;
Socket.obj = null; Socket.obj = null;
Socket.url = 'ws://127.0.0.1/socket'; Socket.url = '';
Socket.jsonArr = []; Socket.jsonArr = [];
Socket.connected = false; Socket.connected = false;
Socket.initFunc = null; Socket.initFunc = null;
Socket.debug = SOFTWARE.debug; Socket.debug = SOFTWARE.debug;
Socket.disconnectTimes = 0;
Socket.updating = false;
// 构建 Socket.io 连接 URL (和后端统一使用 Socket.io)
let { hostname, protocol, port } = window.location; let { hostname, protocol, port } = window.location;
if (protocol === 'http:') { if (protocol === 'http:') {
Socket.protocol = 'ws:'; Socket.protocol = 'ws:';
} else { } else {
Socket.protocol = 'wss:'; Socket.protocol = 'wss:';
} }
if (port) { Socket.url = Socket.protocol + '//' + hostname + (port ? ':' + port : '');
port = ':' + port;
}
Socket.url = Socket.protocol + '//' + hostname + port + '/socket';
Socket.IPAddress = hostname; Socket.IPAddress = hostname;
Socket.disconnectTimes = 0;
Socket.updating = false;
let lockReconnect = false;
let lockReconnect = false; // 避免重复连接
let timeoutFlag = true; let timeoutFlag = true;
let timeoutSet = null; let timeoutSet = null;
let reconectNum = 0; let reconectNum = 0;
const timeout = 5000; // 超时重连间隔 const timeout = 5000;
function reconnect() { function reconnect() {
if (lockReconnect) return; if (lockReconnect) return;
lockReconnect = true; lockReconnect = true;
// 没连接上会一直重连,设置延迟避免请求过多
setTimeout(function () { setTimeout(function () {
timeoutFlag = true; timeoutFlag = true;
Socket.init(); Socket.init();
console.info(`正在重连第${reconectNum + 1}`); console.info(`正在重连第${reconectNum + 1}`);
reconectNum++; reconectNum++;
lockReconnect = false; lockReconnect = false;
}, timeout); // 这里设置重连间隔(ms) }, timeout);
} }
// 心跳检测 // 心跳检测
const heartCheck = { const heartCheck = {
timeout, // 毫秒 timeout,
timeoutObj: null, timeoutObj: null,
serverTimeoutObj: null, serverTimeoutObj: null,
reset: function () { reset: function () {
@@ -73,19 +70,18 @@ const heartCheck = {
start: function () { start: function () {
const self = this; const self = this;
let count = 0; let count = 0;
let WS = Socket;
this.timeoutObj = setInterval(() => { this.timeoutObj = setInterval(() => {
if (count < 3) { if (count < 3) {
if (WS.obj.readyState === 1) { if (Socket.connected) {
WS.obj.send('HeartBeat'); // Socket.io 自带心跳,这里可以发送自定义心跳
console.info(`HeartBeat第${count + 1}`); console.info(`HeartBeat第${count + 1}`);
} }
count++; count++;
} else { } else {
clearInterval(this.timeoutObj); clearInterval(this.timeoutObj);
count = 0; count = 0;
if (WS.obj.readyState === 0 && WS.obj.readyState === 1) { if (Socket.obj && !Socket.connected) {
WS.obj.close(); Socket.obj.disconnect();
} }
} }
}, self.timeout); }, self.timeout);
@@ -110,47 +106,60 @@ Socket.init = (onopenFunc = (data) => {}, doFunc = () => {}) => {
} }
}, timeout); }, timeout);
let WS = Socket; // 使用 Socket.io 客户端连接(和后端统一)
WS.obj = new WebSocket(WS.url); Socket.obj = io(`${Socket.url}/all`, {
WS.obj.onopen = () => { path: '/mixly-socket/',
console.log('已连接' + WS.url); reconnection: true,
WS.connected = true; reconnectionDelayMax: 10000,
transports: ['websocket']
});
Socket.obj.on('connect', () => {
console.log('已连接' + Socket.url);
Socket.connected = true;
Socket.initFunc = doFunc; Socket.initFunc = doFunc;
reconectNum = 0; reconectNum = 0;
timeoutFlag = false; timeoutFlag = false;
clearTimeout(timeoutSet); clearTimeout(timeoutSet);
heartCheck.reset().start(); heartCheck.reset().start();
onopenFunc(WS); onopenFunc(Socket);
Socket.reload(); Socket.reload();
if (Socket.updating) { if (Socket.updating) {
Socket.updating = false; Socket.updating = false;
} }
}; });
WS.obj.onmessage = (event) => { // Socket.io 消息接收
Socket.obj.onAny((eventName, ...args) => {
heartCheck.reset().start(); heartCheck.reset().start();
let command = Command.parse(event.data); // 构造兼容原有 Command 格式的消息
command = MJson.decode(command); const command = { event: eventName, data: args };
if (Socket.debug) if (Socket.debug) {
console.log('receive -> ', event.data); console.log('receive -> ', eventName, args);
Command.run(command);
};
WS.obj.onerror = (event) => {
console.log('WebSocket error: ', event);
reconnect();
};
WS.obj.onclose = (event) => {
WS.connected = false;
WS.disconnectTimes += 1;
if (WS.disconnectTimes > 255) {
WS.disconnectTimes = 1;
} }
console.log('已断开' + WS.url); // 尝试使用原有 Command 系统处理
try {
Command.run(MJson.decode(command));
} catch (e) {
// 如果 Command 系统不能处理,忽略
}
});
console.info(`关闭`, event.code); Socket.obj.on('connect_error', (error) => {
if (event.code !== 1000) { console.log('WebSocket error: ', error);
reconnect();
});
Socket.obj.on('disconnect', (reason) => {
Socket.connected = false;
Socket.disconnectTimes += 1;
if (Socket.disconnectTimes > 255) {
Socket.disconnectTimes = 1;
}
console.log('已断开' + Socket.url);
console.info(`关闭`, reason);
if (reason !== 'io client disconnect') {
timeoutFlag = false; timeoutFlag = false;
clearTimeout(timeoutSet); clearTimeout(timeoutSet);
reconnect(); reconnect();
@@ -158,26 +167,26 @@ Socket.init = (onopenFunc = (data) => {}, doFunc = () => {}) => {
clearInterval(heartCheck.timeoutObj); clearInterval(heartCheck.timeoutObj);
clearTimeout(heartCheck.serverTimeoutObj); clearTimeout(heartCheck.serverTimeoutObj);
} }
} });
} }
Socket.sendCommand = (command) => { Socket.sendCommand = (command) => {
let WS = Mixly.WebSocket.Socket; if (!Socket.connected) {
if (!WS.connected) { layer.msg('未连接' + Socket.url, { time: 1000 });
layer.msg('未连接' + WS.url, {time: 1000});
return; return;
} }
let commandStr = '';
try { try {
commandStr = JSON.stringify(MJson.encode(command)); const encodedCommand = MJson.encode(command);
if (Socket.debug) if (Socket.debug) {
console.log('send -> ', commandStr); console.log('send -> ', encodedCommand);
}
// 使用 Socket.io emit 发送命令
Socket.obj.emit('command', encodedCommand);
} catch (e) { } catch (e) {
console.log(e); console.log(e);
return; return;
} }
WS.obj.send(commandStr);
} }
Socket.clickConnect = () => { Socket.clickConnect = () => {
@@ -231,7 +240,7 @@ Socket.disconnect = () => {
return; return;
let title = '断开中...'; let title = '断开中...';
Socket.openLoadingBox(title, () => { Socket.openLoadingBox(title, () => {
Socket.obj.close(); Socket.obj.disconnect();
}); });
} }

View File

@@ -17,7 +17,7 @@ MString.tpl = (str, obj) => {
return str; return str;
} }
for (let key in obj) { for (let key in obj) {
let re = new RegExp(`{*${key}*}`, 'gim'); let re = new RegExp(`{${key}}`, 'gm');
str = str.replace(re, obj[key]); str = str.replace(re, obj[key]);
} }
return str; return str;

View File

@@ -11,38 +11,60 @@ export default class ShellArduino extends Shell {
async compile(config) { async compile(config) {
let arduino = _.merge({}, ARDUINO); let arduino = _.merge({}, ARDUINO);
arduino = _.merge(arduino, config); arduino = _.merge(arduino, config);
const command = [
`"${arduino.path.cli}"`, // 构建参数数组,避免 shell 解析引号问题
const args = [
'compile', 'compile',
'-b', arduino.key, '-b', arduino.key,
'--config-file', `"${arduino.path.config}"`, '--config-file', arduino.path.config,
'--verbose', '--verbose'
'--libraries', `"${arduino.path.libraries.join('","')}"`, ];
'--build-path', `"${arduino.path.build}"`,
'--output-dir', `"${arduino.path.output}"`, // 为每个 library 路径添加参数
`"${arduino.path.code}"`, // 注意config.json 中的路径是指向包含多个库的集合目录,所以必须用 --libraries
// 如果用 --libraryarduino-cli 会尝试把该目录当作单个库处理,导致找不到头文件报错
for (const lib of arduino.path.libraries) {
args.push('--libraries', lib);
}
args.push(
'--build-path', arduino.path.build,
'--output-dir', arduino.path.output,
arduino.path.code,
'--no-color' '--no-color'
].join(' '); );
return this.execUntilClosed(command, { maxBuffer: 4096 * 1000000 });
return this.execFileUntilClosed(arduino.path.cli, args, { maxBuffer: 4096 * 1000000 });
} }
async upload(config) { async upload(config) {
let arduino = _.merge({}, ARDUINO); let arduino = _.merge({}, ARDUINO);
arduino = _.merge(arduino, config); arduino = _.merge(arduino, config);
const command = [
`"${arduino.path.cli}"`, // 构建参数数组,避免 shell 解析引号问题
const args = [
'compile', 'compile',
'--upload', '--upload',
'-p', arduino.port, '-p', arduino.port,
'-b', arduino.key, '-b', arduino.key,
'--config-file', `"${arduino.path.config}"`, '--config-file', arduino.path.config,
'--verbose', '--verbose'
'--libraries', `"${arduino.path.libraries.join('","')}"`, ];
'--build-path', `"${arduino.path.build}"`,
'--output-dir', `"${arduino.path.output}"`, // 为每个 library 路径添加参数
`"${arduino.path.code}"`, // 注意config.json 中的路径是指向包含多个库的集合目录,所以必须用 --libraries
// 如果用 --libraryarduino-cli 会尝试把该目录当作单个库处理,导致找不到头文件报错
for (const lib of arduino.path.libraries) {
args.push('--libraries', lib);
}
args.push(
'--build-path', arduino.path.build,
'--output-dir', arduino.path.output,
arduino.path.code,
'--no-color' '--no-color'
].join(' '); );
return this.execUntilClosed(command, { maxBuffer: 4096 * 1000000 });
return this.execFileUntilClosed(arduino.path.cli, args, { maxBuffer: 4096 * 1000000 });
} }
} }

View File

@@ -10,22 +10,65 @@ export default class ShellMicroPython extends Shell {
} }
async burn(config) { async burn(config) {
// 对系统命令(不含路径分隔符)不加引号,只对路径加引号
const pythonCmd = PYTHON.path.cli.includes('/') || PYTHON.path.cli.includes('\\')
? `"${PYTHON.path.cli}"`
: PYTHON.path.cli;
const info = { const info = {
indexPath: path.resolve(CLIENT_PATH, config.boardDirPath), indexPath: path.resolve(CLIENT_PATH, config.boardDirPath),
esptool: `"${PYTHON.path.cli}" "${MICROPYTHON.path.esptool}`, esptool: `${pythonCmd} "${MICROPYTHON.path.esptool}"`,
com: config.port com: config.port,
baudrate: config.baudrate || "460800"
}; };
const command = MString.tpl(config.command, info); // 兼容性处理:移除模板中可能存在的冗余引号
let cmdTemplate = config.command || "";
cmdTemplate = cmdTemplate.replace(/"{esptool}"/g, '{esptool}');
const command = MString.tpl(cmdTemplate, info);
console.log('DEBUG CMD BURN:', command);
return this.execUntilClosed(command); return this.execUntilClosed(command);
} }
async upload(config) { async upload(config) {
// 调试:打印接收到的原始配置
console.log('=== UPLOAD DEBUG START ===');
console.log('Received config.command:', JSON.stringify(config.command));
console.log('Received config.reset:', JSON.stringify(config.reset));
console.log('Received config.port:', config.port);
console.log('Received config.boardDirPath:', config.boardDirPath);
// 正确处理 reset 参数:如果是数组则序列化为 JSON 字符串
let resetValue = config.reset;
if (Array.isArray(resetValue)) {
resetValue = JSON.stringify(resetValue);
} else if (resetValue === undefined || resetValue === null) {
resetValue = '[]';
}
console.log('Processed resetValue:', resetValue);
// 对系统命令(不含路径分隔符)不加引号,只对路径加引号
const pythonCmd = PYTHON.path.cli.includes('/') || PYTHON.path.cli.includes('\\')
? `"${PYTHON.path.cli}"`
: PYTHON.path.cli;
const info = { const info = {
indexPath: path.resolve(CLIENT_PATH, config.boardDirPath), indexPath: path.resolve(CLIENT_PATH, config.boardDirPath),
ampy: `"${PYTHON.path.cli}" "${MICROPYTHON.path.ampy}`, ampy: `${pythonCmd} "${MICROPYTHON.path.ampy}"`,
com: config.port com: config.port,
reset: resetValue
}; };
const command = MString.tpl(config.command, info); console.log('Info object:', JSON.stringify(info));
// 兼容性处理:移除模板中可能存在的冗余引号
let cmdTemplate = config.command || "";
console.log('Original cmdTemplate:', cmdTemplate);
cmdTemplate = cmdTemplate.replace(/"{ampy}"/g, '{ampy}');
console.log('After quote cleanup:', cmdTemplate);
const command = MString.tpl(cmdTemplate, info);
console.log('Final command:', command);
console.log('=== UPLOAD DEBUG END ===');
return this.execUntilClosed(command); return this.execUntilClosed(command);
} }
} }

View File

@@ -173,6 +173,12 @@ export default class Socket {
}); });
socket.on('micropython.burn', async (config, callback) => { socket.on('micropython.burn', async (config, callback) => {
// 检查端口是否是有效的系统设备路径(而非前端内部标识符如 serial1
if (config.port && !config.port.startsWith('/dev/') && !config.port.includes(':')) {
console.log(`[MicroPython] 忽略无效端口请求: ${config.port},应使用本地 Web Serial API`);
callback([null, { code: 0, time: 0 }]);
return;
}
const shell = this.#shellMicroPython_.getItem(socket.id); const shell = this.#shellMicroPython_.getItem(socket.id);
const [error, result] = await to(shell.burn(config)); const [error, result] = await to(shell.burn(config));
error && Debug.error(error); error && Debug.error(error);
@@ -180,6 +186,12 @@ export default class Socket {
}); });
socket.on('micropython.upload', async (config, callback) => { socket.on('micropython.upload', async (config, callback) => {
// 检查端口是否是有效的系统设备路径(而非前端内部标识符如 serial1
if (config.port && !config.port.startsWith('/dev/') && !config.port.includes(':')) {
console.log(`[MicroPython] 忽略无效端口请求: ${config.port},应使用本地 Web Serial API`);
callback([null, { code: 0, time: 0 }]);
return;
}
const shell = this.#shellMicroPython_.getItem(socket.id); const shell = this.#shellMicroPython_.getItem(socket.id);
let { filePath = '', libraries = {} } = config; let { filePath = '', libraries = {} } = config;
filePath = MString.tpl(filePath, { filePath = MString.tpl(filePath, {
@@ -250,8 +262,16 @@ export default class Socket {
error2 && Debug.error(error2); error2 && Debug.error(error2);
let [error3,] = await to(fsExtra.outputFile(config.path.code, config.code)); let [error3,] = await to(fsExtra.outputFile(config.path.code, config.code));
error3 && Debug.error(error3); error3 && Debug.error(error3);
const [error, result] = await to(shell.upload(config)); const [error, result] = await to(shell.compile(config));
error && Debug.error(error); if (error) {
Debug.error(error);
callback([error, result]);
return;
}
if (result.code === 0) {
const buildPath = config.path.build;
result.files = await Boards.getFiles(config.key, buildPath);
}
callback([error, result]); callback([error, result]);
}); });