[English](./README.md) | 简体中文

# 电工定时功能页

给电工品类设备提供一套开箱即用的定时能力页面。宿主小程序只需注册 appid + 跳转带 `deviceId`，即可获得**六类定时**：普通(云)定时、循环定时、随机定时、倒计时、延时关、天文定时(日出/日落)。

> **appid（UIID）**：`typtepohxfeukudmyi`

---

## 目录

- [一、能支持哪些定时](#一能支持哪些定时)
- [二、三步接入（最小可用）](#二三步接入最小可用)
- [三、跳转路由清单](#三跳转路由清单)
- [四、参数速查](#四参数速查)
- [五、按场景推荐传参（怎么用最优）](#五按场景推荐传参怎么用最优)
- [六、某类定时为什么没显示（生效条件）](#六某类定时为什么没显示生效条件)
- [七、常见问题 FAQ](#七常见问题-faq)
- [八、依赖与基础库](#八依赖与基础库)
- [九、多语言文案表（附录）](#九多语言文案表附录)

---

## 一、能支持哪些定时

| 定时类型 | 说明 | 生效前提（简版） | 单独入口路由 |
|---|---|---|---|
| **普通定时**（云定时） | 指定时间点开/关，可按周重复或仅一次 | 产品开通「云定时」高级能力 | `/schedule` |
| **循环定时** | 设定时段内反复开/关（如开 10 分关 5 分循环） | 设备有 `cycle_*` DP | `/cycle` |
| **随机定时** | 时段内随机开/关一次，模拟有人在家 | 设备有 `random_*` DP | `/random` |
| **倒计时** | 倒数结束后自动反转开关状态 | 设备有配对的 `countdown_*` DP + 入参开启 | `/countdown` |
| **延时关**（inching / 点动） | 每次开启后运行一段时间自动关 | 设备有 `switch_inching` DP | `/inching` |
| **天文定时**（日出/日落） | 相对日出/日落前·时·后开/关 | 设备本地定时能力 + 产品开通「天文定时」高级能力 | `/astronomical` |

> 所有类型都汇聚在**综合首页** `/home`，用户在一个页面即可查看/新增/管理全部已支持的定时。多数场景**只跳 `/home` 即可**，单独路由用于「只想给用户开放某一类」。

---

## 二、三步接入（最小可用）

**① 在宿主小程序 `global.config.ts` 注册功能页**

```ts
export const tuya = {
  // ...
  functionalPages: {
    ElectricianTimer: {
      appid: 'typtepohxfeukudmyi',
    },
  },
  // ...
};
```

**② 跳综合定时页（推荐入口，一页管全部）**

```ts
ty.navigateTo({
  url: `functional://ElectricianTimer/home?deviceId=${deviceId}`,
});
```

**③ 完成。** 功能页会自动：
- 读取设备 DP 表，自动识别所有开关通道（`switch` / `pd_switch` / `usb_switch`）；
- 自动探测支持哪些定时类型（见 [第六节](#六某类定时为什么没显示生效条件)），只展示可用的；
- 跟随宿主主题色与系统 12/24 小时制。

> 群组定时：把 `deviceId` 换成 `groupId` 即可（`?groupId=${groupId}`）。**群组下天文定时自动关闭**。

---

## 三、跳转路由清单

统一格式：`functional://ElectricianTimer/<路由>?deviceId=${deviceId}`

| 目的 | 路由 |
|---|---|
| 综合定时列表（**推荐主入口**） | `/home` |
| 云定时列表 | `/schedule` |
| 循环定时列表 | `/cycle` |
| 随机定时列表 | `/random` |
| 倒计时列表 | `/countdown` |
| 倒计时设置页（直接进设置） | `/setCountdown` |
| 延时关列表 | `/inching` |
| 延时关设置页（直接进设置） | `/inching/add` |
| 天文定时列表 | `/astronomical` |

**带背景图**（任意路由后追加，需 `encodeURIComponent`）：

```ts
const bg = encodeURIComponent('https://xxx/bg.png');
ty.navigateTo({
  url: `functional://ElectricianTimer/home?deviceId=${deviceId}&bgImgUrl=${bg}`,
});
```

---

## 四、参数速查

拼在跳转 url 的 query 上。**按用途分组**，绝大多数只需传 `deviceId`。

### 4.1 必填（二选一）

| 参数 | 类型 | 说明 |
|---|---|---|
| `deviceId` | string | 设备 ID（单设备场景） |
| `groupId` | string | 群组 ID（群组定时场景，与 deviceId 二选一） |

### 4.2 能力开关（控制展示哪些定时类型）

| 参数 | 值 | 默认 | 说明 |
|---|---|---|---|
| `supportCountdown` | `n` / `y` | `n` | 是否展示倒计时（默认关，需显式开） |
| `supportCycle` | `n` / `y` | 自动 | 不传时按有无 `cycle_*` DP 决定 |
| `supportRandom` | `n` / `y` | 自动 | 不传时按有无 `random_*` DP 决定 |
| `supportInching` | `n` / `y` | 自动 | 不传时按有无 `switch_inching` DP 决定 |
| `supportAstronomical` | `n` / `y` | `n` | **仅当设备本身支持天文定时时才生效** |
| `ignoreAstronomicalEnable` | `n` / `y` | `n` | `y` = 跳过「天文高级能力」云端判断，只看入参 + 设备能力 |

### 4.3 指定 DP（不传则自动识别，一般无需配）

| 参数 | 类型 | 说明 |
|---|---|---|
| `switchCodes` | string | 指定参与定时的开关，多个用英文逗号隔开；不传则自动取全部开关通道 |
| `countdownCodes` | string | 指定倒计时 DP；**配了它必须同时配 `switchCodes`**（两者按下标一一配对） |
| `cycleCode` | string | 自定义循环定时 DP code |
| `randomCode` | string | 自定义随机定时 DP code |
| `inchingCode` | string | 自定义延时关 DP code |
| `dpCodes` | string | 非开关类 DP 设置，多个用英文逗号隔开 |

### 4.4 外观 / 显示

| 参数 | 值 | 默认 | 说明 |
|---|---|---|---|
| `brand` | Hex（6 位，如 `FF4800`） | 跟随宿主 | 主题色；传纯 6 位十六进制，不带 `#` |
| `theme` | `dark` / `light` | 跟随系统 | 配色方案 |
| `is24Hour` | `n` / `y` | 跟随系统 | 时间制式，`y` = 24 小时制 |
| `bgImgUrl` | string | — | 背景图 url，需 `encodeURIComponent` |

### 4.5 行为 / 上限

| 参数 | 值 | 默认 | 说明 |
|---|---|---|---|
| `category` | string | `sdk_schedule` | 云定时分组 code |
| `cycleMax` | 正整数 | 按 DP 类型默认 | 放开/重置循环定时条数上限；非法值（0/负/小数）忽略 |
| `countdownSuccessAction` | `hold` / `back` | `hold` | 倒计时设置完成后：`hold` 留在倒计时页，`back` 返回上一页 |

### 4.6 倒计时设置页（`/setCountdown`）专属

| 参数 | 类型 | 说明 |
|---|---|---|
| `dpCode` | string | 要设置的倒计时 DP；不传则自动获取 |

---

## 五、按场景推荐传参（怎么用最优）

> 原则：**能不传就不传**——功能页会自动识别 DP、自动探测能力。下面只列典型场景需要**额外**加的参数。

| 场景 | 推荐 url query | 说明 |
|---|---|---|
| **最常见：单/多路开关设备，全能力自动** | `?deviceId=xxx` | 只跳 `/home`，其余全自动。首选。 |
| **要开放倒计时** | `?deviceId=xxx&supportCountdown=y` | 倒计时默认关，必须显式开 |
| **只想给用户开放「云定时」一类** | 跳 `/schedule?deviceId=xxx` | 直接进单类列表，不走综合首页 |
| **群组定时** | `?groupId=xxx` | 用 groupId 替代 deviceId；天文自动关 |
| **多路开关但只想让部分通道可定时** | `?deviceId=xxx&switchCodes=switch_1,switch_2` | 限定参与定时的开关 |
| **倒计时 DP 命名非标准** | `?deviceId=xxx&supportCountdown=y&switchCodes=switch_1,switch_2&countdownCodes=cd_1,cd_2` | 开关与倒计时按下标配对，必须成对配 |
| **设备支持天文但云端能力未开通/想强开** | `?deviceId=xxx&supportAstronomical=y&ignoreAstronomicalEnable=y` | 跳过云端高级能力校验 |
| **循环定时想放开条数上限** | `?deviceId=xxx&cycleMax=50` | 覆盖 SDK 默认上限 |
| **统一品牌视觉** | `?deviceId=xxx&brand=FF4800&theme=dark` | 固定主题色 + 深色 |
| **倒计时设完直接回宿主** | `?deviceId=xxx&supportCountdown=y&countdownSuccessAction=back` | 默认 hold 留页 |

---

## 六、某类定时为什么没显示（生效条件）

功能页对每类定时做「**入参允许 且 设备/云端满足条件**」的双重判断，任一不满足就隐藏该类型。排查表：

| 类型 | 显示条件 |
|---|---|
| 普通定时（云定时） | 产品在云端开通「云定时」能力（`panelConfig.bic` 含 `timer` 且选中）。**入参无法强开**，需产品配置。 |
| 倒计时 | `supportCountdown=y`（默认 n） **且** 存在配对的倒计时 DP |
| 循环定时 | `supportCycle≠n` **且** 存在 `cycle_*` DP（或指定 `cycleCode` 有效） |
| 随机定时 | `supportRandom≠n` **且** 存在 `random_*` DP（或指定 `randomCode` 有效） |
| 延时关 | `supportInching≠n` **且** 存在 `switch_inching` DP（或指定 `inchingCode` 有效） |
| 天文定时 | `supportAstronomical=y` **且** 设备能力位支持 **且** 产品开通「天文定时」高级能力（`ignoreAstronomicalEnable=y` 可跳过最后一项）。**群组下强制关闭。** |

> 首页只展示「已有数据」或「当前可添加」的类型；若某类无数据且不可添加，则不出现在列表。

---

## 七、常见问题 FAQ

- **倒计时没出来？** 倒计时默认关闭，必须传 `supportCountdown=y`，且设备要有配对的 `countdown_*` DP。
- **天文定时没出来？** 需三个条件同时满足（见第六节）；群组场景天文永久不可用。
- **多路开关顺序乱？** 功能页统一按 `普通开关 < PD 开关 < USB 开关`、同类按通道号升序排列，`switchCodes` 传入顺序会被内部兜底重排。
- **定时不准？** 定时可能存在约 30 秒误差（属正常）。
- **离线/局域网加不了定时？** 设备离线不可添加；局域网状态不可加云定时；本地连接状态不可加天文定时——功能页会给出对应提示。
- **`brand` 怎么传？** 传 6 位十六进制值本身，**不带 `#`**，如 `FF4800`。

---

## 八、依赖与基础库

基础库版本：最低可用 `2.12.18`

Kit：

- BaseKit 2.1.2
- BizKit 3.3.1
- DeviceKit 3.9.3
- MiniKit 3.2.1

核心依赖：`@ray-js/electrician-timing-sdk`（驱动云定时/循环/随机/延时关），天文定时由本仓自行实现。

**产品端前置开通**：

- 云定时 → 开通产品「云定时」高级能力；
- 天文定时 → 设备须具备本地定时能力，且产品开通「天文定时」高级能力；
- 倒计时 / 循环 / 随机 → 需设备具备对应 DP 功能。

---

## 九、多语言文案表（附录）

> 本节为文案参考，接入方通常无需关心；如需覆盖/校对可查阅。

### 1. 通用操作按钮与选择

| Key | 中文 (zh) | English (en) |
|-----|-----------|---------------|
| cancel | 取消 | Cancel |
| confirm | 确定 | Confirm |
| delete | 删除 | Delete |
| save | 保存 | Save |
| ret_add | 添加 | Add |
| ret_please_select | 请选择 | Please Select |
| please_select_switch | 请至少选择一个开关 | Please select at least one switch |
| ret_please_select_switch | 请至少选择一个开关 | Please select at least one switch |
| ret_understand | 知道了 | Get it |

### 2. 定时类型标签与页面标题

| Key | 中文 (zh) | English (en) |
|-----|-----------|---------------|
| ret_title | 定时 | Schedule |
| ret_schedule | 定时 | Schedule |
| ret_schedule_title | 定时 | Timing |
| ret_tag_normal | 定时 | Timing |
| ret_tag_astronomical | 天文定时 | Astronomical Timing |
| ret_astronomical_title | 天文定时 | Astronomical Timing |
| ret_tag_sunrise | 日出定时 | Sunrise Time |
| ret_sunrise | 日出定时 | Sunrise Time |
| ret_tag_sunset | 日落定时 | Sunset Time |
| ret_sunset | 日落定时 | Sunset Time |
| ret_tag_cycle | 循环定时 | Cycle Time |
| ret_cycle_title | 循环定时 | Cycle Time |
| ret_cycle_holdtime | 循环定时 | Cycle Time |
| ret_tag_random | 随机定时 | Random Time |
| ret_random_title | 随机定时 | Random Time |
| ret_tag_inching | 延时关 | Delay off |
| ret_inching_title | 延时关 | Delay off |
| ret_inching_switch | 延时关 | Delay off |
| ret_inching_setting | 延时关 | Delay off |
| ret_tag_countdown | 倒计时 | Countdown |
| ret_countdown | 倒计时 | Countdown |
| ret_countdown_title | 倒计时 | Countdown |

### 3. 添加/编辑与执行相关

| Key | 中文 (zh) | English (en) |
|-----|-----------|---------------|
| ret_add_schedule | 添加定时 | Add Timing |
| ret_add_timer | 添加定时 | Add Timing |
| ret_edit_timer | 编辑定时 | Edit Timing |
| ret_select_timer | 选择定时类型 | Select the timing type |
| ret_action | 执行动作 | Execution Action |
| ret_switch_selection | 执行开关 | Execution switch |
| ret_countdown_selection | 选择倒计时 | Select countdown |
| ret_countdown_reset | 重新设定 | Reset |
| ret_countdown_close | 关闭倒计时 | Close Countdown |

### 4. 星期与重复周期

| Key | 中文 (zh) | English (en) |
|-----|-----------|---------------|
| ret_sun | 周日 | Sun |
| ret_mon | 周一 | Mon |
| ret_tues | 周二 | Tue |
| ret_wed | 周三 | Wed |
| ret_thur | 周四 | Thu |
| ret_fri | 周五 | Fri |
| ret_sat | 周六 | Sat |
| ret_weekend | 周末 | Weekend |
| ret_workday | 工作日 | Working Days |
| ret_everyday | 每天 | Every Day |
| ret_once_time | 仅一次 | Only once |

### 5. 时间单位与时段标签

| Key | 中文 (zh) | English (en) |
|-----|-----------|---------------|
| ret_am | 上午 | Am |
| ret_pm | 下午 | Pm |
| ret_hour | 小时 | Hour |
| ret_minute | 分钟 | Minute |
| ret_second | 秒 | Second |
| ret_on | 开 | On |
| ret_off | 关 | Off |
| ret_starttime_label | 开始时间 | Start time |
| ret_endtime_label | 结束时间 | End time |
| ret_cycle_onholdtime_label | 开启时长 | Opening time |
| ret_cycle_offholdtime_label | 关闭时长 | Closing time |

### 6. 日出/日落时刻选项

| Key | 中文 (zh) | English (en) |
|-----|-----------|---------------|
| ret_sunrise_before | 日出前 | Before Sunrise |
| ret_sunrise_at | 日出时 | At Sunrise |
| ret_sunrise_after | 日出后 | After Sunrise |
| ret_sunset_before | 日落前 | Before Sunset |
| ret_sunset_at | 日落时 | At Sunset |
| ret_sunset_after | 日落后 | After Sunset |

### 7. 功能描述（各定时类型说明）

| Key | 中文 (zh) | English (en) |
|-----|-----------|---------------|
| ret_schedule_desc | 设备在指定时间点可进行开/关 | The device can be turned on/off at a specified time |
| ret_cycle_time_desc | 设定的时段内设备可重复进行开/关 | The device can be turned on/off repeatedly within the set time period |
| ret_cycle_holdtime_desc | 在定时范围内可设置开关开启/关闭最小时长，可循环执行多次开/关 | The minimum duration of switch on/off can be set within the timing range, and multiple on/off cycles can be performed |
| ret_random_time_desc | 设定的时段内设备可随机开/关一次，制造有人在家的假象 | The device can be turned on/off randomly within a set period of time to create the illusion that someone is at home |
| ret_countdown_desc | 设备在倒计时结束时进行开/关 | The device turns on/off at the end of the countdown |
| ret_countdown_tips | 开关将在倒计时结束后自动反转 | The switch will automatically reverse after the countdown ends |
| ret_inching_desc | 开启后将使设备处于自动状态；即每次打开设备后，运行一段时间后自动关闭 | After turning on, the device will be in automatic state; that is, each time the device is turned on, it will automatically turn off after running for a period of time. |
| ret_switch_inching_desc | 开启后，每次打开设备后将运行一段时间后自动关闭 | After turning it on, the device will automatically shut down after running for a while each time it is turned on. |
| ret_sunrise_desc | 设备在日出前、日出时、日出后开/关 | Device turns on/off before, during, or after sunrise |
| ret_sunset_desc | 设备在日落前、日落时、日落后开/关 | Device turns on/off before, during, or after sunset |

### 8. 带占位符的格式文案

| Key | 中文 (zh) | English (en) |
|-----|-----------|---------------|
| ret_cycle_holdtime_value | {0}小时{1}分钟 | {0} hours {1} minutes |
| ret_cycle_onholdtime | 开启{0}小时{1}分钟 | Open {0} hours {1} minutes |
| ret_cycle_offholdtime | 关闭{0}小时{1}分钟 | Close {0} hours {1} minutes |
| ret_countdown_time | {0}小时{1}分钟 | {0} hours {1} minutes |
| ret_countdown_minute_action | {0}分钟后{1} | {0} minutes later{1} |
| ret_countdown_hour_action | {0}小时{1}分钟后{2} | {0} hours {1} minutes later {2} |
| ret_inching_label_second | {0}秒关 | {0} seconds off |
| ret_inching_label_minute | {0}分钟关 | {0} minutes off |
| ret_inching_label_minute_second | {0}分钟{1}秒关 | {0} minutes {1} seconds off |

### 9. 错误与操作失败提示

| Key | 中文 (zh) | English (en) |
|-----|-----------|---------------|
| ret_save_failure | 保存数据失败，请稍后重试 | Failed to save data, please try again later |
| ret_forbbiden_failure | 禁用失败，请稍后重试 | Disabling failed, please try again later |
| ret_delete_failure | 删除失败，请稍后重试 | Deletion failed, please try again later |
| ret_open_failure | 启用失败，请稍后重试 | Activation failed, please try again later |
| ret_replace_error | 替换定时失败 | Replacement the timing failed |
| ret_schedule_replace_error | 替换云定时失败 | Replacement normal timing failed |
| ret_inching_replace_error | 替换延时关失败 | Replacement delayed shutdown failed |
| ret_cycle_replace_error | 替换循环定时失败 | Replacement cycle time failed |
| ret_random_replace_error | 替换随机定时失败 | Replacement random timing failed |
| ret_countdown_close_error | 关闭倒计时失败 | Close countdown failed |
| ret_holdTime_error | 循环单元时长不能大于定时总时长 | The duration of the loop unit cannot be greater than the total timing duration |
| ret_start_equal_end | 开始时间和结束时间不能相等 | The start time and end time cannot be equal |
| ret_start_than_end | 结束时间必须大于开始时间 30 分钟以上 | The end time must be at least 30 minutes later than the start time |

### 10. 添加限制与不支持提示

| Key | 中文 (zh) | English (en) |
|-----|-----------|---------------|
| ret_schedule_max | 您的定时添加已达到上限 | Your scheduled addition limit has been reached |
| ret_schedule_offline_tip | 当前设备处于离线状态下，无法添加定时 | The current device is offline and cannot add a schedule |
| ret_schedule_lan_tip | 当前设备处于局域网下，无法添加定时 | The current device is in the local area network and cannot add a schedule |
| ret_schedule_local_tip | 当前设备处于本地连接状态下，无法添加定时 | The current device is in local connection state, and the schedule cannot be added |
| ret_cycle_max | 您的循环定时添加已达到上限 | Your cycle time addition has reached the limit |
| ret_cycle_max_tips | 最大只能支持{0}个开关的定时设置 | The maximum number of switch timing settings supported is {0} |
| ret_random_max | 您的随机定时添加已达到上限 | Your random timing addition has reached the limit |
| ret_random_max_tips | 最大只能支持{0}个开关的定时设置 | The maximum number of switch timing settings supported is {0} |
| ret_astronomical_max | 您的天文定时添加已达到上限 | Your astronomical timing addition limit has been reached |
| ret_astronomical_cloud_max | 您的定时已达到上限{0} | Your timing has reached the upper limit {0} |
| ret_inching_max | 您的延时关已达到上限{0} | Your delay timer has reached the upper limit {0} |
| ret_inching_max_tips | 最大只能支持{0}个开关的延时关 | The maximum number of delayed shutdown settings supported is {0} |
| ret_no_timer_enabled | 当前无定时类型可选择 | Currently no timer type can be selected |
| ret_not_support_inching | 当前配置或设备不支持延时关 | The current configuration or device does not support delayed shutdown |
| ret_not_support_countdown | 当前配置或设备不支持倒计时 | The current configuration or device does not support countdown |
| ret_countdown_not_support | 当前设备不支持此倒计时 | The current device does not support this countdown |

### 11. 确认弹窗与冲突提示

| Key | 中文 (zh) | English (en) |
|-----|-----------|---------------|
| ret_tips | 提示 | Tips |
| ret_close_schedule_tip | 关闭页面将取消您所做的所有更改 | Closing the page will cancel all changes you have made |
| ret_delete_timer_tips | 删除后将无法恢复，确认删除此定时？ | It cannot be restored after deletion. Are you sure you want to delete this timer? |
| ret_delete_countdown_tips | 删除后将无法恢复，确认删除此定时？ | It cannot be restored after deletion. Are you sure you want to delete this timer? |
| ret_countdown_close_tips | 是否确认删除该倒计时？ | Are you sure you want to delete this countdown? |
| ret_conflict_title | 定时存在重复 | There is a repetition of timing |
| ret_conflict_subtitle | 确认替换已有定时？ | Confirm that replacement is scheduled? |
| ret_sunrise_repeat_tips | 日出定时已存在，不能重复添加 | Sunrise timer already exists and cannot be added again |
| ret_sunset_repeat_tips | 日落定时已存在，不能重复添加 | Sunset timer already exists and cannot be added again |
| ret_inching_repeat | {0}已设置延时，确认替换已有延时？ | {0} has set a delay, are you sure you want to replace the existing delay? |

### 12. 空状态与说明

| Key | 中文 (zh) | English (en) |
|-----|-----------|---------------|
| ret_no_data | 暂无定时 | No Data |
| ret_timer_tips | 定时可能会存在30秒左右误差 | The timing may have an error of about 30 seconds |