diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml new file mode 100644 index 0000000..9cdd9bf --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -0,0 +1,72 @@ +name: Bug report / 缺陷报告 +description: Report reproducible incorrect behavior / 报告可复现的异常行为 +title: "[Bug] " +labels: + - bug +body: + - type: markdown + attributes: + value: | + Remove passwords, tokens, private keys, databases, private network details, and real IR data from all text and attachments. + 请从文字和附件中移除密码、Token、证书私钥、数据库、私有网络信息和真实红外数据。 + - type: textarea + id: description + attributes: + label: Problem description / 问题描述 + description: What happened, and which component was involved? / 发生了什么,涉及哪个组件? + validations: + required: true + - type: textarea + id: steps + attributes: + label: Steps to reproduce / 复现步骤 + placeholder: "1. ...\n2. ...\n3. ..." + validations: + required: true + - type: textarea + id: expected + attributes: + label: Expected result / 预期结果 + validations: + required: true + - type: textarea + id: actual + attributes: + label: Actual result / 实际结果 + validations: + required: true + - type: input + id: version + attributes: + label: Version or commit / 版本或提交 + placeholder: v1.2.6 or commit SHA + validations: + required: true + - type: dropdown + id: component + attributes: + label: Component / 组件 + multiple: true + options: + - Firmware / 固件 + - Cloud backend / 云端后端 + - Web frontend / 网页前端 + - MQTT configuration / MQTT 配置 + - IR learner / 红外学习工具 + - Hardware or PCB / 硬件或 PCB + - Documentation / 文档 + - Not sure / 不确定 + validations: + required: true + - type: textarea + id: logs + attributes: + label: Sanitized logs / 脱敏日志 + render: shell + - type: checkboxes + id: sensitive-data + attributes: + label: Sensitive data check / 敏感信息确认 + options: + - label: I removed all credentials, private keys, databases, private network details, and real IR data. / 我已移除所有凭据、私钥、数据库、私有网络信息和真实红外数据。 + required: true diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 14579f9..0000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -name: Bug report -about: Report incorrect or unexpected behaviour -title: "[Bug] " -labels: bug -assignees: '' ---- - -## Do not post secrets - -Before you submit, remove Wi-Fi passwords, MQTT credentials, tokens, cookies, -certificates, private hostnames and IP addresses from every log and screenshot. - -## Component - -- [ ] Firmware (ESP8266) -- [ ] Cloud backend -- [ ] Web frontend -- [ ] MQTT broker configuration -- [ ] Documentation -- [ ] Not sure - -## Description - -A clear and concise description of the problem. - -## Steps to reproduce - -1. -2. -3. - -## Expected behaviour - -## Actual behaviour - -## Environment - -| Field | Value | -| --- | --- | -| Repository version / commit | | -| Board | NodeMCU ESP8266 (state otherwise) | -| USB-serial chip | e.g. CH9102 | -| Host OS | | -| Node.js version (cloud) | | -| Browser (frontend) | | - -## Logs - -
-Serial / server / browser console output (redacted) - -```text - -``` - -
- -## Additional context diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index b6a68d3..9d4b6b7 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,8 +1,8 @@ blank_issues_enabled: false contact_links: - - name: Security vulnerability + - name: Security vulnerability / 安全漏洞 url: https://github.com/nobodycareme/remote-ac-controller/security/advisories/new - about: Do NOT open a public issue. Report vulnerabilities privately here. - - name: Question / usage help - url: https://github.com/nobodycareme/remote-ac-controller/discussions - about: Ask usage questions in Discussions rather than the issue tracker. + about: Report security issues privately. 安全问题请私下报告,不要公开提交。 + - name: Usage help / 使用帮助 + url: https://github.com/nobodycareme/remote-ac-controller/blob/main/SUPPORT.md + about: Check the support routes before opening an issue. 提交前请先查看支持入口。 diff --git a/.github/ISSUE_TEMPLATE/documentation.yml b/.github/ISSUE_TEMPLATE/documentation.yml new file mode 100644 index 0000000..578922d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/documentation.yml @@ -0,0 +1,49 @@ +name: Documentation issue / 文档问题 +description: Report missing, incorrect, or unclear documentation / 报告缺失、错误或不清楚的文档 +title: "[Docs] " +labels: + - documentation +body: + - type: input + id: path + attributes: + label: Document path or link / 文档路径或链接 + placeholder: docs/English/deployment.md + validations: + required: true + - type: dropdown + id: issue-type + attributes: + label: Issue type / 问题类型 + options: + - Incorrect information / 信息错误 + - Missing information / 信息缺失 + - Unclear instructions / 说明不清 + - Broken link or formatting / 链接或格式问题 + - Translation mismatch / 翻译不一致 + validations: + required: true + - type: dropdown + id: language + attributes: + label: Language / 语言版本 + options: + - Chinese / 中文 + - English / 英文 + - Both / 两者 + validations: + required: true + - type: textarea + id: proposal + attributes: + label: Suggested change / 建议修改 + description: Quote only the minimum context needed. / 只引用必要的上下文。 + validations: + required: true + - type: checkboxes + id: sensitive-data + attributes: + label: Sensitive data check / 敏感信息确认 + options: + - label: I removed credentials, private keys, databases, private network details, and real IR data. / 我已移除凭据、私钥、数据库、私有网络信息和真实红外数据。 + required: true diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml new file mode 100644 index 0000000..77c082c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -0,0 +1,48 @@ +name: Feature request / 功能建议 +description: Propose a change based on a concrete use case / 基于具体场景提出改进 +title: "[Feature] " +body: + - type: textarea + id: use-case + attributes: + label: Use case / 使用场景 + description: What are you trying to accomplish? / 你希望完成什么? + validations: + required: true + - type: textarea + id: limitation + attributes: + label: Current limitation / 当前限制 + description: What prevents that workflow today? / 当前是什么阻碍了这个流程? + validations: + required: true + - type: textarea + id: proposal + attributes: + label: Proposed behavior / 建议行为 + description: Describe the smallest useful change. / 描述最小且有用的改动。 + validations: + required: true + - type: dropdown + id: component + attributes: + label: Affected component / 影响组件 + multiple: true + options: + - Firmware / 固件 + - Cloud backend / 云端后端 + - Web frontend / 网页前端 + - MQTT configuration / MQTT 配置 + - IR learner / 红外学习工具 + - Hardware or PCB / 硬件或 PCB + - Documentation / 文档 + - Not sure / 不确定 + validations: + required: true + - type: checkboxes + id: sensitive-data + attributes: + label: Sensitive data check / 敏感信息确认 + options: + - label: This request contains no credentials, private keys, databases, private network details, or real IR data. / 本建议不含凭据、私钥、数据库、私有网络信息或真实红外数据。 + required: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 6373c05..0000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: Feature request -about: Propose a new capability or an improvement -title: "[Feature] " -labels: enhancement -assignees: '' ---- - -## Component - -- [ ] Firmware (ESP8266) -- [ ] Cloud backend -- [ ] Web frontend -- [ ] MQTT broker configuration -- [ ] Documentation / tooling - -## Problem - -What are you unable to do today? Describe the situation, not the solution. - -## Proposed solution - -## Alternatives considered - -## Impact - -- Does it change the MQTT topic contract or payload schema? (yes / no) -- Does it change the device state model? (yes / no) -- Does it require additional hardware? (yes / no) -- Does it affect the security defaults, in particular real-IR being disabled? (yes / no) - -## Additional context diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index ad3d6ae..0000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,51 +0,0 @@ -# Pull Request - -## Summary - - - -## Affected area - -- [ ] `firmware/` (ESP8266) -- [ ] `cloud/backend/` -- [ ] `cloud/frontend/` -- [ ] `cloud/broker/` (Mosquitto config) -- [ ] `docs/` / `hardware/` -- [ ] Repository tooling / CI - -## Type of change - -- [ ] Bug fix -- [ ] New feature -- [ ] Refactor (no behaviour change) -- [ ] Documentation -- [ ] Build / CI - -## Verification - -Describe what you actually ran. Do not tick a box you did not execute. - -- [ ] `pwsh tools/test-all.ps1` passed -- [ ] `pwsh tools/build-all.ps1` passed -- [ ] Verified on real hardware (state the board and how) -- [ ] Not applicable (documentation-only change) - - - -## Security checklist - -These are hard requirements. A PR that fails any of them will not be merged. - -- [ ] No credentials, tokens, passwords, private keys or certificates are added -- [ ] No `secrets.h`, `cloud_secrets.h`, `.env`, `*.db`, `*.pem`, `*.key` is committed -- [ ] No production hostname, IP address or account is hard-coded -- [ ] Real-IR transmission remains disabled by default -- [ ] No file from `Private/`, `Evidence/` or any internal archive is included - -## Breaking changes - - - -## Related issues - - diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..6c35c9d --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,35 @@ +# Pull Request + +## Summary + + + +## Scope + + + +## Validation + + + +- [ ] Tests relevant to this change passed +- [ ] A skipped or unavailable check is explained above + +## Security + +- [ ] No production credentials, tokens, passwords, private keys, certificates, or databases are included +- [ ] No real air-conditioner IR data is included +- [ ] Logs, screenshots, and examples are sanitized +- [ ] Security-sensitive behavior is described for reviewers + +## Documentation + +- [ ] User-facing behavior is documented, or this change needs no documentation +- [ ] Chinese and English documents are synchronized where both exist +- [ ] Added and changed links were checked + +## Release impact + +- [ ] Version impact is stated: none, patch, minor, or major +- [ ] Tag and Release asset impact is stated +- [ ] Any migration or compatibility impact is described diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b6aab0e..5b79581 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1013,6 +1013,9 @@ jobs: with: python-version: '3.12' + - name: Install documentation validation dependencies + run: python3 -m pip install "PyYAML>=6.0,<7" + - name: Documentation parity (every first-party doc paired CN<->EN) run: python3 tools/check-doc-parity.py @@ -1037,6 +1040,9 @@ jobs: with: python-version: '3.12' + - name: Install documentation validation dependencies + run: python3 -m pip install "PyYAML>=6.0,<7" + - name: No broken first-party relative links run: python3 tools/check-doc-links.py @@ -1134,6 +1140,9 @@ jobs: uses: actions/checkout@v4 with: persist-credentials: false + - name: Install documentation validation dependencies + run: python3 -m pip install "PyYAML>=6.0,<7" + - name: Verify v1.2.5 public documentation contract run: | python3 tools/check-public-docs.py diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index bdeef87..af13b42 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -2,23 +2,8 @@ # Code of Conduct / 行为准则 -- [简体中文](./docs/中文/行为准则.md) -- [English](./docs/English/code-of-conduct.md) +本项目采用 [Contributor Covenant 2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct/)。参与讨论和评审时,请尊重不同经验与观点,给出可执行的反馈,不要骚扰、侮辱、泄露他人隐私或发布与协作无关的攻击性内容。 -本仓库采用 [Contributor Covenant 2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct/)。 -简体中文译本见上方链接,如中英文表述存在差异,以英文原文为准。 - -This project adopts the -[Contributor Covenant 2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct/). -The Simplified Chinese translation is linked above; the English text is -authoritative where the two differ. - -Contributor Covenant 文本采用 -[CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) 授权,版权与归属归 -Contributor Covenant 及其贡献者所有,未经修改不得删除其归属信息。 - -The Contributor Covenant text is licensed under -[CC BY 4.0](https://creativecommons.org/licenses/by/4.0/); copyright and -attribution belong to Contributor Covenant and its contributors, and attribution -must not be removed unmodified. +完整中文文本见[行为准则](./docs/中文/行为准则.md),英文文本见 [Code of Conduct](./docs/English/code-of-conduct.md)。如两个版本存在差异,以英文原文为准。 +Contributor Covenant 文本采用 [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) 许可。 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 215d9a1..e9cc6fe 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,105 +1,21 @@ -**简体中文** | [English](./docs/English/contributing.md) +[简体中文](./docs/中文/参与贡献.md) | [English](./docs/English/contributing.md) # Contributing / 参与贡献 -欢迎参与 Remote AC Controller 的开发。本文件是根级指南,可直接执行; -详细的规范文档见[参与贡献指南](./docs/中文/参与贡献.md)(English: [contributing](./docs/English/contributing.md))。 +欢迎修正文档、缺陷或实现新的能力。提交前请先在相关 Issue 中说明范围,安全问题请改用 [Private Vulnerability Reporting](https://github.com/nobodycareme/remote-ac-controller/security/advisories/new)。 -## 环境要求 +## 开始修改 -- Git、Python 3.10+(校验脚本) -- Node.js 24 与 npm(云端) -- PlatformIO Core 6.x(固件 CLI 工作流)或 Arduino IDE 2.x -- Windows PowerShell 5.1+(`tools/dev.ps1`、`tools/test-all.ps1` 等脚本) +- 固件位于 `firmware/`,Cloud 后端和前端位于 `cloud/`,PCB 资料位于 `hardware/`。 +- 文档按 `docs/中文/` 与 `docs/English/` 成对维护;修改一个语言版本时,请同步核对另一个版本。 +- `tools/README.md` 列出公开工具、校验脚本和发布脚本的职责。 +- 不要提交真实凭据、数据库、证书私钥、真实红外数据或生成产物。 -## 仓库目录入口 +## 提交 Pull Request -| 路径 | 说明 | -|---|---| -| `firmware/agent-platformio/` | PlatformIO / command-line workflow(自动化构建与烧录) | -| `firmware/arduino-ide/` | Arduino IDE workflow | -| `firmware/shared/RemoteACCore/` | 固件业务核心(两工作流共享) | -| `cloud/backend/` | Fastify 后端 + MQTT 桥接 | -| `cloud/frontend/` | Vue 3 前端 | -| `hardware/` | PCB 与硬件文档 | -| `docs/` | 中英文文档(成对维护) | -| `tools/` | 校验与发布脚本 | +1. 从最新 `main` 创建范围明确的分支。 +2. 只修改完成该问题所需的文件。 +3. 运行与改动相关的测试,并在 PR 中写明实际命令和结果。 +4. 检查版本、文档、安全边界和 Release 资产是否受到影响。 -## 常用命令 - -### Backend - -```bash -cd cloud/backend -npm ci -npx tsc --noEmit -npm run build -npm test -``` - -### Frontend - -```bash -cd cloud/frontend -npm ci -npx tsc --noEmit -npm run build -npm test -``` - -### Firmware(PlatformIO / command-line workflow,public profile) - -```powershell -cd firmware/agent-platformio -pwsh ./tools/dev.ps1 test -Profile public -pwsh ./tools/dev.ps1 verify -Profile public -pwsh ./tools/dev.ps1 build -Profile public -``` - -### Firmware(Arduino IDE workflow) - -用 Arduino IDE 2.x 打开 `firmware/arduino-ide/Remote_AC_Controller/Remote_AC_Controller.ino`, -按 sketch 内 README 完成一次性配置后编译上传。 - -### 文档校验 - -```bash -python tools/check-doc-parity.py -python tools/check-doc-links.py -python tools/check-doc-language-links.py -python tools/check-public-docs.py -python tools/check-version.py -python tools/check-pcb-release.py -``` - -## 分支命名 - -- 功能/修复:`feat/`、`fix/` -- 文档:`docs/` -- 发布准备:`release/` - -## Commit 要求 - -- 清晰的主题行(type(scope): summary)。 -- 一个提交只做一件事;不要用 `git commit -a` 跳过范围审查。 -- 提交前运行 `git diff --check`。 - -## PR 检查清单 - -- [ ] 本地通过 Backend/Frontend/Firmware 命令(见上) -- [ ] 文档校验脚本全绿 -- [ ] 不包含生产凭据、私钥、数据库、真实 IR 帧或 Windows 本地路径 -- [ ] 中英文文档成对更新(如涉及 docs/) - -## 禁止提交的内容 - -- 任何凭据:`campus_secrets.h`、`cloud_secrets.h`、`profiles/*.h`(真实值)、`secrets.env`、`.env` -- TLS 私钥/证书、数据库文件(`*.db`、`*.sqlite*`) -- 真实红外帧数据(仅允许公开状态元数据) -- `Private/`、`Evidence/`、`Archives/`、`Deliverables/` 目录内容 -- 生成产物(`node_modules/`、`.build/`、`dist/`、ZIP、EXE) - -## 详细指南 - -- 中文:[参与贡献指南](./docs/中文/参与贡献.md)、[支持说明](./docs/中文/支持说明.md) -- English: [contributing](./docs/English/contributing.md)、[support](./docs/English/support.md) +完整的开发命令、分支约定和检查清单见[中文贡献指南](./docs/中文/参与贡献.md)与 [English contributing guide](./docs/English/contributing.md)。使用问题请查看 [SUPPORT.md](./SUPPORT.md)。 diff --git a/README.en.md b/README.en.md index ed22df0..08a2b8e 100644 --- a/README.en.md +++ b/README.en.md @@ -1,4 +1,4 @@ -

+

Overview · Quick Start · Documentation · @@ -10,7 +10,7 @@

Remote AC Controller

-

Control an ordinary air conditioner from your phone with an ESP8266, an IR module, and a web page.

+

Connect an ordinary IR air conditioner to a phone web UI with an ESP8266.

CI @@ -18,100 +18,98 @@ Apache-2.0

---- - ## Overview -Remote AC Controller is an ESP8266-based air conditioner remote control project. The device controls the AC through infrared and reports temperature, humidity, and device status to a web page. The repository includes firmware, cloud services, PCB files, and an IR learning tool. - -With a NodeMCU board, an IR transmitter, and a small temperature/humidity sensor, you can build the whole system. The IR codes are learned from your own remote, so it works with most infrared-controlled air conditioners. - -The project is designed for everyday use: the web UI works on phones, and you can deploy it on a LAN or on a public server. The firmware supports home Wi-Fi and optional campus network access to fit different environments. +The project started with a practical goal: control an ordinary IR air conditioner from a NodeMCU, then document the firmware, web service, PCB, and IR learning workflow needed to build it from scratch. ## Interface preview -

- Desktop control interface -

- -

- Mobile control interface -

- -Desktop and mobile use the same responsive page; the data in the screenshots is demo data shown for layout illustration only. + + + + + +
Desktop control interfaceMobile control interface
-## Features +One responsive interface works on desktop and mobile. The screenshots contain demo data and show layout only. -- Control AC power, mode, and common states from the phone web page; -- DHT11 temperature and humidity monitoring; -- Scheduled tasks and temperature-based automation; -- ESP8266 communicates with the cloud over MQTT; -- Supports home WPA/WPA2 Wi-Fi and optional Srun campus network auth; -- IR learning tool to capture data from your own remote. +## Core capabilities -Phone web control requires the frontend, backend, MQTT broker, and ESP8266 firmware running together. The firmware can also be used standalone for serial interaction, sensor reading, and IR hardware debugging. The parts can be developed and deployed separately; when replacing the frontend, backend, broker, or firmware, keep the existing API and MQTT protocol compatible. +- Control AC power, mode, and common states from a phone web page +- View DHT11 temperature, humidity, and device presence +- Run recurring scheduled tasks +- Use dual-threshold hysteresis to avoid rapid cycling +- Connect the ESP8266 and cloud through MQTT, with optional Srun campus access +- Learn IR codes from your own remote ## Quick start -| Goal | Start here | +| Goal | Next step | |---|---| -| Home or lab Wi-Fi | [First-time setup](./docs/English/first-time-setup.md) | -| Xidian campus network | [Xidian campus authentication](./docs/English/xidian-campus-network-authentication.md) | -| Build the ESP8266 firmware | [PlatformIO firmware guide](./firmware/agent-platformio/README.en.md) | -| Use Arduino IDE | [Arduino IDE guide](./docs/English/arduino-ide-guide.md) | -| Deploy your own server | [Deployment guide](./docs/English/deployment.md) | -| Learn your own remote | [IR learning guide](./docs/English/ir-learning.md) | -| Manufacture the PCB | [PCB documentation](./hardware/pcb/README.en.md) | - -A minimal public build: +| Validate the source | Run the public PlatformIO build below; no real credentials are needed. | +| Build a physical device | Follow [Wiring](./docs/English/wiring.md), [First-time setup](./docs/English/first-time-setup.md), and [IR learning](./docs/English/ir-learning.md), then flash the firmware. | +| Deploy full web control | Use the [Deployment guide](./docs/English/deployment.md) to configure the backend, frontend, and MQTT broker before connecting the device. | ```powershell cd firmware/agent-platformio ./tools/dev.ps1 build -Profile public ``` -This is a credentials-free public build, not an offline build: the firmware still compiles the Wi-Fi and cloud modules, just without real credentials, and it does not auto-connect at boot. - -To set up local credentials for a home router or the Xidian campus network and to flash the firmware, start with the [first-time setup guide](./docs/English/first-time-setup.md). To check that your toolchain works, run the command above — no credential files are needed. +The public profile still compiles the Wi-Fi and cloud modules, but it contains no real credentials and does not connect automatically at boot. ## System layout -``` -Phone web page → Cloud → MQTT → ESP8266 → IR → AC +```text +Phone web UI → Fastify backend → MQTT → ESP8266 → IR → AC ``` -The server uses Fastify, the frontend uses Vue 3, and the device is a NodeMCU ESP8266. +The Vue 3 frontend serves desktop and mobile clients. A NodeMCU ESP8266 reads the sensor and drives the IR module. -The repository is organized by directory: `firmware/` holds the ESP8266 firmware (PlatformIO and Arduino IDE workflows), `cloud/` holds the backend and web frontend, `hardware/` holds the PCB files, and `tools/` holds the IR learning tool and helper scripts. The parts communicate over the MQTT message protocol, documented in [MQTT protocol](./docs/English/mqtt-protocol.md). +| Directory | Contents | +|---|---| +| `firmware/` | PlatformIO and Arduino IDE firmware projects | +| `cloud/` | Fastify backend, Vue 3 frontend, and deployment configuration | +| `hardware/` | Wiring, PCB sources, and manufacturing files | +| `tools/` | IR learning application and project maintenance scripts | +| `docs/` | English and Chinese user, design, and maintenance guides | -The backend, web frontend, and firmware can be started and debugged separately; complete phone control needs all three plus an MQTT broker. The firmware supports several network access methods — see the [first-time setup guide](./docs/English/first-time-setup.md). +## Verified hardware -## Hardware +| Category | Model or revision | +|---|---| +| Board | NodeMCU ESP8266 | +| Temperature and humidity sensor | DHT11 | +| IR module | ZJ-IR-V2 | +| PCB | Rev 1.0.1 | + +Other boards or IR modules require a fresh check of pins, voltage levels, and communication protocols. -- Board: NodeMCU ESP8266 -- Temperature/humidity: DHT11 -- IR module: ZJ-IR-V2 -- PCB: Rev 1.0.1 +## Documentation -The project has been developed and validated on NodeMCU ESP8266, DHT11, and ZJ-IR-V2. When using other ESP8266 boards or IR modules, re-check the pin mapping, voltage levels, and communication protocol. +| Getting started | Architecture and protocols | Maintenance | Participate | +|---|---|---|---| +| [First-time setup](./docs/English/first-time-setup.md) | [Architecture](./docs/English/architecture.md) | [Operations guide](./docs/English/operations-guide.md) | [Contributing](./CONTRIBUTING.md) | +| [Arduino IDE](./docs/English/arduino-ide-guide.md) | [MQTT protocol](./docs/English/mqtt-protocol.md) | [Troubleshooting](./docs/English/troubleshooting.md) | [Support](./SUPPORT.md) | +| [Deployment](./docs/English/deployment.md) | [Security model](./docs/English/security-model.md) | [Backup and recovery](./docs/English/backup-and-recovery.md) | [Security policy](./SECURITY.md) | -The public repository does not ship real AC IR codes, and no validated BOM or pick-and-place files are provided. Use the [IR learning guide](./docs/English/ir-learning.md) to capture data from your own remote, then follow the [first-time setup guide](./docs/English/first-time-setup.md) to flash it. +See the [English documentation index](./docs/English/documentation-index.md) for the complete list. -## Documentation +## Security and limits -| Understand the project | Use and configure | Maintain and troubleshoot | -|---|---|---| -| [Architecture](./docs/English/architecture.md) | [First-time setup](./docs/English/first-time-setup.md) | [Operations guide](./docs/English/operations-guide.md) | -| [Security model](./docs/English/security-model.md) | [Arduino IDE guide](./docs/English/arduino-ide-guide.md) | [Troubleshooting](./docs/English/troubleshooting.md) | -| [MQTT protocol](./docs/English/mqtt-protocol.md) | [Deployment guide](./docs/English/deployment.md) | [Backup and recovery](./docs/English/backup-and-recovery.md) | -| [Changelog](./docs/English/changelog.md) | [IR learning](./docs/English/ir-learning.md) | [Security policy](./docs/English/security.md) | +
+Boundaries to review before building -Chinese documentation is available from the [简体中文文档导航](./docs/中文/文档导航.md). +- The public repository contains no real Wi-Fi, MQTT, or campus-network credentials. +- Real AC IR codes are not included; capture them from your own remote. +- Firmware safety policy restricts real IR transmission by default. +- Other boards and IR modules may need adaptation. +- The Windows IR learner executable is unsigned. +- PCB files do not include an unverified BOM or pick-and-place data. -All documents are provided in both Chinese and English with the same structure, so you can switch languages side by side. If a topic is not listed in the table, check the [documentation index](./docs/English/documentation-index.md). +
-## Contributing and support +## Contributing, support, and license -Issues and pull requests are welcome — please read the [contributing guide](./docs/English/contributing.md) first. If you find a problem, describing what you did and the environment helps maintainers fix it faster. Security vulnerabilities should be reported through GitHub Private Vulnerability Reporting; see the [security policy](./docs/English/security.md). For usage questions, check the [documentation index](./docs/English/documentation-index.md) or open an [Issue](https://github.com/nobodycareme/remote-ac-controller/issues). +Read [Contributing](./CONTRIBUTING.md) before submitting a change. [Support](./SUPPORT.md) directs usage questions and defects; report vulnerabilities through GitHub Private Vulnerability Reporting rather than a public issue. -The project is licensed under the [Apache License 2.0](./LICENSE); third-party component licenses are listed in the [third-party notices](./docs/English/third-party-notices.md). All code and docs are maintained in this repository; release notes are in the [changelog](./docs/English/changelog.md) and [GitHub Releases](https://github.com/nobodycareme/remote-ac-controller/releases). +The project is licensed under [Apache License 2.0](./LICENSE). Dependency licences are listed in [Third-party notices](./docs/English/third-party-notices.md). diff --git a/README.md b/README.md index 67a9bc5..c009ad9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

+

项目简介 · 快速开始 · 文档 · @@ -10,7 +10,7 @@

Remote AC Controller

-

用 ESP8266、红外模块和网页,把普通空调接入手机远程控制。

+

用 ESP8266 和红外模块,把普通空调接入手机网页。

CI @@ -18,104 +18,98 @@ Apache-2.0

---- - ## 项目简介 -Remote AC Controller 是一个基于 ESP8266 的空调远程控制项目。设备通过红外控制空调,并把温湿度和设备状态发送到网页。仓库包含固件、云端、PCB 资料和红外学习工具。 - -如果你只有一台 NodeMCU 开发板、一个红外发射模块和一个小型温湿度传感器,就可以搭建这套系统;核心红外码由你自己的遥控器学习得到,因此适用于大多数支持红外遥控的空调型号。 - -网页端可以在手机上直接操作,也可以部署在局域网或公网服务器上;固件端支持普通 WiFi 和可选校园网等多种接入方式,方便适配不同的使用环境。 +这个项目源于一个直接需求:用一块 NodeMCU 控制普通红外空调,同时把固件、网页服务、PCB 和红外学习流程整理成一套可以从零搭建的方案。 ## 界面预览 -

- 桌面端控制界面 -

- -

- 移动端控制界面 -

- -桌面端和移动端使用同一套响应式页面;图中数据为演示数据,仅用于展示界面布局。完整功能说明见[部署指南](./docs/中文/部署指南.md)。 + + + + + +
桌面端控制界面移动端控制界面
-## 主要功能 +同一套响应式页面,支持桌面和手机访问。截图使用演示数据,仅展示界面布局。 -- 手机网页控制空调开关、模式和常用状态; -- DHT11 温湿度监测; -- 定时任务和温度自动控制; -- ESP8266 通过 MQTT 与云端通信; -- 支持普通 WPA/WPA2 WiFi 和可选 Srun 校园网认证; -- 红外学习工具用于采集用户自己的遥控器数据。 +## 核心能力 -手机网页控制需要前端、后端、MQTT Broker 和 ESP8266 固件共同运行。固件本身也可以单独使用,用于串口交互、传感器采集和红外硬件调试。各部分可以分别开发和部署;替换前端、后端、Broker 或固件时,需要保持现有 API 与 MQTT 协议兼容。 +- 通过手机网页控制空调开关、模式和常用状态 +- 查看 DHT11 温湿度与设备在线状态 +- 设置周期定时任务 +- 使用双阈值滞回温控,避免频繁启停 +- 通过 MQTT 连接 ESP8266 与云端,并可选接入 Srun 校园网 +- 从自己的遥控器学习红外码 ## 快速开始 -| 目标 | 从这里开始 | +| 目标 | 下一步 | |---|---| -| 普通家庭或实验室 WiFi | [首次配置指南](./docs/中文/首次配置.md) | -| 西电校园网 | [西电校园网自动认证](./docs/中文/西电校园网自动认证.md) | -| 编译 ESP8266 固件 | [PlatformIO 固件指南](./firmware/agent-platformio/README.md) | -| 使用 Arduino IDE | [Arduino IDE 使用指南](./docs/中文/Arduino-IDE使用指南.md) | -| 部署自己的服务器 | [部署指南](./docs/中文/部署指南.md) | -| 学习自己的遥控器 | [红外学习指南](./docs/中文/红外学习.md) | -| 制造 PCB | [PCB 说明](./hardware/pcb/README.md) | - -一个最小公开构建示例: +| 只验证源码 | 无需真实凭据,运行下面的公开 PlatformIO 构建。 | +| 制作真实设备 | 按顺序阅读[接线说明](./docs/中文/接线说明.md)、[首次配置](./docs/中文/首次配置.md)和[红外学习](./docs/中文/红外学习.md),再烧录固件。 | +| 部署完整网页控制 | 根据[部署指南](./docs/中文/部署指南.md)配置后端、前端和 MQTT,再连接设备。 | ```powershell cd firmware/agent-platformio ./tools/dev.ps1 build -Profile public ``` -这是无凭据公开构建,不是完全离线构建:固件仍会编译 WiFi 和云端模块,只是不包含真实凭据,默认也不会在开机时自动连接网络。 - -想了解如何为普通家庭路由器或西电校园网准备本地凭据、如何烧录固件,请从上面的[首次配置指南](./docs/中文/首次配置.md)开始。如果只是想先编译一次验证环境可用,执行上面的命令即可,不需要创建任何凭据文件。 +公开构建会编译 WiFi 和云端模块,但不带真实凭据,也不会在开机时自动连接网络。 -关于每种配置方式对应的编译开关和命令行参数,文档中都有对应的说明;遇到问题也可以先查看[故障排查](./docs/中文/故障排查.md)。 +## 系统结构 -## 系统组成 - -``` -手机网页 → 云端 → MQTT → ESP8266 → 红外 → 空调 +```text +手机网页 → Fastify 后端 → MQTT → ESP8266 → 红外 → 空调 ``` -服务端使用 Fastify,前端使用 Vue 3,设备端为 NodeMCU ESP8266。 +Vue 3 前端负责桌面和手机界面,NodeMCU ESP8266 采集传感器数据并驱动红外模块。 -项目按目录组织:`firmware/` 是 ESP8266 固件(PlatformIO 与 Arduino IDE 两种使用方式),`cloud/` 是云端后端与网页前端,`hardware/` 是 PCB 资料,`tools/` 是红外学习工具与辅助脚本。各部分通过 MQTT 消息协议衔接,详细约定见 [MQTT 协议](./docs/中文/MQTT协议.md)。 +| 目录 | 内容 | +|---|---| +| `firmware/` | PlatformIO 与 Arduino IDE 固件工程 | +| `cloud/` | Fastify 后端、Vue 3 前端和部署配置 | +| `hardware/` | 接线、PCB 源文件与制造资料 | +| `tools/` | 红外学习工具及项目维护脚本 | +| `docs/` | 中英文使用、设计和维护文档 | -云端后端、网页前端和固件可以分别启动和调试;完整的手机网页控制需要三部分与一个 MQTT Broker 一起运行。固件内部支持多种网络接入方式,配置方法见对应的[首次配置指南](./docs/中文/首次配置.md)。 +## 已验证硬件 -## 硬件 +| 类别 | 型号或修订 | +|---|---| +| 开发板 | NodeMCU ESP8266 | +| 温湿度传感器 | DHT11 | +| 红外模块 | ZJ-IR-V2 | +| PCB | Rev 1.0.1 | -- 开发板:NodeMCU ESP8266 -- 温湿度:DHT11 -- 红外模块:ZJ-IR-V2 -- PCB:Rev 1.0.1 +使用其他开发板或红外模块时,需要重新核对引脚、电平和通信协议。 -项目已在 NodeMCU ESP8266、DHT11 和 ZJ-IR-V2 上完成开发和验证。使用其他 ESP8266 开发板或红外模块时,需要重新核对引脚、电平和通信协议。 +## 文档入口 -公开仓库不提供真实空调红外码,也未提供经过验证的 BOM 和贴片坐标文件。你可以用[红外学习工具](./docs/中文/红外学习.md)从自己的遥控器上采集红外数据,再按[首次配置指南](./docs/中文/首次配置.md)烧录进设备。 +| 开始使用 | 架构与协议 | 维护与排障 | 参与项目 | +|---|---|---|---| +| [首次配置](./docs/中文/首次配置.md) | [系统架构](./docs/中文/系统架构.md) | [运维指南](./docs/中文/运维指南.md) | [参与贡献](./CONTRIBUTING.md) | +| [Arduino IDE](./docs/中文/Arduino-IDE使用指南.md) | [MQTT 协议](./docs/中文/MQTT协议.md) | [故障排查](./docs/中文/故障排查.md) | [支持说明](./SUPPORT.md) | +| [部署指南](./docs/中文/部署指南.md) | [安全模型](./docs/中文/安全模型.md) | [备份与恢复](./docs/中文/备份与恢复.md) | [安全策略](./SECURITY.md) | -## 文档 +完整列表见[中文文档导航](./docs/中文/文档导航.md)。 -| 了解项目 | 使用与配置 | 维护与排障 | -|---|---|---| -| [系统架构](./docs/中文/系统架构.md) | [首次配置指南](./docs/中文/首次配置.md) | [运维指南](./docs/中文/运维指南.md) | -| [安全模型](./docs/中文/安全模型.md) | [Arduino IDE 使用指南](./docs/中文/Arduino-IDE使用指南.md) | [故障排查](./docs/中文/故障排查.md) | -| [MQTT 协议](./docs/中文/MQTT协议.md) | [部署指南](./docs/中文/部署指南.md) | [备份与恢复](./docs/中文/备份与恢复.md) | -| [更新日志](./docs/中文/更新日志.md) | [红外学习](./docs/中文/红外学习.md) | [安全策略](./docs/中文/安全策略.md) | +## 安全与限制 -英文文档见 [English documentation index](./docs/English/documentation-index.md)。 +
+搭建前需要了解的边界 -所有文档都提供中英文两种版本,并保持相同的目录结构,方便切换语言对照阅读。如果某个主题在表格中没有列出来,可以在[文档导航](./docs/中文/文档导航.md)里按目录查找。 +- 公共仓库不含真实 WiFi、MQTT 或校园网凭据。 +- 项目不提供真实空调红外码,请从自己的遥控器学习。 +- 真实红外发送默认受固件安全策略限制。 +- 其他开发板和红外模块可能需要适配。 +- Windows 红外学习工具的 EXE 未签名。 +- PCB 资料不含未经验证的 BOM 或贴片坐标。 -## 参与贡献与支持 +
-欢迎提交 Issue 和 Pull Request,请先阅读[贡献指南](./docs/中文/参与贡献.md)。如果你希望为项目贡献代码或文档,请先查看贡献指南中的约定,确保改动符合项目的结构和风格。如果你在使用中发现了问题,欢迎在 [Issues](https://github.com/nobodycareme/remote-ac-controller/issues) 中描述现象和环境信息,这样能帮助维护者更快定位。安全漏洞请通过 GitHub 的 Private Vulnerability Reporting 报告,见[安全策略](./docs/中文/安全策略.md)。使用问题请先查阅[文档导航](./docs/中文/文档导航.md),或在 Issues 中提问。 +## 贡献、支持和许可 -项目使用 [Apache License 2.0](./LICENSE) 许可,第三方组件许可见[第三方组件许可声明](./docs/中文/第三方许可说明.md)。所有代码与文档均在本仓库内维护,发布说明见[更新日志](./docs/中文/更新日志.md)与 [GitHub Releases](https://github.com/nobodycareme/remote-ac-controller/releases)。 +提交改动前请阅读[贡献指南](./CONTRIBUTING.md);使用问题和缺陷入口见[支持说明](./SUPPORT.md)。安全漏洞请通过 GitHub Private Vulnerability Reporting 提交,不要公开披露。 -如果某个功能的行为与文档描述不一致,也欢迎通过 Issue 反馈。 +项目采用 [Apache License 2.0](./LICENSE),第三方组件许可见[第三方许可说明](./docs/中文/第三方许可说明.md)。 diff --git a/SECURITY.md b/SECURITY.md index ee5e376..89a2f10 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,44 +1,18 @@ -**简体中文** | [English](./docs/English/security.md) +[简体中文](./docs/中文/安全策略.md) | [English](./docs/English/security.md) # Security Policy / 安全策略 -## 支持的版本(Supported Versions) +## 报告漏洞 -| 版本 | 支持状态 | -|---|---| -| v1.2.x(最新发布) | 支持,建议及时更新 | -| 更早版本 | 不再维护 | - -## 报告安全漏洞(Reporting a Vulnerability) - -**请勿通过公开 Issue 报告安全漏洞。** 公开评论中的敏感细节会泄露给所有人。 - -请使用 GitHub 私有安全漏洞报告功能(仓库 `Security` → `Report a vulnerability`)。 -我们会在七个自然日内确认收到有效报告(We aim to acknowledge valid security -reports within seven days),并尽可能在修复发布前保持细节私密。 - -## 属于安全问题的范围 +**不要通过公开 Issue 报告安全问题。** 请使用 GitHub [Private Vulnerability Reporting](https://github.com/nobodycareme/remote-ac-controller/security/advisories/new),并只提供复现所需的最少信息。 -- 凭据泄露或可被读取的凭据材料 -- 会话、身份验证或授权绕过 -- MQTT/TLS 通信或证书处理的缺陷 -- 拒绝服务或资源耗尽风险 -- 公开仓库中出现生产私钥、真实红外码、数据库或个人信息 +提交日志或附件前,请移除真实密码、Token、WiFi/MQTT/校园网凭据、证书私钥、数据库和真实空调红外数据。 -## 属于普通 Bug 的范围 +## 支持版本 -- 功能不符合预期、编译/构建问题、文档错误、性能问题 -- 这类问题请通过公开 [Issue](https://github.com/nobodycareme/remote-ac-controller/issues) 提交 - -## 凭据泄露时的处理建议 - -如果你认为公开内容中泄露了任何生产凭据: - -1. 立即通过私有漏洞报告渠道告知维护者; -2. 在维护者确认前,不要公开描述泄露的具体值; -3. 维护者将评估并安排凭据轮换与公开内容清理。 - -## 详细指南 +| Version / 版本 | Status / 状态 | +|---|---| +| 最新 v1.2.x Release | Supported / 支持 | +| 更早版本 | Not maintained / 不再维护 | -- 中文:[安全策略](./docs/中文/安全策略.md) -- English: [security](./docs/English/security.md) +报告范围、处理流程和部署方责任见[中文安全策略](./docs/中文/安全策略.md)与 [English security policy](./docs/English/security.md)。普通缺陷请按 [SUPPORT.md](./SUPPORT.md) 选择公开入口。 diff --git a/SUPPORT.md b/SUPPORT.md index 765c051..e05b85a 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -1,32 +1,13 @@ -**简体中文** | [English](./docs/English/support.md) +[简体中文](./docs/中文/支持说明.md) | [English](./docs/English/support.md) # Support / 支持说明 -## 使用与配置问题 +| 需求 | 入口 | +|---|---| +| 使用或配置问题 | 先查[文档导航](./docs/中文/文档导航.md)和[故障排查](./docs/中文/故障排查.md),再提交已脱敏的 Issue。 | +| 可复现缺陷 | 使用 [Bug report](https://github.com/nobodycareme/remote-ac-controller/issues/new/choose),附版本、组件、步骤和日志。 | +| 功能建议 | 使用 [Feature request](https://github.com/nobodycareme/remote-ac-controller/issues/new/choose),说明场景与当前限制。 | +| 文档问题 | 使用 [Documentation issue](https://github.com/nobodycareme/remote-ac-controller/issues/new/choose),注明路径和语言。 | +| 安全漏洞 | 不要公开提交;使用 [Private Vulnerability Reporting](https://github.com/nobodycareme/remote-ac-controller/security/advisories/new)。 | -先查阅[文档导航](./docs/中文/文档导航.md)中的对应指南(部署、运维、固件、接线等)。 -若未解决,在 [GitHub Issue](https://github.com/nobodycareme/remote-ac-controller/issues) -中描述你的环境、复现步骤与相关日志(不要包含生产凭据)。 - -## 可复现的 Bug - -在 Issue 中提供: - -- 版本(固件 `version` 命令输出 / Release tag) -- 复现步骤与期望/实际行为 -- 相关串口日志或后端日志(脱敏后) - -## 功能建议 - -通过 [GitHub Issue](https://github.com/nobodycareme/remote-ac-controller/issues) -提交功能建议,说明使用场景与期望行为。 - -## 安全漏洞 - -**请勿公开提交。** 使用 GitHub Private Vulnerability Reporting(仓库 -`Security` → `Report a vulnerability`),详见 [SECURITY.md](./SECURITY.md)。 - -## 详细指南 - -- 中文:[支持说明](./docs/中文/支持说明.md) -- English: [support](./docs/English/support.md) +公开内容中不得包含真实凭据、数据库、证书私钥或真实红外数据。支持范围与自托管责任见[中文支持说明](./docs/中文/支持说明.md)和 [English support guide](./docs/English/support.md)。 diff --git a/docs/English/documentation-index.md b/docs/English/documentation-index.md index e687a3c..fc3b3f8 100644 --- a/docs/English/documentation-index.md +++ b/docs/English/documentation-index.md @@ -1,73 +1,54 @@ -[简体中文](../中文/文档导航.md) | **English** +[简体中文](../中文/文档导航.md) | **English** -# Documentation Index +# Documentation index -This page indexes all English technical documentation for Remote AC Controller. Every document carries a language switch at the top so you can jump to its Chinese counterpart; the Chinese index lives at [中文文档导航](../中文/文档导航.md). +Start with one of the reading paths below, or browse by topic. Each first-party document appears in one group only. -Back to the repository root: [`README.md`](./README.md) +## Recommended paths -## Getting Started +- **Home user**: use [Getting started](#getting-started) in this order: wiring, first-time setup, IR learning, and deployment. +- **Source validation only**: open [Getting started](#getting-started) for the PlatformIO firmware project, then the Cloud development environment. +- **Maintainer**: read [Understand the system](#understand-the-system) before the operations and release guides. -- [Project overview and quick start](./README.md) — capabilities, architecture diagram, one-shot validation commands -- [Arduino IDE guide](./arduino-ide-guide.md) — build, upload, and debug the firmware with Arduino IDE 2.x -- [Deployment](./deployment.md) — full deployment flow for backend, frontend, and MQTT broker -- [Operations guide](./operations-guide.md) — routine checks, logs, certificate rotation, upgrades +## Getting started -## How It Works +- [First-time setup](./first-time-setup.md) — configure networking, credentials, and firmware safety switches +- [Wiring](./wiring.md) — verify pins and physical connections +- [Arduino IDE guide](./arduino-ide-guide.md) — build and upload with Arduino IDE 2.x +- [PlatformIO firmware project](../../firmware/agent-platformio/README.en.md) — build the firmware with the public profile +- [Deployment](./deployment.md) — deploy the backend, frontend, and MQTT broker -- [Architecture](./architecture.md) — end-to-end components, data flow, and boundaries -- [Security model](./security-model.md) — roles, sessions, IR kill switches, threat surface -- [Xidian campus network authentication](./xidian-campus-network-authentication.md) — automatic Srun authentication on ESP8266 boot -- [Srun campus network porting guide](./srun-campus-network-porting-guide.md) — adapting to other Srun-based campuses +## Understand the system -## Hardware and Wiring +- [Architecture](./architecture.md) — components, data flow, and boundaries +- [MQTT protocol](./mqtt-protocol.md) — topics, messages, and presence state +- [Security model](./security-model.md) — identity, sessions, credentials, and IR safety boundaries +- [Hardware](./hardware.md) — verified components and PCB file scope -- [Hardware](./hardware.md) — board, sensor, IR module, and PCB selection -- [Wiring](./wiring.md) — pin assignment and physical wiring +## Feature guides -## IR Learning +- [IR learning](./ir-learning.md) — capture and validate data from your own remote +- [Scheduling](./scheduling.md) — configure recurring tasks +- [Temperature automation](./temperature-automation.md) — configure dual-threshold hysteresis +- [Xidian campus network authentication](./xidian-campus-network-authentication.md) — configure the currently verified Srun access flow +- [Srun campus network porting guide](./srun-campus-network-porting-guide.md) — adapt the implementation to another Srun deployment -- [IR learning](./ir-learning.md) — capture remote-control IR frames and load them into firmware +## Maintain the project -## Cloud and MQTT +- [Operations guide](./operations-guide.md) — routine checks, logs, certificate rotation, and upgrades +- [Troubleshooting](./troubleshooting.md) — diagnose common firmware and cloud problems +- [Backup and recovery](./backup-and-recovery.md) — backup, restore, and drills +- [Resource-constrained deployment](./resource-constrained-deployment.md) — control build resources on a 1 GB host +- [Versioning](./versioning.md) — distinguish software versions from PCB revisions +- [Hardware release process](./hardware-release-process.md) — package and verify manufacturing files +- [Maintainer release process](./maintainer-release-process.md) — prepare, verify, and publish a version -- [MQTT protocol](./mqtt-protocol.md) — topic naming, payload structure, presence detection +## Participate -## Automation - -- [Scheduling](./scheduling.md) — weekly cron-style scheduled tasks -- [Temperature automation](./temperature-automation.md) — dual-threshold hysteresis control - -## Deployment and Operations - -- [Deployment](./deployment.md) — production deployment steps -- [Operations guide](./operations-guide.md) — runtime maintenance -- [Resource-constrained deployment](./resource-constrained-deployment.md) — build and runtime constraints on a 1 GB host - -## Security - -- [Security model](./security-model.md) — design-level security boundaries -- [Security policy](./security.md) — vulnerability reporting process and supported scope - -## Troubleshooting - -- [Troubleshooting](./troubleshooting.md) — common symptoms, diagnosis, and fixes - -## Backup and Recovery - -- [Backup and recovery](./backup-and-recovery.md) — database and configuration backup, restore, and drills - -## Project and Community - -- [Contributing](./contributing.md) — development workflow, commit conventions, required gates -- [Code of conduct](./code-of-conduct.md) — community behaviour standards -- [Support](./support.md) — support scope and help channels -- [Maintainer release process](./maintainer-release-process.md) — end-to-end release flow -- [Versioning](./versioning.md) — software version vs PCB revision -- [Hardware release process](./hardware-release-process.md) — PCB packaging and verification -- [Changelog](./changelog.md) — release history - -## Licensing - -- [Third-party notices](./third-party-notices.md) — licences and provenance of dependencies -- [Apache-2.0 licence](../../LICENSE) — authoritative English text (a Chinese reference translation is available at [Apache-2.0 许可证参考译文](../中文/Apache-2.0许可证参考译文.md)) +- [Contributing](./contributing.md) — development workflow and submission requirements +- [Support](./support.md) — routes for usage questions, defects, and proposals +- [Security policy](./security.md) — report vulnerabilities privately +- [Code of conduct](./code-of-conduct.md) — community collaboration rules +- [Changelog](./changelog.md) — software release history +- [Third-party notices](./third-party-notices.md) — dependency licences and provenance +- [Apache License 2.0](../../LICENSE) — authoritative project licence diff --git "a/docs/\344\270\255\346\226\207/\346\226\207\346\241\243\345\257\274\350\210\252.md" "b/docs/\344\270\255\346\226\207/\346\226\207\346\241\243\345\257\274\350\210\252.md" index 4afdc54..1223347 100644 --- "a/docs/\344\270\255\346\226\207/\346\226\207\346\241\243\345\257\274\350\210\252.md" +++ "b/docs/\344\270\255\346\226\207/\346\226\207\346\241\243\345\257\274\350\210\252.md" @@ -1,76 +1,54 @@ -**简体中文** | [English](../English/documentation-index.md) +**简体中文** | [English](../English/documentation-index.md) # 文档导航 -本页是 Remote AC Controller 全部中文技术文档的索引。每篇文档顶部都有语言切换入口,可直接跳转到对应的英文版本;英文索引见 [English documentation index](../English/documentation-index.md)。 +从下面的阅读路径开始,或按主题查找文档。每篇第一方文档只在一个分类中出现。 -返回仓库根目录:[`README.md`](../../README.md) +## 推荐阅读路径 -## 快速上手 +- **普通家庭用户**:从[开始使用](#开始使用)依次选择接线、首次配置、红外学习和部署。 +- **只验证源码**:从[开始使用](#开始使用)进入 PlatformIO 固件工程,再查看 Cloud 开发环境。 +- **维护者**:先读[理解系统](#理解系统),再进入运维指南和维护者发布流程。 -- [项目总览与快速开始](../../README.md) — 系统能力、架构图、一键验证命令 -- [Arduino IDE 使用指南](./Arduino-IDE使用指南.md) — 用 Arduino IDE 2.x 编译、上传与调试固件 -- [部署指南](./部署指南.md) — 云端后端、前端与 MQTT Broker 的完整部署流程 -- [运维指南](./运维指南.md) — 日常巡检、日志、证书轮换与升级 +## 开始使用 -## 系统原理 +- [首次配置](./首次配置.md) — 配置网络、凭据和固件安全开关 +- [接线说明](./接线说明.md) — 核对引脚和实物连接 +- [Arduino IDE 使用指南](./Arduino-IDE使用指南.md) — 使用 Arduino IDE 2.x 编译和上传 +- [PlatformIO 固件工程](../../firmware/agent-platformio/README.md) — 使用公开配置构建固件 +- [部署指南](./部署指南.md) — 部署后端、前端和 MQTT Broker -- [系统架构](./系统架构.md) — 端到端组件、数据流与边界 -- [安全模型](./安全模型.md) — 角色、会话、红外开关与威胁面 -- [西电校园网自动认证](./西电校园网自动认证.md) — ESP8266 上电自动完成 Srun 认证 -- [Srun 校园网移植指南](./Srun校园网移植指南.md) — 适配到其他使用 Srun 的学校 +## 理解系统 -## 硬件与接线 +- [系统架构](./系统架构.md) — 组件、数据流和边界 +- [MQTT 协议](./MQTT协议.md) — 主题、消息和在线状态 +- [安全模型](./安全模型.md) — 身份、会话、凭据和红外安全边界 +- [硬件说明](./硬件说明.md) — 已验证硬件和 PCB 资料范围 -- [硬件说明](./硬件说明.md) — 开发板、传感器、红外模块与 PCB 选型 -- [接线说明](./接线说明.md) — 引脚分配与实物接线 +## 功能指南 -## 红外学习 +- [红外学习](./红外学习.md) — 采集并验证自己的遥控器数据 +- [定时任务](./定时任务.md) — 配置周期调度 +- [温度自动控制](./温度自动控制.md) — 配置双阈值滞回温控 +- [西电校园网自动认证](./西电校园网自动认证.md) — 配置当前已验证的 Srun 接入 +- [Srun 校园网移植指南](./Srun校园网移植指南.md) — 适配其他 Srun 部署 -- [红外学习](./红外学习.md) — 采集遥控器红外帧并写入固件的完整流程 +## 维护项目 -## 云端与 MQTT +- [运维指南](./运维指南.md) — 巡检、日志、证书轮换和升级 +- [故障排查](./故障排查.md) — 定位常见固件和云端问题 +- [备份与恢复](./备份与恢复.md) — 备份、还原和演练 +- [低配置服务器部署](./低配置服务器部署.md) — 在 1 GB 主机上控制构建资源 +- [版本管理](./版本管理.md) — 区分软件版本与 PCB 修订 +- [PCB 发布流程](./PCB发布流程.md) — 打包和校验制造数据 +- [维护者发布流程](./维护者发布流程.md) — 准备、验证和发布版本 -- [MQTT 协议](./MQTT协议.md) — 主题命名、报文结构与在线判定 +## 参与项目 -## 自动化 - -- [定时任务](./定时任务.md) — 按星期掩码的周期调度 -- [温度自动控制](./温度自动控制.md) — 双阈值滞回温控 - -## 部署运维 - -- [部署指南](./部署指南.md) — 生产部署步骤 -- [运维指南](./运维指南.md) — 运行期维护 -- [低配置服务器部署](./低配置服务器部署.md) — 1 GB 内存机器的构建与运行约束 - -## 安全 - -- [安全模型](./安全模型.md) — 设计层面的安全边界 -- [安全策略](./安全策略.md) — 漏洞报告流程与支持范围 - -## 故障排查 - -- [故障排查](./故障排查.md) — 常见故障现象、定位方法与修复 - -## 备份恢复 - -- [备份与恢复](./备份与恢复.md) — 数据库与配置的备份、还原与演练 - -## 维护者 - -- [维护者发布流程](./维护者发布流程.md) — 从提交到发布的完整流程 -- [版本管理](./版本管理.md) — 软件版本与 PCB 修订的版本体系 -- [PCB 发布流程](./PCB发布流程.md) — 制造数据打包、校验与修订 - -## 项目与社区 - -- [参与贡献](./参与贡献.md) — 开发流程、提交规范与门禁要求 -- [行为准则](./行为准则.md) — 社区行为规范 -- [支持说明](./支持说明.md) — 支持范围与求助渠道 -- [更新日志](./更新日志.md) — 版本变更记录 - -## 许可 - -- [第三方许可说明](./第三方许可说明.md) — 依赖组件的许可与来源 -- [Apache-2.0 许可证参考译文](./Apache-2.0许可证参考译文.md) — 中文参考译文(正本以根目录 [`LICENSE`](../../LICENSE) 英文原文为准) +- [参与贡献](./参与贡献.md) — 开发流程和提交要求 +- [支持说明](./支持说明.md) — 使用问题、缺陷和建议的入口 +- [安全策略](./安全策略.md) — 私下报告安全漏洞 +- [行为准则](./行为准则.md) — 社区协作规则 +- [更新日志](./更新日志.md) — 软件版本变更 +- [第三方许可说明](./第三方许可说明.md) — 依赖许可和来源 +- [Apache-2.0 许可证参考译文](./Apache-2.0许可证参考译文.md) — 中文参考译文,英文正本见根目录 [`LICENSE`](../../LICENSE) diff --git a/tools/README.md b/tools/README.md new file mode 100644 index 0000000..000b7f2 --- /dev/null +++ b/tools/README.md @@ -0,0 +1,60 @@ +# 工具目录 / Tools + +本目录同时包含用户工具和仓库维护脚本。现有路径被 CI、发布流程、文档或源码引用,因此本轮保持路径不变;新增脚本时应先选择下面的职责分类,避免继续形成无说明的平铺目录。 + +## 用户工具 / User tools + +| Path | Purpose | +|---|---| +| [`ir-simple-learner/`](./ir-simple-learner/) | Windows 红外学习应用的源码、依赖锁定、构建入口和双语说明。 | + +普通用户通常只需要这一组。使用方法见[中文说明](./ir-simple-learner/README.md)或 [English guide](./ir-simple-learner/README.en.md)。 + +## Validation + +| Path | Purpose | +|---|---| +| [`check-cloud-secret-authority.py`](./check-cloud-secret-authority.py) | 检查 Cloud 凭据来源和忽略规则。 | +| [`check-doc-language-links.py`](./check-doc-language-links.py) | 检查中英文文档的跨语言链接边界。 | +| [`check-doc-links.mjs`](./check-doc-links.mjs) | 检查 Cloud 文档链接和结构。 | +| [`check-doc-links.py`](./check-doc-links.py) | 检查全仓库第一方相对链接。 | +| [`check-doc-parity.py`](./check-doc-parity.py) | 检查中英文文档映射。 | +| [`check-doc-structure.mjs`](./check-doc-structure.mjs) | 检查 Cloud 文档章节结构。 | +| [`check-ir-tool-parity.py`](./check-ir-tool-parity.py) | 检查红外学习工具与固件预设的一致性。 | +| [`check-no-insecure-tls.py`](./check-no-insecure-tls.py) | 阻止不安全的 TLS 客户端配置。 | +| [`check-pcb-release.py`](./check-pcb-release.py) | 校验 PCB 制造包合同。 | +| [`check-public-docs.py`](./check-public-docs.py) | 检查公开主页、文档索引和社区入口。 | +| [`check-readme-render.py`](./check-readme-render.py) | 通过 GitHub Markdown API 验证 README 渲染。 | +| [`check-v126-reproducibility.py`](./check-v126-reproducibility.py) | 检查 v1.2.6 部署与所有者合同。 | +| [`check-version.py`](./check-version.py) | 检查各组件软件版本一致。 | +| [`security_scan.py`](./security_scan.py) | 扫描公开文件中的秘密和高风险材料。 | +| [`test-devps1-profile-contract.py`](./test-devps1-profile-contract.py) | 验证固件开发脚本的 Profile 行为。 | +| [`test-public-docs-negative.py`](./test-public-docs-negative.py) | 证明公开文档检查能拦截故意破坏。 | +| [`test-v126-reproducibility-negative.py`](./test-v126-reproducibility-negative.py) | 证明 v1.2.6 复现检查能拦截合同漂移。 | +| [`test-wifi-ssid-parity.py`](./test-wifi-ssid-parity.py) | 验证两个固件入口的 SSID 行为一致。 | +| [`validate-cloud-secrets.py`](./validate-cloud-secrets.py) | 验证 Cloud 本地秘密文件的字段与占位值。 | + +## Release + +| Path | Purpose | +|---|---| +| [`package-pcb-release.py`](./package-pcb-release.py) | 生成 PCB Release 制造包。 | +| [`pcb_release_contract.py`](./pcb_release_contract.py) | 定义 PCB 制造包的文件合同。 | + +发布脚本会影响资产内容。修改前应先阅读[维护者发布流程](../docs/中文/维护者发布流程.md)或 [Maintainer release process](../docs/English/maintainer-release-process.md)。 + +## Development + +| Path | Purpose | +|---|---| +| [`build-all.ps1`](./build-all.ps1) | 构建 Cloud、固件和红外学习工具。 | +| [`test-all.ps1`](./test-all.ps1) | 运行跨组件测试与校验。 | +| [`gen-wifi-ssid-cases.py`](./gen-wifi-ssid-cases.py) | 生成 SSID 边界测试样例。 | +| [`prepare_srun_arduino_library.py`](./prepare_srun_arduino_library.py) | 为 Arduino IDE 工程准备 Srun 库。 | + +## 路径约定 / Path policy + +- 用户文档应链接到稳定入口,不要链接临时输出。 +- Validation 脚本只检查合同,不修改产品数据。 +- Release 脚本必须保持资产内容可复核。 +- 路径迁移需要同步更新 CI、文档、导入和发布流程,并运行完整测试;在这些条件满足前保留现有路径。 diff --git a/tools/check-public-docs.py b/tools/check-public-docs.py index 8a56d9c..e1b5d58 100644 --- a/tools/check-public-docs.py +++ b/tools/check-public-docs.py @@ -59,12 +59,13 @@ def resolve_root(): # Exact ordered H2 mapping (CN index -> EN index). CN_H2 = [ - "项目简介", "界面预览", "主要功能", "快速开始", - "系统组成", "硬件", "文档", "参与贡献与支持", + "项目简介", "界面预览", "核心能力", "快速开始", "系统结构", + "已验证硬件", "文档入口", "安全与限制", "贡献、支持和许可", ] EN_H2 = [ - "Overview", "Interface preview", "Features", "Quick start", - "System layout", "Hardware", "Documentation", "Contributing and support", + "Overview", "Interface preview", "Core capabilities", "Quick start", "System layout", + "Verified hardware", "Documentation", "Security and limits", + "Contributing, support, and license", ] H2_PAIRS = list(zip(CN_H2, EN_H2)) @@ -238,6 +239,57 @@ def git_ls_files(path): return None +COMMUNITY_FILES = ["CONTRIBUTING.md", "SECURITY.md", "SUPPORT.md", "CODE_OF_CONDUCT.md"] +ISSUE_FORMS = { + ".github/ISSUE_TEMPLATE/bug-report.yml": {"description", "steps", "expected", "actual", "version", "component", "logs", "sensitive-data"}, + ".github/ISSUE_TEMPLATE/feature-request.yml": {"use-case", "limitation", "proposal", "component", "sensitive-data"}, + ".github/ISSUE_TEMPLATE/documentation.yml": {"path", "issue-type", "language", "proposal", "sensitive-data"}, +} +INDEX_H2_CN = ["推荐阅读路径", "开始使用", "理解系统", "功能指南", "维护项目", "参与项目"] +INDEX_H2_EN = ["Recommended paths", "Getting started", "Understand the system", "Feature guides", "Maintain the project", "Participate"] +MARKETING_PHRASES = [ + "方便适配", "灵活支持", "丰富功能", "一站式", "全方位", "完整覆盖", "强大", "高效便捷", "适用于多种场景", + "production-grade", "enterprise-grade", "highly reliable", "one-stop", "powerful and flexible", +] + + +def markdown_targets(text): + return [m.group(1).strip().split("#", 1)[0] for m in re.finditer(r"\[[^\]]+\]\(([^)]+)\)", text)] + + +def issue_form_error(path, required_ids): + full = os.path.join(ROOT, path) + if not os.path.isfile(full): + return "missing file" + text = read(path) + try: + import yaml + data = yaml.safe_load(text) + except ImportError: + return "PyYAML is required" + except Exception as exc: + return f"YAML parse error: {exc}" + if isinstance(data, dict): + if not isinstance(data.get("body"), list): + return "body must be a list" + ids = {item.get("id") for item in data["body"] if isinstance(item, dict) and item.get("id")} + types = [item.get("type") for item in data["body"] if isinstance(item, dict)] + else: + return "top level must be a mapping" + missing = required_ids - ids + if missing: + return "missing ids: " + ", ".join(sorted(missing)) + allowed = {"markdown", "textarea", "input", "dropdown", "checkboxes"} + if any(item_type not in allowed for item_type in types): + return "unsupported body type" + return None + + +def duplicate_relative_links(path): + targets = [target for target in markdown_targets(read(path)) if target and not target.startswith(("http://", "https://", "mailto:"))] + return sorted({target for target in targets if targets.count(target) > 1}) + + def main(): ok = True cn = read("README.md") @@ -280,8 +332,8 @@ def main(): start = max(0, txt.rfind("\n", 0, m.start()), txt.rfind("。", 0, m.start()), txt.rfind(". ", 0, m.start()), txt.rfind(";", 0, m.start())) seg = txt[start:m.start()] - if re.search(r"(未提供|没有|不提供|不存在|无 )", seg) or \ - re.search(r"(no |not |without |does not ship|none )", seg, re.I): + if re.search(r"(未提供|没有|不提供|不存在|不含|无 )", seg) or \ + re.search(r"(no |not |without |does not ship|does not include|do not include|none )", seg, re.I): continue cnt_bom += 1 print(f"BOM_CLAIM {f}: {w!r}") @@ -297,10 +349,10 @@ def main(): # 4) H2 section parity: exact ordered mapping, at most 8 H2s cn_h2 = [h.strip() for h in re.findall(r"(?m)^## (.+)$", cn)] en_h2 = [h.strip() for h in re.findall(r"(?m)^## (.+)$", en)] - if len(cn_h2) > 8: - print(f"CN_H2_TOO_MANY actual={len(cn_h2)} (want <= 8)") + if len(cn_h2) > 9: + print(f"CN_H2_TOO_MANY actual={len(cn_h2)} (want <= 9)") ok = False - if len(en_h2) > 8: + if len(en_h2) > 9: print(f"EN_H2_TOO_MANY actual={len(en_h2)} (want <= 8)") ok = False if len(cn_h2) != len(CN_H2): @@ -418,14 +470,14 @@ def main(): # 9) setup link presence for txt in (cn, en): cnt_wifi += len(re.findall(r"首次配置|wifi_secrets|first-time-setup", txt)) - cnt_campus += len(re.findall(r"西电校园网自动认证|campus_secrets|xidian-campus-network-authentication", txt)) + cnt_campus += len(re.findall(r"校园网|Srun|campus", txt, re.I)) print(f"README_WIFI_SETUP_LINK_COUNT={cnt_wifi}") print(f"README_CAMPUS_SETUP_LINK_COUNT={cnt_campus}") if cnt_wifi < 2: print("README_WIFI_SETUP_LINKS_TOO_FEW (<2)") ok = False if cnt_campus < 2: - print("README_CAMPUS_SETUP_LINKS_TOO_FEW (<2)") + print("README_OPTIONAL_CAMPUS_ACCESS_MISSING (<2)") ok = False # 10) real-looking credentials @@ -545,11 +597,11 @@ def main(): print(f"BROKEN_LINK {f}: {t}") ok = False - # 16) line counts: CN 120-180, EN within 20% of CN + # 16) line counts: concise homepage, with comparable bilingual length cn_lines = len(cn.splitlines()) en_lines = len(en.splitlines()) - if not (120 <= cn_lines <= 180): - print(f"README_LINE_COUNT README.md = {cn_lines} (want 120-180)") + if not (100 <= cn_lines <= 180): + print(f"README_LINE_COUNT README.md = {cn_lines} (want 100-180)") ok = False lo, hi = int(cn_lines * 0.8), int(cn_lines * 1.2) if not (lo <= en_lines <= hi): @@ -930,6 +982,146 @@ def sentence_negated(txt, pos): else: print("V125_CN_EN_TLS_PRIORITY_MISMATCH=False") + # 21) public homepage and repository information-architecture contract + badge_counts = [] + for f, txt in [("README.md", cn), ("README.en.md", en)]: + badge_count = len(re.findall(r"]+(?:badge\.svg|img\.shields\.io)", txt, re.I)) + badge_counts.append(badge_count) + if badge_count > 4: + print(f"README_BADGE_LIMIT_ERROR {f}: {badge_count}") + ok = False + if re.search(r"(?i)(?:(?extra' + txt = txt.replace("

\n\n## 项目简介", badge + badge + "\n

\n\n## 项目简介") + open(p, "w", encoding="utf-8").write(txt) + + +def sabotage_43(root): + p = os.path.join(root, "README.en.md") + txt = open(p, encoding="utf-8").read() + "\nLocal notes: C:\\Temp\\Evidence\\result.txt\n" + open(p, "w", encoding="utf-8").write(txt) + + +def sabotage_44(root): + p = os.path.join(root, "README.md") + txt = open(p, encoding="utf-8").read() + "\n这是一套强大的一站式控制方案。\n" + open(p, "w", encoding="utf-8").write(txt) + + +def sabotage_45(root): + p = os.path.join(root, "README.en.md") + txt = open(p, encoding="utf-8").read() + flow = "Phone web UI → Fastify backend → MQTT → ESP8266 → IR → AC" + txt += "\n" + flow + "\n" + open(p, "w", encoding="utf-8").write(txt) + + +def sabotage_46(root): + p = os.path.join(root, "tools/README.md") + txt = open(p, encoding="utf-8").read() + "\n[Missing tool](./missing-tool.py)\n" + open(p, "w", encoding="utf-8").write(txt) + + +def sabotage_47(root): + p = os.path.join(root, ".github/ISSUE_TEMPLATE/documentation.yml") + txt = open(p, encoding="utf-8").read().replace("body:\n", "body:\n\t- invalid: tab-indented\n", 1) + open(p, "w", encoding="utf-8").write(txt) + + def main(): results = [ case(1, "markdown_in_html_block", sabotage_1), @@ -430,6 +488,18 @@ def main(): case(33, "set_insecure_recommended", sabotage_33), case(34, "fingerprint_no_rotation", sabotage_34), case(35, "cn_en_tls_priority_mismatch", sabotage_35), + case(36, "primary_start_path_removed", sabotage_36), + case(37, "readme_fact_parity", sabotage_37), + case(38, "doc_index_duplicate_link", sabotage_38), + case(39, "community_file_missing", sabotage_39), + case(40, "issue_form_required_field", sabotage_40), + case(41, "pr_template_section", sabotage_41), + case(42, "readme_badge_limit", sabotage_42), + case(43, "readme_absolute_private_path", sabotage_43), + case(44, "readme_marketing_phrase", sabotage_44), + case(45, "system_flow_duplicate", sabotage_45), + case(46, "tools_readme_broken_path", sabotage_46), + case(47, "issue_form_invalid_yaml", sabotage_47), ] total = len(results) passed = sum(results)