tirtc-device-builder 0.9.6 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codex-plugin/plugin.json +1 -1
- package/CHANGELOG.md +45 -0
- package/README.md +16 -15
- package/bin/esp32-kit-metadata.js +34 -7
- package/bin/install-esp32-kit.js +50 -19
- package/package.json +1 -1
- package/skills/tirtc-esp32-builder/SKILL.md +4 -3
- package/skills/tirtc-esp32-builder/USAGE.md +19 -1
- package/skills/tirtc-esp32-builder/VERSION +1 -1
- package/skills/tirtc-esp32-builder/assets/developer-intake-prompt.md +1 -1
- package/skills/tirtc-esp32-builder/assets/lckfb-szpi-esp32s3-portable-prompt.md +5 -5
- package/skills/tirtc-esp32-builder/knowledge/waveshare-esp32-p4-wifi6-touch-lcd-3.5/knowledge.md +9 -0
- package/skills/tirtc-esp32-builder/references/environment.md +16 -7
- package/skills/tirtc-esp32-builder/references/hardware-ir.md +3 -3
- package/skills/tirtc-esp32-builder/scripts/doctor.py +38 -8
- package/skills/tirtc-esp32-builder/scripts/hardware_ir.py +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,51 @@
|
|
|
2
2
|
|
|
3
3
|
This project follows Semantic Versioning.
|
|
4
4
|
|
|
5
|
+
## 0.10.0
|
|
6
|
+
|
|
7
|
+
- Align the Kit's provisioning and device-binding implementation with the
|
|
8
|
+
reference XiaoTai product firmware (ships in the ESP32-S3 Device Kit
|
|
9
|
+
1.2.0 release, tagged separately):
|
|
10
|
+
- Wi-Fi provisioning: the embedded setup page gains a live scan list
|
|
11
|
+
(`POST /api/scan`, `GET /api/networks`), saved-network history with
|
|
12
|
+
`use_saved` password reuse, portal isolation to the SoftAP interface and
|
|
13
|
+
Origin checks on writes, exponential retry (1/2/4/8/15/30 s) with the
|
|
14
|
+
portal opened alongside retries after 5 consecutive failures, a manual
|
|
15
|
+
`wifi-change` entrance that retains credentials, and a station fallback
|
|
16
|
+
DNS slot (`CONFIG_WIFI_MANAGER_FALLBACK_DNS_IPV4`, default 223.5.5.5).
|
|
17
|
+
- Device binding: fresh-boot SNTP is required before any authentication;
|
|
18
|
+
the verification-code TTS endpoint (`GET /v1/device/tts`) is supported
|
|
19
|
+
behind a prompt callback (NULL by default; headless devices keep the
|
|
20
|
+
serial code); binding failures and rebinds can be retried without a
|
|
21
|
+
reboot (`bind-retry`); an `unbind` signal or a 6006 token response now
|
|
22
|
+
triggers identity reconciliation and a signed rebind that retains the
|
|
23
|
+
stored identity instead of clearing NVS and restarting.
|
|
24
|
+
- Shared components (`wifi_manager`, `platform_client`, `runtime_config`)
|
|
25
|
+
keep dual-target ESP32-S3/ESP32-P4 conditionals so future P4 ports can
|
|
26
|
+
reuse them unchanged.
|
|
27
|
+
- Extend the Kit packing contract and generator tests to cover the new
|
|
28
|
+
portal endpoints, history component, embedded setup page, and portal
|
|
29
|
+
isolation; keep the `XiaoTai-` / open-auth / 192.168.6.1 SoftAP contract.
|
|
30
|
+
- Add the ESP32-P4 Device Kit: TiRTC P4 SDK 2.5.0 (vendor baseline
|
|
31
|
+
`9b4e35c7`, IDF 5.5.4 / 1000 Hz / LWIP_MAX_SOCKETS=10 contract), the
|
|
32
|
+
XiaoTai P4 1.4.0 reference firmware imported as `device-sim-p4` (shared
|
|
33
|
+
transport components resolve from the S3 reference; the P4 `tirtc_sdk`
|
|
34
|
+
wrapper re-pins the archive), generator `--target esp32p4` copy mode,
|
|
35
|
+
per-target pack/metadata/installer plumbing, a `publish-p4` release job
|
|
36
|
+
that fails until the P4 kit is pinned, and P4-aware Doctor SDK resolution
|
|
37
|
+
and contract keys. Managed `setup` stays ESP32-S3-only.
|
|
38
|
+
- Device Kit releases (1.2.0 for S3, 1.0.0 for P4) and checksum pinning
|
|
39
|
+
are deferred to their release workflows; no sha256 is fabricated in this
|
|
40
|
+
changelog. Until the S3 Kit 1.2.0 is tagged, managed setup keeps
|
|
41
|
+
installing the pinned 1.1.7 Kit.
|
|
42
|
+
|
|
43
|
+
## 0.9.7
|
|
44
|
+
|
|
45
|
+
- Pin ESP32-S3 Device Kit 1.1.7 with the `XiaoTai-` SoftAP name and the
|
|
46
|
+
provisioning DHCP state fix; keep TiRTC C SDK 2.5.0.
|
|
47
|
+
- Align generated-project instructions, Hardware IR validation, and Kit
|
|
48
|
+
packaging checks with the SoftAP name, and cover DHCP initial states.
|
|
49
|
+
|
|
5
50
|
## 0.9.6
|
|
6
51
|
|
|
7
52
|
- Pin ESP32-S3 Device Kit 1.1.6 with TiRTC C SDK 2.5.0 and verify the
|
package/README.md
CHANGED
|
@@ -8,11 +8,12 @@ TiRTC Device Builder 用于把 ESP32-S3/ESP32-P4 开发板接入 TiRTC。输入
|
|
|
8
8
|
|---|---|---|
|
|
9
9
|
| `tirtc-esp32-builder` | ESP32-S3 / ESP32-P4、ESP-IDF 5.5.x | 板型识别、Hardware IR、工程生成/移植、H5/AI/设备互呼/微信 VoIP、AEC 门禁、编译烧录和分层验收 |
|
|
10
10
|
|
|
11
|
-
H5/AI 的 ESP32-S3 托管模板、协议文档和 TiRTC SDK 已打包在独立的 ESP32 Device Kit 中,安装时会自动下载并校验。ESP32 示例源码由本仓库的 `kit-src/` 维护;设备互呼或微信 VoIP 的移植可参考其中的独立示例。ESP32-P4
|
|
11
|
+
H5/AI 的 ESP32-S3 托管模板、协议文档和 TiRTC SDK 已打包在独立的 ESP32 Device Kit 中,安装时会自动下载并校验。ESP32 示例源码由本仓库的 `kit-src/` 维护;设备互呼或微信 VoIP 的移植可参考其中的独立示例。ESP32-P4 使用独立发布的 `tirtc-esp32p4-kit`(小钛 P4 参考固件:hosted C6 Wi-Fi + LVGL UI + 摄像头 + P4 SDK 2.5.0),通过生成器 `--target esp32p4` 复制生成,不能复用 S3 预编译库。
|
|
12
12
|
|
|
13
13
|
- npm 包:[tirtc-device-builder](https://www.npmjs.com/package/tirtc-device-builder)
|
|
14
14
|
- GitHub 仓库:[tangeai/tirtc-device-builder](https://github.com/tangeai/tirtc-device-builder)
|
|
15
|
-
- ESP32 Device Kit:[kit-esp32s3-v1.1.
|
|
15
|
+
- ESP32 Device Kit:[kit-esp32s3-v1.1.7](https://github.com/tangeai/tirtc-device-builder/releases/tag/kit-esp32s3-v1.1.7)
|
|
16
|
+
- ESP32-P4 Device Kit:`tirtc-esp32p4-kit`(首次发布前以 `kit-esp32p4-v*` tag 发布的 GitHub Release 为准)
|
|
16
17
|
|
|
17
18
|
文档导航:
|
|
18
19
|
|
|
@@ -283,7 +284,7 @@ board-materials/
|
|
|
283
284
|
| ESP-IDF | 5.5.x |
|
|
284
285
|
| 自动安装版本 | ESP-IDF v5.5.4 |
|
|
285
286
|
| 本仓库源码与本地打包使用的 TiRTC SDK | `espressif-esp32s3/2.5.0` |
|
|
286
|
-
| ESP32 Device Kit | 1.1.
|
|
287
|
+
| ESP32 Device Kit | 1.1.7(内含 TiRTC SDK 2.5.0) |
|
|
287
288
|
| Node.js | 18 或更高版本 |
|
|
288
289
|
| 支持自动安装的系统 | Linux、WSL、macOS |
|
|
289
290
|
| 原生 Windows | 使用 Espressif 官方安装器准备 ESP-IDF,再重新运行检查 |
|
|
@@ -394,7 +395,7 @@ Cline 当前还需要在 `Settings → Features → Enable Skills` 中启用实
|
|
|
394
395
|
|---|---|
|
|
395
396
|
| Agent Skill | 上表中所选目录下的 `tirtc-esp32-builder` |
|
|
396
397
|
| 托管根目录 | `~/.tirtc-device-builder` |
|
|
397
|
-
| Device Kit | `~/.tirtc-device-builder/kits/esp32s3/1.1.
|
|
398
|
+
| Device Kit | `~/.tirtc-device-builder/kits/esp32s3/1.1.7` |
|
|
398
399
|
| ESP-IDF | `~/.tirtc-device-builder/esp-idf-v5.5.4` |
|
|
399
400
|
| Espressif 工具 | `~/.tirtc-device-builder/espressif` |
|
|
400
401
|
| 安装记录 | `~/.tirtc-device-builder/config.json` |
|
|
@@ -439,7 +440,7 @@ npx --yes tirtc-device-builder@latest setup esp32 --install \
|
|
|
439
440
|
|
|
440
441
|
```bash
|
|
441
442
|
npx --yes tirtc-device-builder@latest setup esp32 --install \
|
|
442
|
-
--kit-archive /absolute/path/tirtc-esp32s3-kit-1.1.
|
|
443
|
+
--kit-archive /absolute/path/tirtc-esp32s3-kit-1.1.7.tar.gz
|
|
443
444
|
```
|
|
444
445
|
|
|
445
446
|
安装器仍会核对固定的 SHA-256、目录结构、清单和每个资源文件,不接受未经验证的同名压缩包。
|
|
@@ -654,7 +655,7 @@ bootloader、分区表和应用镜像;无需手工维护多条 `esptool.py`
|
|
|
654
655
|
|
|
655
656
|
### Wi-Fi 凭证和设备绑定
|
|
656
657
|
|
|
657
|
-
SoftAP 是可选方案,不是接入前提。Hardware IR 要根据 BSP 的实际能力和产品要求,选择 SoftAP、BLE、SmartConfig、安全工厂/NVS 注入、不纳入版本控制的开发配置,或有文档的自定义方案。若选择 SoftAP,热点名必须以 `
|
|
658
|
+
SoftAP 是可选方案,不是接入前提。Hardware IR 要根据 BSP 的实际能力和产品要求,选择 SoftAP、BLE、SmartConfig、安全工厂/NVS 注入、不纳入版本控制的开发配置,或有文档的自定义方案。若选择 SoftAP,热点名必须以 `XiaoTai-` 开头、使用开放认证(无需密码),AP 网关和配网页面地址固定为 `192.168.6.1`(`http://192.168.6.1`),并通过通配 DNS 和 HTTP 回退启用 captive portal 自动发现。DHCP Option 114 只用于 RFC 8908 HTTPS/JSON API,不能指向本地 HTML 页面。系统没有自动弹窗时仍可手动打开该 HTTP 地址;HTTPS 不能透明重定向。这些值要写入 Hardware IR 并通过门禁;目标 WLAN 的 SSID 和密码仍不得写死在源码中。
|
|
658
659
|
|
|
659
660
|
无论选择哪种方法,都要有当前 PCB/BSP 的支持证据,凭证不能进入 Git、源码或报告,并且要保留清除或重配入口。没有 SoftAP、但支持工厂 NVS 注入的设备同样可以接入。只要工程提交了明文密码,Hardware IR v2 门禁就会判为 `BLOCKED`。
|
|
660
661
|
|
|
@@ -822,7 +823,7 @@ npx --yes tirtc-device-builder@latest setup esp32 --install --force-skill
|
|
|
822
823
|
|
|
823
824
|
```bash
|
|
824
825
|
npx --yes tirtc-device-builder@latest setup esp32 --install \
|
|
825
|
-
--kit-archive /absolute/path/tirtc-esp32s3-kit-1.1.
|
|
826
|
+
--kit-archive /absolute/path/tirtc-esp32s3-kit-1.1.7.tar.gz
|
|
826
827
|
```
|
|
827
828
|
|
|
828
829
|
安装器会校验 SHA-256 和内部文件清单。如果校验不一致,请重新获取官方 Release 附件,不要跳过校验。
|
|
@@ -933,25 +934,25 @@ python3 ~/.codex/skills/.system/plugin-creator/scripts/validate_plugin.py .
|
|
|
933
934
|
|
|
934
935
|
```bash
|
|
935
936
|
npm run pack:esp32-kit -- \
|
|
936
|
-
--kit-version 1.1.
|
|
937
|
+
--kit-version 1.1.7
|
|
937
938
|
```
|
|
938
939
|
|
|
939
940
|
输出位于 `dist/`:
|
|
940
941
|
|
|
941
942
|
```text
|
|
942
|
-
tirtc-esp32s3-kit-1.1.
|
|
943
|
-
tirtc-esp32s3-kit-1.1.
|
|
943
|
+
tirtc-esp32s3-kit-1.1.7.tar.gz
|
|
944
|
+
tirtc-esp32s3-kit-1.1.7.tar.gz.sha256
|
|
944
945
|
```
|
|
945
946
|
|
|
946
947
|
校验后推送独立的 `kit-esp32s3-v<version>` 标签。`publish-kit.yml` 会从 metadata 固定的本仓库源码 commit 重建压缩包、核对 SHA-256,并使用 GitHub Actions token 创建 Release:
|
|
947
948
|
|
|
948
949
|
```bash
|
|
949
950
|
cd dist
|
|
950
|
-
sha256sum -c tirtc-esp32s3-kit-1.1.
|
|
951
|
+
sha256sum -c tirtc-esp32s3-kit-1.1.7.tar.gz.sha256
|
|
951
952
|
cd ..
|
|
952
953
|
|
|
953
|
-
git tag -a kit-esp32s3-v1.1.
|
|
954
|
-
git push origin kit-esp32s3-v1.1.
|
|
954
|
+
git tag -a kit-esp32s3-v1.1.7 -m "TiRTC ESP32-S3 Device Kit 1.1.7"
|
|
955
|
+
git push origin kit-esp32s3-v1.1.7
|
|
955
956
|
```
|
|
956
957
|
|
|
957
958
|
metadata 中的版本、标签、本仓库源码 commit 和期望 SHA-256 必须与本地可复现打包结果一致;工作流不会从浮动的 `main` 取发布内容。
|
|
@@ -962,8 +963,8 @@ metadata 中的版本、标签、本仓库源码 commit 和期望 SHA-256 必须
|
|
|
962
963
|
|
|
963
964
|
```bash
|
|
964
965
|
npm test
|
|
965
|
-
git tag -a v0.9.
|
|
966
|
-
git push origin v0.9.
|
|
966
|
+
git tag -a v0.9.7 -m "v0.9.7"
|
|
967
|
+
git push origin v0.9.7
|
|
967
968
|
```
|
|
968
969
|
|
|
969
970
|
不要重复发布已经存在的 npm 版本。版本变化同步更新 `package.json`、`.codex-plugin/plugin.json` 和发布说明。
|
|
@@ -1,10 +1,37 @@
|
|
|
1
1
|
export const ESP32_KIT = Object.freeze({
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
target: "esp32s3",
|
|
3
|
+
platform: "espressif-esp32s3",
|
|
4
|
+
archiveName: "tirtc-esp32s3-kit-1.1.7.tar.gz",
|
|
5
|
+
archiveRoot: "tirtc-esp32s3-kit-1.1.7",
|
|
6
|
+
releaseTag: "kit-esp32s3-v1.1.7",
|
|
7
|
+
sha256: "61be93e5b3648c067a581195d2146ac57f748c2f356e9b681a0926f301cf6a8b",
|
|
6
8
|
sdkVersion: "2.5.0",
|
|
7
|
-
sourceCommit: "
|
|
8
|
-
url: "https://github.com/tangeai/tirtc-device-builder/releases/download/kit-esp32s3-v1.1.
|
|
9
|
-
version: "1.1.
|
|
9
|
+
sourceCommit: "50be0b4b6ad83ca376e010ebb7256db4fb6debcd",
|
|
10
|
+
url: "https://github.com/tangeai/tirtc-device-builder/releases/download/kit-esp32s3-v1.1.7/tirtc-esp32s3-kit-1.1.7.tar.gz",
|
|
11
|
+
version: "1.1.7",
|
|
12
|
+
released: true,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
* The ESP32-P4 Device Kit is pinned by its first release. Until the release
|
|
17
|
+
* workflow publishes and pins it, sha256/sourceCommit/url stay null and the
|
|
18
|
+
* publish-p4 job fails any premature kit-esp32p4-v* tag. Nothing is fabricated.
|
|
19
|
+
*/
|
|
20
|
+
export const ESP32_P4_KIT = Object.freeze({
|
|
21
|
+
target: "esp32p4",
|
|
22
|
+
platform: "espressif-esp32p4",
|
|
23
|
+
archiveName: "tirtc-esp32p4-kit-1.0.0.tar.gz",
|
|
24
|
+
archiveRoot: "tirtc-esp32p4-kit-1.0.0",
|
|
25
|
+
releaseTag: "kit-esp32p4-v1.0.0",
|
|
26
|
+
sha256: null,
|
|
27
|
+
sdkVersion: "2.5.0",
|
|
28
|
+
sourceCommit: null,
|
|
29
|
+
url: null,
|
|
30
|
+
version: "1.0.0",
|
|
31
|
+
released: false,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export const ESP32_KITS = Object.freeze({
|
|
35
|
+
esp32s3: ESP32_KIT,
|
|
36
|
+
esp32p4: ESP32_P4_KIT,
|
|
10
37
|
});
|
package/bin/install-esp32-kit.js
CHANGED
|
@@ -16,15 +16,30 @@ import {
|
|
|
16
16
|
import { tmpdir } from "node:os";
|
|
17
17
|
import { basename, dirname, join, relative, resolve } from "node:path";
|
|
18
18
|
import { fileURLToPath } from "node:url";
|
|
19
|
-
import { ESP32_KIT } from "./esp32-kit-metadata.js";
|
|
19
|
+
import { ESP32_KIT, ESP32_KITS } from "./esp32-kit-metadata.js";
|
|
20
20
|
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
const REQUIRED_FILES_BY_TARGET = {
|
|
22
|
+
esp32s3: [
|
|
23
|
+
"manifest.json",
|
|
24
|
+
"device-sim/scripts/create_esp32_project.py",
|
|
25
|
+
"device-sim/templates/esp32-h5-ai/CMakeLists.txt",
|
|
26
|
+
"device-sim/templates/esp32-h5-ai/platform-media-contract.json",
|
|
27
|
+
"device-sim/templates/esp32-h5-ai/tirtc-runtime-contract.json",
|
|
28
|
+
],
|
|
29
|
+
esp32p4: [
|
|
30
|
+
"manifest.json",
|
|
31
|
+
"device-sim/scripts/create_esp32_project.py",
|
|
32
|
+
"device-sim/device-sim-p4/CMakeLists.txt",
|
|
33
|
+
"device-sim/device-sim-p4/sdkconfig.defaults",
|
|
34
|
+
"device-sim/device-sim-p4/dependencies.lock",
|
|
35
|
+
"device-sim/device-sim-esp32/components/wifi_manager/src/wifi_manager.c",
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const SDK_VERSION_PATTERN_BY_TARGET = {
|
|
40
|
+
esp32s3: /^(?:2\.3\.0|2\.5\.0)$/,
|
|
41
|
+
esp32p4: /^2\.5\.0$/,
|
|
42
|
+
};
|
|
28
43
|
|
|
29
44
|
function hashFile(path) {
|
|
30
45
|
return createHash("sha256").update(readFileSync(path)).digest("hex");
|
|
@@ -77,7 +92,8 @@ function assertNoLinks(root, current = root) {
|
|
|
77
92
|
}
|
|
78
93
|
|
|
79
94
|
function validateExtractedKit(root, metadata) {
|
|
80
|
-
const
|
|
95
|
+
const requiredFiles = REQUIRED_FILES_BY_TARGET[metadata.target] ?? [];
|
|
96
|
+
const missing = requiredFiles.filter((path) => !existsSync(join(root, path)));
|
|
81
97
|
if (missing.length > 0) {
|
|
82
98
|
throw new Error(`Device Kit is incomplete: ${missing.join(", ")}`);
|
|
83
99
|
}
|
|
@@ -95,12 +111,15 @@ function validateExtractedKit(root, metadata) {
|
|
|
95
111
|
`Device Kit version mismatch: expected ${metadata.version}, got ${manifest.kit_version}`,
|
|
96
112
|
);
|
|
97
113
|
}
|
|
98
|
-
|
|
99
|
-
|
|
114
|
+
const sdkPattern = SDK_VERSION_PATTERN_BY_TARGET[metadata.target];
|
|
115
|
+
if (!sdkPattern ||
|
|
116
|
+
manifest.target !== metadata.target ||
|
|
117
|
+
manifest.platform !== metadata.platform ||
|
|
118
|
+
!sdkPattern.test(manifest.tirtc_sdk_version) ||
|
|
100
119
|
(metadata.sdkVersion && manifest.tirtc_sdk_version !== metadata.sdkVersion)) {
|
|
101
120
|
throw new Error("Device Kit target or TiRTC SDK version is incompatible");
|
|
102
121
|
}
|
|
103
|
-
const sdkRoot = `device-sim/sdk
|
|
122
|
+
const sdkRoot = `device-sim/sdk/${metadata.platform}/${manifest.tirtc_sdk_version}`;
|
|
104
123
|
const sdkFiles = [
|
|
105
124
|
`${sdkRoot}/include/tirtc/tiRTC.h`,
|
|
106
125
|
`${sdkRoot}/lib/libTiRTC.a`,
|
|
@@ -170,17 +189,20 @@ async function download(url, destination) {
|
|
|
170
189
|
function parseArgs(args) {
|
|
171
190
|
let archive = null;
|
|
172
191
|
let target = null;
|
|
192
|
+
let kit = "esp32s3";
|
|
173
193
|
for (let index = 0; index < args.length; index += 1) {
|
|
174
194
|
const argument = args[index];
|
|
175
|
-
if (argument === "--archive" || argument === "--target") {
|
|
195
|
+
if (argument === "--archive" || argument === "--target" || argument === "--kit") {
|
|
176
196
|
const value = args[index + 1];
|
|
177
197
|
if (!value || value.startsWith("--")) {
|
|
178
|
-
throw new Error(`${argument} requires a
|
|
198
|
+
throw new Error(`${argument} requires a value`);
|
|
179
199
|
}
|
|
180
200
|
if (argument === "--archive") {
|
|
181
201
|
archive = resolve(value);
|
|
182
|
-
} else {
|
|
202
|
+
} else if (argument === "--target") {
|
|
183
203
|
target = resolve(value);
|
|
204
|
+
} else {
|
|
205
|
+
kit = value;
|
|
184
206
|
}
|
|
185
207
|
index += 1;
|
|
186
208
|
continue;
|
|
@@ -190,20 +212,29 @@ function parseArgs(args) {
|
|
|
190
212
|
if (!target) {
|
|
191
213
|
throw new Error("--target is required");
|
|
192
214
|
}
|
|
193
|
-
|
|
215
|
+
if (!(kit in ESP32_KITS)) {
|
|
216
|
+
throw new Error(`unknown Device Kit target selector: ${kit}`);
|
|
217
|
+
}
|
|
218
|
+
return { archive, target, metadata: ESP32_KITS[kit] };
|
|
194
219
|
}
|
|
195
220
|
|
|
196
221
|
async function main() {
|
|
197
222
|
const options = parseArgs(process.argv.slice(2));
|
|
223
|
+
const metadata = options.metadata;
|
|
198
224
|
let archive = options.archive;
|
|
199
225
|
let downloadDirectory = null;
|
|
200
226
|
try {
|
|
201
227
|
if (!archive) {
|
|
228
|
+
if (!metadata.released) {
|
|
229
|
+
throw new Error(
|
|
230
|
+
`Device Kit ${metadata.target} metadata is not yet pinned to a release; pass --archive`,
|
|
231
|
+
);
|
|
232
|
+
}
|
|
202
233
|
downloadDirectory = mkdtempSync(join(tmpdir(), "tirtc-kit-download-"));
|
|
203
|
-
archive = join(downloadDirectory,
|
|
204
|
-
await download(
|
|
234
|
+
archive = join(downloadDirectory, metadata.archiveName);
|
|
235
|
+
await download(metadata.url, archive);
|
|
205
236
|
}
|
|
206
|
-
installEsp32KitArchive(archive, options.target);
|
|
237
|
+
installEsp32KitArchive(archive, options.target, metadata);
|
|
207
238
|
} finally {
|
|
208
239
|
if (downloadDirectory) {
|
|
209
240
|
rmSync(downloadDirectory, { force: true, recursive: true });
|
package/package.json
CHANGED
|
@@ -27,9 +27,10 @@ past build as proof for a new artifact.
|
|
|
27
27
|
Clone or download it only when the user authorizes that external write.
|
|
28
28
|
Read the exact business documents routed by `workflow.md`.
|
|
29
29
|
4. Run Doctor for the exact target and SDK package. Managed generation currently
|
|
30
|
-
automates ESP32-S3. ESP32-P4
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
automates ESP32-S3. For ESP32-P4 use the published `tirtc-esp32p4-kit`
|
|
31
|
+
(the XiaoTai P4 reference firmware with hosted C6 Wi-Fi and LVGL UI): copy it
|
|
32
|
+
with `create_esp32_project.py --target esp32p4`, build with the RISC-V
|
|
33
|
+
toolchain on ESP-IDF 5.5.4, and never link the S3 archive into a P4 image.
|
|
33
34
|
|
|
34
35
|
## 2. Identify the board and query knowledge
|
|
35
36
|
|
|
@@ -44,6 +44,24 @@ printf '%s\n' "$TIRTC_THING_CONNECT_ROOT"
|
|
|
44
44
|
|
|
45
45
|
已有完整 ThingConnect 工作区仍可通过 `--thing-connect-root` 显式复用,主要用于维护模板或协议时的开发场景。
|
|
46
46
|
|
|
47
|
+
### ESP32-P4 Device Kit
|
|
48
|
+
|
|
49
|
+
P4 不上 managed 安装(需要独立的 RISC-V 工具链)。从 GitHub Release 下载
|
|
50
|
+
`tirtc-esp32p4-kit`(小钛 P4 参考固件 1.4.0:hosted C6 Wi-Fi + LVGL UI +
|
|
51
|
+
摄像头,含 P4 SDK 2.5.0 与构建契约)并校验 SHA-256 后:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
python3 <解包目录>/device-sim/scripts/create_esp32_project.py \
|
|
55
|
+
/absolute/path/my-p4-device my_p4_device --target esp32p4
|
|
56
|
+
cd /absolute/path/my-p4-device
|
|
57
|
+
idf.py set-target esp32p4
|
|
58
|
+
idf.py build # 需要 ESP-IDF 5.5.4 与 riscv32-esp-elf(install.sh esp32p4)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
诊断使用 `--target esp32p4`;P4 永远不得链接 S3 的 `libTiRTC.a`。板级差异
|
|
62
|
+
(屏幕、摄像头、Codec、按键)位于参考固件的板级组件内,共享传输组件
|
|
63
|
+
(platform_client/runtime_config/wifi_manager)与 S3 同源。
|
|
64
|
+
|
|
47
65
|
## 常见输入方式
|
|
48
66
|
|
|
49
67
|
只有板卡型号:
|
|
@@ -74,7 +92,7 @@ printf '%s\n' "$TIRTC_THING_CONNECT_ROOT"
|
|
|
74
92
|
python3 <skill-dir>/scripts/doctor.py \
|
|
75
93
|
--expected-idf 5.5 \
|
|
76
94
|
--target esp32s3 \
|
|
77
|
-
--thing-connect-root ~/.tirtc-device-builder/kits/esp32s3/1.1.
|
|
95
|
+
--thing-connect-root ~/.tirtc-device-builder/kits/esp32s3/1.1.7 \
|
|
78
96
|
--require-workspace
|
|
79
97
|
```
|
|
80
98
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.10.0
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
接入方式:
|
|
29
29
|
- Wi-Fi:<选择一种,或写“根据 BSP 选择”>
|
|
30
|
-
- 选择 SoftAP 时:热点名以 `
|
|
30
|
+
- 选择 SoftAP 时:热点名以 `XiaoTai-` 开头、开放认证无需密码,AP 网关和配网页面为 `192.168.6.1` / `http://192.168.6.1`,启用通配 DNS 和 HTTP 重定向进行 captive portal 自动发现,不把 DHCP Option 114 指向本地 HTML 页面,并保留手动打开地址的回退说明
|
|
31
31
|
- 设备绑定:<选择一种,或写“根据平台合同选择”>
|
|
32
32
|
|
|
33
33
|
工程:
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
export TIRTC_AGENT_CLIENT=codex
|
|
11
|
-
npx --yes tirtc-device-builder@0.9.
|
|
11
|
+
npx --yes tirtc-device-builder@0.9.7 setup esp32 --install \
|
|
12
12
|
--client "$TIRTC_AGENT_CLIENT" --force-skill
|
|
13
13
|
```
|
|
14
14
|
|
|
@@ -17,11 +17,11 @@ npx --yes tirtc-device-builder@0.9.6 setup esp32 --install \
|
|
|
17
17
|
本轮第一步先只读运行:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
npx --yes tirtc-device-builder@0.9.
|
|
21
|
-
npx --yes tirtc-device-builder@0.9.
|
|
20
|
+
npx --yes tirtc-device-builder@0.9.7 --version
|
|
21
|
+
npx --yes tirtc-device-builder@0.9.7 setup esp32 --client "$TIRTC_AGENT_CLIENT"
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
必须根据命令的实际输出和本机文件确认:npm 包为 0.9.
|
|
24
|
+
必须根据命令的实际输出和本机文件确认:npm 包为 0.9.7、已安装 Skill 的 `VERSION` 为 0.9.7、所选 Device Kit 的 `manifest.json` 中 `kit_version` 为 1.1.7、`tirtc_sdk_version` 为 2.5.0,并且 Doctor 对 `--expected-kit 1.1.7` 输出 `OVERALL: PASS`。Plugin manifest 不属于这种 npm 安装方式的运行时前置条件,不得把不可访问的 Plugin 版本当作阻塞项。如果版本不一致、Skill 是在当前会话启动后才安装,或环境检查未通过,停止并报告前置条件不成立;不要在当前会话中替换 Skill 后继续生成工程。
|
|
25
25
|
|
|
26
26
|
工作区与 clean-room 边界:
|
|
27
27
|
- 将启动 Agent 客户端时的当前目录定义为 `WORKSPACE_ROOT`。
|
|
@@ -60,7 +60,7 @@ npx --yes tirtc-device-builder@0.9.6 setup esp32 --client "$TIRTC_AGENT_CLIENT"
|
|
|
60
60
|
- AI 对讲必须实现全双工和 AEC;构建阶段必须证明同时采集播放、真实播放参考与 `echo_cancellation.enabled=true`,实机结果仍只能在 L2-L7 验证后声明。
|
|
61
61
|
|
|
62
62
|
接入要求:
|
|
63
|
-
- SoftAP 配网:热点名使用 `
|
|
63
|
+
- SoftAP 配网:热点名使用 `XiaoTai-` 前缀、开放认证无需密码,AP 网关和配网页面为 `192.168.6.1` / `http://192.168.6.1`;启用通配 DNS 和 HTTP 重定向进行 captive portal 自动发现,不把 DHCP Option 114 指向本地 HTML 页面;Hardware IR 记录 `captive_portal: true`;目标 Wi-Fi 凭证保存 NVS。
|
|
64
64
|
- 验证码绑定,并复用已有绑定。
|
|
65
65
|
- 分别实现 `wifi-clear` 和 `tirtc-clear`。
|
|
66
66
|
- 平台发现本轮先使用 HTTP;HTTPS 留待独立验收。
|
package/skills/tirtc-esp32-builder/knowledge/waveshare-esp32-p4-wifi6-touch-lcd-3.5/knowledge.md
CHANGED
|
@@ -5,6 +5,15 @@ contains source-correlated observations and targeted regressions, not an
|
|
|
5
5
|
installable adapter or complete Hardware IR. A matching sales name does not
|
|
6
6
|
authorize pin reuse. No credentials, raw call logs or user media are retained.
|
|
7
7
|
|
|
8
|
+
## Current kit status (2026-09-22)
|
|
9
|
+
|
|
10
|
+
The builder repository now ships the XiaoTai P4 reference firmware (product
|
|
11
|
+
1.4.0, source `f33b7d2`) in `kit-src/device-sim/device-sim-p4/` and packs the
|
|
12
|
+
TiRTC ESP32-P4 SDK 2.5.0 vendor baseline (libTiRTC.a sha256
|
|
13
|
+
`9b4e35c7…`) into the `tirtc-esp32p4-kit` release. The historical observations
|
|
14
|
+
below (TiRTC 2.3.0, archive `a7a01ffd…`, IDF 5.5.4-dirty) remain historical
|
|
15
|
+
artifacts and do not describe the current kit baseline.
|
|
16
|
+
|
|
8
17
|
## Read only the needed source
|
|
9
18
|
|
|
10
19
|
| Baseline | Pinned source | Locate next |
|
|
@@ -16,7 +16,7 @@ The automatic branch never runs `sudo` or modifies a persistent shell profile. W
|
|
|
16
16
|
When `<setup-root>/env.sh` exists, use it only as an activation prefix for the current command:
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
bash -lc '. "<setup-root>/env.sh" && python3 "<skill-dir>/scripts/doctor.py" --expected-idf 5.5 --expected-kit 1.1.
|
|
19
|
+
bash -lc '. "<setup-root>/env.sh" && python3 "<skill-dir>/scripts/doctor.py" --expected-idf 5.5 --expected-kit 1.1.7 --target esp32s3 --require-workspace'
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
The helper contains paths, not device or network credentials. Read `<setup-root>/config.json` when exact managed paths are needed; the environment helper does not authorize unrelated downloads, shell-profile changes, flashing, or credential writes.
|
|
@@ -26,7 +26,7 @@ Run the doctor before generation, build, flash, or monitor:
|
|
|
26
26
|
```bash
|
|
27
27
|
python3 <skill-dir>/scripts/doctor.py \
|
|
28
28
|
--expected-idf 5.5 \
|
|
29
|
-
--expected-kit 1.1.
|
|
29
|
+
--expected-kit 1.1.7 \
|
|
30
30
|
--target esp32s3 \
|
|
31
31
|
--require-workspace
|
|
32
32
|
```
|
|
@@ -47,7 +47,7 @@ For an explicitly selected legacy workspace, omit `--expected-kit`; otherwise re
|
|
|
47
47
|
4. an ancestor whose `kit-src/` or `thing-connect/` child contains that generator.
|
|
48
48
|
|
|
49
49
|
The default managed root is `<setup-root>/kits/esp32s3/<kit-version>`. The `tirtc-device-builder/kit-src` directory is the ESP32 development source; the doctor also accepts an installed Device Kit root. Older `thing-connect/` layouts remain accepted as legacy inputs.
|
|
50
|
-
Resolve the SDK from the selected Kit manifest or generated project. Kit 1.1.
|
|
50
|
+
Resolve the SDK from the selected Kit manifest or generated project. Kit 1.1.7
|
|
51
51
|
and this repository's source generator use the ESP32-S3 SDK 2.5.0.
|
|
52
52
|
|
|
53
53
|
The managed Kit currently contains the ESP32-S3 H5/AI starter. When the requested
|
|
@@ -59,10 +59,19 @@ protocols and non-ESP32 simulators. Cloning is an external write and requires
|
|
|
59
59
|
user authorization. Do not track a moving default branch as build evidence.
|
|
60
60
|
|
|
61
61
|
ESP32-P4 uses a separate `espressif_esp32p4` SDK archive and RISC-V toolchain.
|
|
62
|
-
The managed setup does not install that archive
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
The managed setup does not install that archive; P4 projects come from the
|
|
63
|
+
published `tirtc-esp32p4-kit` (the XiaoTai P4 reference firmware, released
|
|
64
|
+
alongside the S3 Kit). The P4 flow is:
|
|
65
|
+
|
|
66
|
+
1. Download the `tirtc-esp32p4-kit` GitHub release, verify its SHA-256, and
|
|
67
|
+
extract it (or point `--thing-connect-root` at this repository's `kit-src`).
|
|
68
|
+
2. `python3 device-sim/scripts/create_esp32_project.py <out> <name> --target esp32p4`
|
|
69
|
+
(copies the full reference firmware and materializes the shared transport
|
|
70
|
+
components and the P4 SDK under `third_party/tirtc`).
|
|
71
|
+
3. `idf.py set-target esp32p4`, build with the RISC-V toolchain
|
|
72
|
+
(`install.sh esp32p4`; the pinned SDK requires ESP-IDF 5.5.4 exactly).
|
|
73
|
+
4. Run Doctor with `--target esp32p4` and never accept the packaged S3 archive
|
|
74
|
+
as a compatible fallback.
|
|
66
75
|
|
|
67
76
|
SDK resolution is independent after generation: an explicit `--sdk-dir` wins, followed by `<project>/third_party/tirtc`, then the SDK packaged in the resolved Device Kit or legacy workspace. The generated project remains diagnosable after it is moved away from the Kit.
|
|
68
77
|
|
|
@@ -65,8 +65,8 @@ The selected Wi-Fi method must be available and corroborated, credentials must r
|
|
|
65
65
|
|
|
66
66
|
When the selected method is SoftAP:
|
|
67
67
|
|
|
68
|
-
- generate the SSID as `
|
|
69
|
-
prefix is `
|
|
68
|
+
- generate the SSID as `XiaoTai-<device suffix>` so its exact, case-sensitive
|
|
69
|
+
prefix is `XiaoTai-`; use a stable non-secret suffix and keep the complete SSID
|
|
70
70
|
within the ESP32 32-byte limit;
|
|
71
71
|
- configure an open network (`WIFI_AUTH_OPEN`) with an empty AP password so a
|
|
72
72
|
user can connect directly;
|
|
@@ -81,7 +81,7 @@ When the selected method is SoftAP:
|
|
|
81
81
|
client auto-popup is not guaranteed and HTTPS cannot be transparently
|
|
82
82
|
redirected.
|
|
83
83
|
|
|
84
|
-
Record these values on the selected SoftAP method as `ssid_prefix: "
|
|
84
|
+
Record these values on the selected SoftAP method as `ssid_prefix: "XiaoTai-"`,
|
|
85
85
|
`auth_mode: "open"`, `ipv4_address: "192.168.6.1"`, and
|
|
86
86
|
`captive_portal: true`. The Hardware IR gate returns `NEEDS_CONFIRMATION` when
|
|
87
87
|
one is missing and `BLOCKED` when one differs.
|
|
@@ -22,10 +22,29 @@ CONTRACT_KEYS = {
|
|
|
22
22
|
"CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS",
|
|
23
23
|
"CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS",
|
|
24
24
|
}
|
|
25
|
+
# The P4 archive additionally pins the socket budget (absent from the S3 contract).
|
|
26
|
+
CONTRACT_KEYS_P4 = CONTRACT_KEYS | {"CONFIG_LWIP_MAX_SOCKETS"}
|
|
25
27
|
THING_CONNECT_ENV = "TIRTC_THING_CONNECT_ROOT"
|
|
26
28
|
GENERATOR_RELATIVE_PATH = Path("device-sim/scripts/create_esp32_project.py")
|
|
27
|
-
SDK_RELATIVE_ROOT = Path("device-sim/sdk/espressif-esp32s3")
|
|
28
29
|
DEVICE_KIT_MANIFEST = "manifest.json"
|
|
30
|
+
SDK_FALLBACK_VERSIONS = {
|
|
31
|
+
"esp32s3": ("2.5.0", "2.3.0"),
|
|
32
|
+
"esp32p4": ("2.5.0",),
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def sdk_relative_root(platform: str | None, target: str) -> Path:
|
|
37
|
+
"""SDK root inside the Kit; the manifest platform wins, the target is the
|
|
38
|
+
fallback. A P4 target never resolves the ESP32-S3 SDK archive."""
|
|
39
|
+
if platform == "espressif-esp32p4" or target == "esp32p4":
|
|
40
|
+
return Path("device-sim/sdk/espressif-esp32p4")
|
|
41
|
+
return Path("device-sim/sdk/espressif-esp32s3")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def contract_keys(target: str) -> set[str]:
|
|
45
|
+
if target == "esp32p4":
|
|
46
|
+
return CONTRACT_KEYS_P4
|
|
47
|
+
return CONTRACT_KEYS
|
|
29
48
|
|
|
30
49
|
|
|
31
50
|
def check(name: str, status: str, detail: str, required: bool = True) -> dict[str, Any]:
|
|
@@ -115,10 +134,10 @@ def parse_kconfig(path: Path) -> dict[str, str]:
|
|
|
115
134
|
|
|
116
135
|
|
|
117
136
|
def compare_contract(
|
|
118
|
-
contract: dict[str, str], config: dict[str, str]
|
|
137
|
+
contract: dict[str, str], config: dict[str, str], keys: set[str] | None = None
|
|
119
138
|
) -> list[str]:
|
|
120
139
|
mismatches: list[str] = []
|
|
121
|
-
for key in sorted(CONTRACT_KEYS):
|
|
140
|
+
for key in sorted(keys if keys is not None else CONTRACT_KEYS):
|
|
122
141
|
expected = contract.get(key)
|
|
123
142
|
actual = config.get(key)
|
|
124
143
|
if expected is None:
|
|
@@ -238,6 +257,7 @@ def resolve_sdk_dir(
|
|
|
238
257
|
explicit: Path | None,
|
|
239
258
|
project: Path | None,
|
|
240
259
|
thing_connect_root: Path | None,
|
|
260
|
+
target: str = "esp32s3",
|
|
241
261
|
) -> tuple[Path | None, str]:
|
|
242
262
|
if explicit is not None:
|
|
243
263
|
return explicit.expanduser().resolve(), "explicit --sdk-dir"
|
|
@@ -251,15 +271,22 @@ def resolve_sdk_dir(
|
|
|
251
271
|
try:
|
|
252
272
|
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
|
|
253
273
|
version = manifest.get("tirtc_sdk_version")
|
|
274
|
+
platform = manifest.get("platform")
|
|
254
275
|
if isinstance(version, str) and re.fullmatch(r"\d+\.\d+\.\d+", version):
|
|
255
|
-
return
|
|
276
|
+
return (
|
|
277
|
+
thing_connect_root / sdk_relative_root(platform, target) / version,
|
|
278
|
+
"Device Kit",
|
|
279
|
+
)
|
|
256
280
|
except (OSError, json.JSONDecodeError):
|
|
257
281
|
pass
|
|
258
|
-
for version in (
|
|
259
|
-
candidate = thing_connect_root /
|
|
282
|
+
for version in SDK_FALLBACK_VERSIONS.get(target, SDK_FALLBACK_VERSIONS["esp32s3"]):
|
|
283
|
+
candidate = thing_connect_root / sdk_relative_root(None, target) / version
|
|
260
284
|
if candidate.is_dir():
|
|
261
285
|
return candidate, "ESP32 source workspace"
|
|
262
|
-
return
|
|
286
|
+
return (
|
|
287
|
+
thing_connect_root / sdk_relative_root(None, target) / "2.5.0",
|
|
288
|
+
"ESP32 source workspace",
|
|
289
|
+
)
|
|
263
290
|
return None, "not found"
|
|
264
291
|
|
|
265
292
|
|
|
@@ -373,6 +400,7 @@ def diagnose(args: argparse.Namespace) -> dict[str, Any]:
|
|
|
373
400
|
args.sdk_dir,
|
|
374
401
|
args.project,
|
|
375
402
|
thing_connect_root,
|
|
403
|
+
args.target,
|
|
376
404
|
)
|
|
377
405
|
if sdk_dir is None:
|
|
378
406
|
sdk_files: list[Path] = []
|
|
@@ -427,7 +455,9 @@ def diagnose(args: argparse.Namespace) -> dict[str, Any]:
|
|
|
427
455
|
checks.append(check("TiRTC build contract", "FAIL", detail))
|
|
428
456
|
else:
|
|
429
457
|
mismatches = compare_contract(
|
|
430
|
-
parse_env_file(contract_path),
|
|
458
|
+
parse_env_file(contract_path),
|
|
459
|
+
parse_kconfig(config_path),
|
|
460
|
+
contract_keys(args.target),
|
|
431
461
|
)
|
|
432
462
|
checks.append(
|
|
433
463
|
check(
|