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

# Electrician Timing Function Page

Used for the timing function page of electrical products, supporting normal timing, sunrise timing, sunset timing, cycle timing, random timing, inching switch, countdown and other functions.

## 快速查找

> 电工定时功能页,UIID `typtepohxfeukudmyi`。六类定时:云定时/循环/随机/倒计时/延时关由 `@ray-js/electrician-timing-sdk` 驱动;**天文定时(日出/日落)完全在本仓实现**(Redux `astronomicalSlice`)。源码主目录前缀 `functional/`。

### 页面 / 路由(六类定时)

| 类型 | 路由 | 列表页 | 编辑页 | 摘要 |
|---|---|---|---|---|
| 云定时 schedule | `/schedule` | `functional/pages/schedule/list/List.tsx` | `schedule/add/index.tsx` | 普通定时,SDK `useCloudTimers`,周重复/一次性 |
| 循环 cycle | `/cycle` | `functional/pages/cycle/list/List.tsx` | `cycle/add/index.tsx` | 时段内反复开关,SDK `useEleCycle` |
| 随机 random | `/random` | `functional/pages/random/list/List.tsx` | `random/add/index.tsx` | 时段内随机执行,SDK `useEleRandom`(模拟在家) |
| 倒计时 countdown | `/countdown` | `functional/pages/countdown/list/List.tsx` | `countdown/countdown/index.tsx` | 倒数后开/关,配对开关 DP |
| 延时关 inching | `/inching` | `functional/pages/inching/list/List.tsx` | `inching/add/index.tsx` | 开后定时自关,SDK `useEleInching`,通道级 |
| 天文 astronomical | `/astronomical` | `functional/pages/astronomical/list/List.tsx` | `astronomical/add/index.tsx` | 日出/日落相对时刻,**本仓实现**,需设备本地定时能力 |
| 综合首页 | — | `functional/pages/home/index.tsx` | — | 选项卡入口,`getSupportList()` 动态渲染支持类型 |

### 关键代码路径

| 层 | 文件 | 说明 |
|---|---|---|
| 网关请求 | `functional/api/atop.ts` | `api<T>(apiName, postData, version)` 包 `apiRequestByAtop`;`getAbility(devId, code)` 查能力 |
| SDK 接入(cycle/random/inching) | hooks `useEleCycle`/`useEleRandom`/`useEleInching` + `electri.cycle/random/inching.add/update/remove/updateStatus()` | 来自 `@ray-js/electrician-timing-sdk` |
| SDK 接入(云定时) | `useCloudTimers()` + `addCloudTimer/updateCloudTimer/removeCloudTimer/updateCloudTimerStatus()` | SDK 提供 |
| 冲突弹窗 | `functional/components/conflict/index.tsx` | 包 SDK `ConflictPopup`,传本地化文本 + DP 名映射 |
| 天文定时状态 | `functional/redux/modules/astronomicalSlice.ts` | `fetchAstronomicalList`/`create`/`edit`/`enabled`/`disabled`/`deleteAstronomical`,走 Ray `getAstronomicalList` 等 API |
| 常量/枚举 | `functional/constant.ts` | `enum FuncType { normal, cycle, countdown, random, inching, sunrise, sunset }` |
| 接口类型 | `functional/interface.ts` | `NormalTimerData`/`CycleData`/`RandomData`/`CountdownData`/`InchingData`/`AstronomicalData`/`ConflictItem` |
| 配置 | `functional/config.ts` | `config.switchCodes/countdownCodes/cycleCode/randomCode/inchingCode/category`;`fetchChannelDps()` 按 `/^switch(_led)?(_\d+)?$/` 匹配通道 |
| Redux | `functional/redux/modules/` | `systemInfoSlice`(设备/DP)、`commonSlice`(`dpNames`)、`themeSlice`、`astronomicalSlice` |
| 通用组件 | `functional/components/` | `timer-picker`(时间)、`week`(周重复)、`topBar`(导航) |

### 排查速查

| 现象 | 先看 |
|---|---|
| 某类定时不显示 | `functional/pages/home/index.tsx` `getSupportList()` + `config.isSupportXxx` |
| 循环/随机/延时关异常 | SDK `electri.*` 命名空间;设备 DP 驱动,非本仓存储 |
| 天文定时不生效 | 本仓 `astronomicalSlice` + 设备本地定时能力(`getAbility`);云端拒绝见排查中枢 cases.md「日出日落天文定时」 |
| 倒计时显示异常 | 与开关 DP 一一对应(`countdownCodes` 下标对应 `switchCodes`),仅 UI 展示无单独存储 |
| 冲突弹窗文案/DP 名 | `functional/components/conflict/index.tsx` 传入的本地化配置 + `commonSlice.dpNames` |

## Usage

### Installation Function Page

Add the following code to the `global.config.ts` file of the project

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

### Jump to function page

#### Jump to the timed comprehensive list page

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

#### Jump to the cloud schedule list page

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

#### Jump to loop timing list page

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

#### Jump to random time list page

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

#### Jump to countdown list page

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

#### Jump to countdown timer setting page

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

#### Jump to the inching timing list page

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

#### Jump to the inching timing setting page

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

#### Jump to the astronomical timing list page

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

#### Background Image Settings

```ts
const jumpUrl = `functional://ElectricianTimer/schedule?deviceId=${deviceId}&bgImgUrl=encodeURIComponent(ImageURLAddress)`;
ty.navigateTo({
  url: jumpUrl,
});
```


### General parameters

| Name                   | Type     | Value range | Required | Description                                                                                                                                                               |
| ---------------------- | -------- | ----------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| deviceId               | string   | -           | Yes      | Device ID                                                                                                                                                                 |
| switchCodes            | string | -           | No       | Supported switches, automatically acquired if not configured. Please separate multiple switches with “,”                                                                                                              |
| countdownCodes         | string | -           | No       | Supported countdown. Note that since the switch and countdown appear in pairs, to configure this property, you need to configure the supported switch at the same time. Please separate multiple numbers with “,”   |
| supportCountdown       | string   | n,y         | No       | Whether the countdown is supported, the default is not supported                                                                                                          |
| supportCycle           | string   | n,y         | No       | Whether to support loop timing. If not passed, it will be determined whether to support it based on whether there is DP function.                                         |
| supportRandom          | string   | n,y         | No       | Whether to support random timing. If not passed, it will be determined based on whether the DP function is available.                                                     |
| supportInching         | string   | n,y         | No       | Whether to support inching timing, if not transmitted, it will be determined whether to support it based on whether there is DP function                                  |
| supportAstronomical    | string   | n,y         | No       | Whether to support astronomical timing. This parameter setting is valid only when the device supports astronomical timing.                                                |
| cycleCode              | string   | -           | No       | Custom loop timing dp code                                                                                                                                                |
| randomCode             | string   | -           | No       | Custom random timing dp code                                                                                                                                              |
| inchingCode            | string   | -           | No       | Customize the inching timing dp code                                                                                                                                      |
| is24Hour               | string   | n,y         | No       | Whether it is a 24-hour system, `y` means yes, `n` means no                                                                                                               |
| category               | string   | -           | No       | The group code of cloud scheduling, the default is `sdk_schedule`                                                                                                         |
| brand                  | string   | -           | No       | Theme color, by default follows the host miniApp theme color. In Hex format, please enter a 6-digit valid value, such as: FFFFFF                                                                                                           |
| countdownSuccessAction | string   | hold,back   | No       | Set the action when the countdown is completed. `hold` means staying on the countdown page, and `back` means returning to the previous page. The default value is `hold`. |
| bgImgUrl | string   | -  | 否   | Background image of the timing page by encodeURIComponent      |

### Countdown setting page parameters

| Name   | Type   | Value range | Required | Description                                                                                           |
| ------ | ------ | ----------- | -------- | ----------------------------------------------------------------------------------------------------- |
| dpCode | string | -           | No       | The countdown dp that needs to be set. If not passed, the countdown dp will be automatically obtained |


## Dependency on MiniApp library

Basic library version: Minimum available version `2.12.18`
Kit:
- BaseKit 2.1.2
- BizKit: 3.3.1
- Devicekit: 3.9.3
- MiniKit 3.2.1

## Multilingual description

### 1. General Action Buttons and Selection

| 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. Timer Type Tags and Page Titles

| 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. Add/Edit and Execution

| 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. Weekdays and Repeat Cycle

| 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. Time Units and Period Labels

| 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. Sunrise/Sunset Time Options

| 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. Feature Descriptions (Timer Type Explanations)

| 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. Format Strings with Placeholders

| 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. Errors and Operation Failure Messages

| 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. Addition Limits and Unsupported Tips

| 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. Confirm Dialogs and Conflict Tips

| 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. Empty State and Notices

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

## Precautions

- Astronomical timing requires the device to have local timing capabilities, and the product needs to enable the advanced astronomical timing capabilities;
- Cloud timing needs to be supported, so please enable the advanced cloud timing capabilities of the product;
- Countdown, loop timing, and random timing require the product to have the relevant dp function as a prerequisite, and the support and shutdown settings are effective.