# 第一批移植任务提示词 (P0 基础架构) > 使用提示词时,将 `{编号}` 替换为对应任务的提示词正文。 --- ## 任务 1.1 — miot_error.py → miot_error.go ``` ## 任务:移植 MIoT 错误系统 源文件:D:\miot\py-miot\miot_error.py (151行) 目标文件:D:\miot\go-miot\miot_error.go (新建) 参考子文档:D:\miot\go-miot\migration\07-miot-err.md ### 需实现的内容 1. 错误码常量(Go 用 const iota,值对齐 Python 的 MIoTErrorCode 枚举): - CODE_UNKNOWN = -10000, CODE_UNAVAILABLE = -10001, CODE_INVALID_PARAMS = -10002 - CODE_RESOURCE_ERROR = -10003, CODE_INTERNAL_ERROR = -10004 - CODE_UNAUTHORIZED_ACCESS = -10005, CODE_TIMEOUT = -10006 - CODE_OAUTH_UNAUTHORIZED = -10020, CODE_HTTP_INVALID_ACCESS_TOKEN = -10030 - CODE_MIPS_INVALID_RESULT = -10040, CODE_CERT_INVALID_CERT = -10050 - CODE_CONFIG_INVALID_INPUT = -10100, CODE_CONFIG_INVALID_STATE = -10101 - CODE_LAN_UNAVAILABLE = -10120 2. MIoTError 结构体,实现 error 接口: - Code 字段(错误码), Message 字段(消息) - Error() 方法返回 "code=N, message=xxx" 格式 - ToDict() 方法返回 map[string]interface{} 3. 13 个子错误类型(Go 用类型别名 + 构造函数): MIoTOauthError, MIoTHttpError, MIoTMipsError, MIoTDeviceError, MIoTSpecError, MIoTStorageError, MIoTCertError, MIoTClientError, MIoTEvError, MipsServiceError, MIoTConfigError, MIoTOptionsError, MIoTLanError 4. 文件头注释标注 "package miot" ### 注意事项 - 无外部依赖,可独立编译 - 每个子类型提供 NewXxxError(message string) 构造函数 - 错误码用 const int 定义,不要用 iota(因为值不是连续的) ``` --- ## 任务 1.2 — const.py → const.go ``` ## 任务:移植 MIoT 常量系统 源文件:D:\miot\py-miot\const.py (161行) 目标文件:D:\miot\go-miot\const.go (新建) 参考子文档:D:\miot\go-miot\migration\08-miot-constant.md ### 需实现的内容 1. 字符串常量: DOMAIN="xiaomi_home", DEFAULT_NAME="Xiaomi Home", DEFAULT_NICK_NAME="Xiaomi" OAUTH2_CLIENT_ID, OAUTH2_AUTH_URL, DEFAULT_OAUTH2_API_HOST DEFAULT_CLOUD_BROKER_HOST, DEFAULT_CLOUD_SERVER, DEFAULT_CTRL_MODE DEFAULT_INTEGRATION_LANGUAGE, OAUTH_REDIRECT_URL 2. 数值常量: MIHOME_HTTP_API_TIMEOUT=30, MIHOME_MQTT_KEEPALIVE=60 MIHOME_CERT_EXPIRE_MARGIN=3600*24*3, NETWORK_REFRESH_INTERVAL=30 SPEC_STD_LIB_EFFECTIVE_TIME=3600*24*14 MANUFACTURER_EFFECTIVE_TIME=3600*24*14 3. 变量(切片/映射,需在 var() 中定义): SUPPORTED_PLATFORMS []string — 18 个平台名 UNSUPPORTED_MODELS []string — 4 个模型 CLOUD_SERVERS map[string]string — 6 个区域 SUPPORT_CENTRAL_GATEWAY_CTRL []string — ["cn"] INTEGRATION_LANGUAGES map[string]string — 13 种语言 DEFAULT/MIN/MAX_COVER_DEAD_ZONE_WIDTH int 4. CA 证书常量: MIHOME_CA_CERT_STR string — 两段 PEM 证书(用反引号多行字符串) MIHOME_CA_CERT_SHA256 string ### 注意事项 - 无外部依赖,可独立编译 - Go 不支持类型混合的常量组,数值单独一组,字符串单独一组 - 路径常量(如文件路径)用 Go 的 os.Getenv 或相对路径,不对齐 Python 的字面值 ``` --- ## 任务 1.3 — common.py → common.go ``` ## 任务:移植 MIoT 通用工具 源文件:D:\miot\py-miot\common.py (189行) 目标文件:D:\miot\go-miot\common.go (新建) 参考子文档:D:\miot\go-miot\migration\06-miot-utils.md ### 需实现的内容 1. 工具函数(全部为包级公开函数): - GenAbsolutePath(relativePath string) string — path.Join - CalcGroupID(uid, homeID string) string — SHA1 取前 16 位 hex - LoadJSONFile(filePath string) (map[string]interface{}, error) - LoadYAMLFile(filePath string) (map[string]interface{}, error) - RandomizeInt(value int, ratio float64) int - RandomizeFloat(value float64, ratio float64) float64 - SlugifyName(name string) string — 可用 github.com/gosimple/slug - SlugifyDID(cloudServer, did string) string — f"{cloudServer}_{did}" 后 slugify 2. MIoTHttp 工具类(可选,如已有 http_client.go 则跳过): - Get(url string, params, headers map[string]string) (string, error) - GetJSON(url string, params, headers map[string]string) (map[string]interface{}, error) - Post / PostJSON 同理 3. MIoTMatcher(可选,评估是否需要 MQTT topic 匹配功能) ### 依赖 - encoding/json, encoding/yaml (或 gopkg.in/yaml.v3) - crypto/sha1, encoding/hex - github.com/gosimple/slug (可选) - path/filepath, io/ioutil ### 注意事项 - 如果 go-miot 已有 http_client.go,HTTP 部分可跳过 - Slugify 如果用第三方库,需要在 go.mod 中添加依赖 ``` --- ## 任务 1.4 — miot_storage.py → miot_storage.go ``` ## 任务:移植 MIoT 存储系统 源文件:D:\miot\py-miot\miot_storage.py (789行) 目标文件:D:\miot\go-miot\miot_storage.go (新建) 依赖:miot_error.go, const.go 参考子文档:D:\miot\go-miot\migration\05-miot-storage.md ### 需实现的内容 1. MIoTStorage 结构体和方法: - 字段:rootPath string, mu sync.RWMutex - Load(domain, name string) ([]byte, error) — 读取文件 - Save(domain, name string, data interface{}) error — 支持 []byte/string/map/slice - Remove(domain, name string) error - RemoveDomain(domain string) error — 递归删除目录 - FileExists(domain, name string) bool - SaveFile / LoadFile — 二进制原始读写(不加哈希) - Clear() error — 清空所有存储 - 路径格式:{rootPath}/{domain}/{name} 2. 文件完整性: - Save 时将 SHA256 哈希追加到文件末尾 (32 bytes) - Load 时校验哈希,不一致返回 error 3. 异步支持: - 用 goroutine + channel 实现异步方法(LoadAsync, SaveAsync 等) - 注意并发安全(RWMutex) 4. 用户配置管理(可选,如果不需要可跳过): - UpdateUserConfig / LoadUserConfig 5. MIoTCert 证书管理(可选,P0 阶段可以仅定义结构体): - 证书加载、验证、生成 CSR 等方法可后续实现 ### 注意事项 - Python 的 async/await → Go 的 goroutine + channel - Python 的 asyncio.run_in_executor → Go 直接用 goroutine - 文件路径用 filepath.Join,Windows 兼容 - 哈希校验失败返回明确错误 ``` --- ## 任务 1.5 — miot_cloud.py → miot_cloud.go ``` ## 任务:移植 MIoT 云端 HTTP 客户端 源文件:D:\miot\py-miot\miot_cloud.py (714行) 目标文件:D:\miot\go-miot\miot_cloud.go (新建) 依赖:miot_error.go, const.go, common.go 参考子文档:D:\miot\go-miot\migration\03-miot-cloud.md ### 需实现的内容 1. MIoTOauthClient 结构体(OAuth 授权客户端): - 字段:clientID int64, redirectURL, oauthHost, deviceID, state string - 构造函数 NewMIoTOauthClient(clientID, redirectURL, cloudServer, uuid string) - GenAuthURL() — 生成授权 URL(URL 编码参数拼接) - GetAccessToken(code string) (map[string]interface{}, error) - RefreshAccessToken(refreshToken string) (map[string]interface{}, error) - Close() — 关闭 HTTP 连接 - token 过期时间计算:expires_ts = time.Now() + expires_in*0.7 2. MIoTHttpClient 结构体(云端 API 客户端): - 字段:host, baseURL, clientID, accessToken string - 构造函数 NewMIoTHttpClient(cloudServer, clientID, accessToken string) - UpdateHTTPHeader(cloudServer, clientID, accessToken string) - HTTP 请求头设置:X-Client-BizId=haapi, Authorization=Bearer{token} 3. 核心 API 方法: - GetUserInfo() — 获取用户信息 - GetHomeInfos() — 获取家庭信息(支持分页) - GetDevices(homeIDs []string) — 获取设备列表(合并设备信息和家庭/房间归属) - GetDevicesWithDIDs(dids []string) — 按 DID 批量获取设备 - GetProps(params []map) — 批量获取设备属性 - GetCentralCert(csr string) — 获取中央证书 - GetSeparatedSharedDevices() — 获取共享设备 - GetUID() — 获取用户 UID 4. 内部辅助方法: - __mihome_api_get(urlPath, params) — GET 请求(处理 401/非200 状态码) - __mihome_api_post(urlPath, data) — POST 请求 - __get_dev_room_page(maxID) — 分页获取设备和房间信息 - __get_device_list_page(dids, startDID) — 分页获取设备列表 ### API 端点(关键): POST /app/v2/ha/oauth/get_token — OAuth token POST /app/v2/homeroom/gethome — 获取家庭 POST /app/v2/homeroom/get_dev_room_page — 设备房间分页 POST /app/v2/home/device_list_page — 设备列表分页 POST /app/v2/miotspec/prop/get — 属性批量获取 GET https://open.account.xiaomi.com/user/profile — 用户信息 ### 注意事项 - 使用 net/http 标准库 - 设备过滤:跳过 miwifi.* 前缀,跳过 UNSUPPORTED_MODELS - 分页逻辑:Python 用递归,Go 可以用 for 循环 + break - Python asyncio.gather → Go sync.WaitGroup + goroutine - 子设备处理:.s\d+ 后缀的设备合并到父设备 ``` --- ## 任务 1.6 — miot_client.py → miot_client.go (补全) ``` ## 任务:补全 MIoT 客户端 源文件:D:\miot\py-miot\miot_client.py 目标文件:D:\miot\go-miot\miot_client.go (现有,需补全) 参考子文档:D:\miot\go-miot\migration\01-miot-client.md ### 补全检查清单 1. 客户端初始化: - 构造函数参数:cloudServer, accessToken, clientID, language, loop - 依赖注入:MIoTHttpClient, MIoTSpecInstance(列表), MIoTStorage, MIoTLan 2. 设备管理: - 设备发现和注册:从云端获取设备列表,创建 MIoTDevice 实例 - 设备存储:保存/加载设备实例到 storage 3. 属性操作: - GetProp(did, siid, piid) — 优先本地 MIPS,回退云端 - SetProp(did, siid, piid, value) — 只走云端(或 MIPS if connected) - 属性缓存和批量刷新 4. 事件订阅: - 订阅设备事件(MIPS 推送 + 云端轮询) - 事件回调管理 5. 资源管理: - Init() — 初始化 MIPS、LAN、云端连接 - Close() — 关闭所有连接,释放资源 - 重连机制 ### 关键结构体 type MIoTClient struct { cloudServer string accessToken string clientID string language string httpClient *MIoTHttpClient mipsClient *MIoTMipsClient lanManager *MIoTLan storage *MIoTStorage devices map[string]*MIoTDevice devMu sync.RWMutex // ... } ### 注意事项 - 先读现有 go-miot/miot_client.go,了解已实现的部分 - 只补全缺失功能,不要重写已有代码 - 并发安全(devices map 读写的锁保护) - 错误处理:所有外部调用都要处理 error ``` --- ## 任务 1.7 — miot_device.py → miot_device.go (补全) ``` ## 任务:补全 MIoT 设备模型 源文件:D:\miot\py-miot\miot_device.py 目标文件:D:\miot\go-miot\miot_device.go (现有,需补全) 参考子文档:D:\miot\go-miot\migration\02-miot-device.md ### 补全检查清单 1. MIoTDevice 结构体: - 基本字段:did, name, model, urn, token, ip, online bool - 制造商字段:manufacturer, icon - 归属字段:homeID, roomID, homeName, roomName, groupID - 连接类型:connectType, rssi, ssid, bssid - 版本:fwVersion - 子设备:subDevices map[int]*MIoTDevice - SPEC 引用:serviceList []*MIoTSpecService 2. 设备初始化: - NewMIoTDevice(client *MIoTClient, did string) *MIoTDevice - LoadFromCloud(client *MIoTClient, cloudData map) — 从云端数据填充 - LoadSPEC(client *MIoTClient) error — 从 SPEC 解析服务/属性/事件/动作 3. 属性操作: - GetProp(siid, piid int) (interface{}, error) — 委托给 client.GetProp - SetProp(siid, piid int, value interface{}) error — 委托给 client.SetProp - GetFormattedProp(siid, piid int) — 含值格式化和精度处理 4. 设备状态: - IsOnline() bool - SetOnline(online bool) - HasWiFi() — connectType != -1 判断 5. 序列化: - ToDict() map[string]interface{} — 用于 storage 保存 - FromDict(data map[string]interface{}) *MIoTDevice — 从 storage 加载 ### 注意事项 - 先读现有 go-miot/miot_device.go - SPEC 解析可能依赖 spec_parser.go(尚未完整),先预留接口 - 子设备用指针切片而非递归结构 ``` --- ## 依赖关系图(第一批内部) ``` ┌─────────────┐ │ miot_error │ ← 无依赖 └──────┬──────┘ │ ┌────────────────┼────────────────┐ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ const │ │ common │ │ storage │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ │ └───────────────┼───────────────┘ ▼ ┌──────────┐ │miot_cloud│ └────┬─────┘ │ ┌─────────┴─────────┐ ▼ ▼ ┌──────────┐ ┌──────────┐ │miot_client│◄─────│miot_device│ └──────────┘ └──────────┘ ``` ## 执行顺序 1. miot_error (最独立,先做) 2. const (无依赖) 3. common (无依赖) 4. miot_storage (依赖 error) 5. miot_cloud (依赖 error/const/common) 6. miot_client (依赖 cloud/device/storage) 7. miot_device (依赖 client/spec) ```