@ledvance/ui-biz-bundle 1.1.66 → 1.1.68
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/navigation/Routers.ts +2 -0
- package/src/newModules/biorhythm/BiorhythmPage.tsx +11 -7
- package/src/newModules/fixedTime/FixedTimePage.tsx +4 -3
- package/src/newModules/randomTime/RandomTimePage.tsx +4 -3
- package/src/newModules/remoteControl/RemoteControlActions.ts +6 -0
- package/src/newModules/remoteControl/RemoteControlPage.tsx +51 -0
- package/src/newModules/remoteControl/Router.ts +16 -0
- package/src/newModules/sleepWakeUp/Interface.ts +70 -0
- package/src/newModules/sleepWakeUp/Router.ts +25 -0
- package/src/newModules/sleepWakeUp/SleepWakeUpActions.ts +317 -0
- package/src/newModules/sleepWakeUp/SleepWakeUpDetailPage.tsx +661 -0
- package/src/newModules/sleepWakeUp/SleepWakeUpPage.tsx +456 -0
- package/src/newModules/sleepWakeUp/utils.ts +254 -0
package/package.json
CHANGED
|
@@ -17,6 +17,8 @@ export const ui_biz_routerKey = {
|
|
|
17
17
|
'bi_biz_biological_icon_select': 'bi_biz_biological_icon_select',
|
|
18
18
|
'ui_biz_sleep_wakeUp': 'ui_biz_sleep_wakeUp',
|
|
19
19
|
'ui_biz_sleep_wakeUp_edit': 'ui_biz_sleep_wakeUp_edit',
|
|
20
|
+
'ui_biz_sleep_wakeUp_new': 'ui_biz_sleep_wakeUp_new',
|
|
21
|
+
'ui_biz_sleep_wakeUp_edit_new': 'ui_biz_sleep_wakeUp_edit_new',
|
|
20
22
|
'ui_biz_music': 'ui_biz_music',
|
|
21
23
|
'ui_biz_select_page': 'ui_biz_select_page',
|
|
22
24
|
'ui_biz_fixed_time': 'ui_biz_fixed_time',
|
|
@@ -46,18 +46,22 @@ interface UIState extends BiorhythmBean {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
export interface BiorhythmPageParams {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
biorhythmDpCode: string
|
|
50
|
+
conflictDps: {
|
|
51
|
+
randomTimeDpCode?: string
|
|
52
|
+
fixedTimeDpCode?: string
|
|
53
|
+
sleepDpCode?: string
|
|
54
|
+
wakeUpDpCode?: string
|
|
55
|
+
}
|
|
52
56
|
isSupportTemperature: boolean
|
|
53
57
|
isSupportBrightness: boolean
|
|
54
|
-
|
|
58
|
+
isMixLight?: boolean
|
|
55
59
|
}
|
|
56
60
|
|
|
57
61
|
const BiorhythmPage = () => {
|
|
58
62
|
const params = useParams<BiorhythmPageParams>()
|
|
59
63
|
const navigation = useNavigation()
|
|
60
|
-
const [biorhythm, setBiorhythm] = useBiorhythm(params.
|
|
64
|
+
const [biorhythm, setBiorhythm] = useBiorhythm(params.biorhythmDpCode)
|
|
61
65
|
const deviceId = useDeviceId()
|
|
62
66
|
const deviceInfo = useDeviceInfo()
|
|
63
67
|
const { productId } = deviceInfo
|
|
@@ -437,7 +441,7 @@ const BiorhythmPage = () => {
|
|
|
437
441
|
iconIdList: state.planList?.map(item => {
|
|
438
442
|
return item.iconId
|
|
439
443
|
}),
|
|
440
|
-
isMixRGBWLamp: params.
|
|
444
|
+
isMixRGBWLamp: !!params.isMixLight,
|
|
441
445
|
isSupportTemperature: params.isSupportTemperature,
|
|
442
446
|
isSupportBrightness: params.isSupportBrightness,
|
|
443
447
|
showDeleteBtn
|
|
@@ -478,7 +482,7 @@ const BiorhythmPage = () => {
|
|
|
478
482
|
iconIdList: state.planList?.map(item => {
|
|
479
483
|
return item.iconId
|
|
480
484
|
}),
|
|
481
|
-
isMixRGBWLamp: params.
|
|
485
|
+
isMixRGBWLamp: !!params.isMixLight,
|
|
482
486
|
isSupportTemperature: params.isSupportTemperature,
|
|
483
487
|
isSupportBrightness: params.isSupportBrightness,
|
|
484
488
|
showDeleteBtn
|
|
@@ -26,9 +26,10 @@ const MAX_NUM = 10
|
|
|
26
26
|
export interface FixedTimePageParams {
|
|
27
27
|
fixedTimeDpCode: string
|
|
28
28
|
conflictDps: {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
randomTimeDpCode?: string
|
|
30
|
+
biorhythmDpCode?: string
|
|
31
|
+
sleepDpCode?: string
|
|
32
|
+
wakeUpDpCode?: string
|
|
32
33
|
}
|
|
33
34
|
isPlug?: boolean
|
|
34
35
|
showTags?: boolean
|
|
@@ -27,9 +27,10 @@ const MAX_NUM = 10
|
|
|
27
27
|
export interface RandomTimePageParams {
|
|
28
28
|
randomTimeDpCode: string
|
|
29
29
|
conflictDps: {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
fixedTimeDpCode?: string
|
|
31
|
+
biorhythmDpCode?: string
|
|
32
|
+
sleepDpCode?: string
|
|
33
|
+
wakeUpDpCode?: string
|
|
33
34
|
}
|
|
34
35
|
isPlug?: boolean
|
|
35
36
|
showTags?: boolean
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import I18n from '@ledvance/base/src/i18n';
|
|
3
|
+
import { useReactive } from 'ahooks';
|
|
4
|
+
import { useDeviceInfo } from '@ledvance/base/src/models/modules/NativePropsSlice';
|
|
5
|
+
import Page from '@ledvance/base/src/components/Page';
|
|
6
|
+
import LdvSwitch from '@ledvance/base/src/components/ldvSwitch';
|
|
7
|
+
import { useRemoteControl } from './RemoteControlActions';
|
|
8
|
+
import { useParams } from '@ledvance/base/src/hooks/Hooks';
|
|
9
|
+
import Card from '@ledvance/base/src/components/Card';
|
|
10
|
+
import Spacer from '@ledvance/base/src/components/Spacer';
|
|
11
|
+
import { Utils } from 'tuya-panel-kit'
|
|
12
|
+
|
|
13
|
+
const { convertX: cx } = Utils.RatioUtils
|
|
14
|
+
|
|
15
|
+
export interface RemoteControlPageParams {
|
|
16
|
+
remoteControlDpCode: string;
|
|
17
|
+
}
|
|
18
|
+
const RemoteControlPage = () => {
|
|
19
|
+
const deviceInfo = useDeviceInfo();
|
|
20
|
+
const params = useParams<RemoteControlPageParams>();
|
|
21
|
+
const [remoteControl, setRemoteControl] = useRemoteControl(params.remoteControlDpCode);
|
|
22
|
+
|
|
23
|
+
const state = useReactive({
|
|
24
|
+
loading: false,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<Page
|
|
29
|
+
backText={deviceInfo.name}
|
|
30
|
+
loading={state.loading}
|
|
31
|
+
headlineText={I18n.getLang('light_sources_specific_settings_remote_control')}
|
|
32
|
+
>
|
|
33
|
+
<Spacer />
|
|
34
|
+
<Card style={{marginHorizontal: cx(24)}}>
|
|
35
|
+
<LdvSwitch
|
|
36
|
+
title={I18n.getLang('light_sources_specific_settings_remote_control')}
|
|
37
|
+
color="#fff"
|
|
38
|
+
colorAlpha={1}
|
|
39
|
+
enable={remoteControl}
|
|
40
|
+
setEnable={async v => {
|
|
41
|
+
state.loading = true;
|
|
42
|
+
await setRemoteControl(v);
|
|
43
|
+
state.loading = false;
|
|
44
|
+
}}
|
|
45
|
+
/>
|
|
46
|
+
</Card>
|
|
47
|
+
</Page>
|
|
48
|
+
);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export default RemoteControlPage;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {NavigationRoute} from "tuya-panel-kit";
|
|
2
|
+
import RemoteControlPage from "./RemoteControlPage";
|
|
3
|
+
import {ui_biz_routerKey} from "../../navigation/Routers";
|
|
4
|
+
|
|
5
|
+
const RemoteControlPageRouters: NavigationRoute[] = [
|
|
6
|
+
{
|
|
7
|
+
name: ui_biz_routerKey.ui_biz_remote_control,
|
|
8
|
+
component: RemoteControlPage,
|
|
9
|
+
options: {
|
|
10
|
+
hideTopbar: true,
|
|
11
|
+
showOfflineView: false,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
export default RemoteControlPageRouters
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export interface WakeUpItem {
|
|
2
|
+
enable: boolean;
|
|
3
|
+
weeks: number[];
|
|
4
|
+
delay: number;
|
|
5
|
+
hour: number;
|
|
6
|
+
minute: number;
|
|
7
|
+
h: number;
|
|
8
|
+
s: number;
|
|
9
|
+
v: number;
|
|
10
|
+
brightness: number;
|
|
11
|
+
temperature: number;
|
|
12
|
+
last: number;
|
|
13
|
+
nodeHex: string;
|
|
14
|
+
isSleep: boolean;
|
|
15
|
+
startTime: number;
|
|
16
|
+
endTime: number;
|
|
17
|
+
isColorMode: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface WakeUpUIItem extends WakeUpItem {
|
|
21
|
+
name: string
|
|
22
|
+
id: number
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface WakeUpData {
|
|
26
|
+
version: number;
|
|
27
|
+
num: number;
|
|
28
|
+
nodes: WakeUpItem[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface WakeUpUIData {
|
|
32
|
+
version: number;
|
|
33
|
+
num: number;
|
|
34
|
+
nodes: WakeUpUIItem[];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface SleepItem {
|
|
38
|
+
enable: boolean;
|
|
39
|
+
weeks: number[];
|
|
40
|
+
delay: number;
|
|
41
|
+
hour: number;
|
|
42
|
+
minute: number;
|
|
43
|
+
h: number;
|
|
44
|
+
s: number;
|
|
45
|
+
v: number;
|
|
46
|
+
brightness: number;
|
|
47
|
+
temperature: number;
|
|
48
|
+
nodeHex: string;
|
|
49
|
+
isSleep: boolean;
|
|
50
|
+
startTime: number;
|
|
51
|
+
endTime: number;
|
|
52
|
+
isColorMode: boolean;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface SleepUIItem extends SleepItem {
|
|
56
|
+
name: string
|
|
57
|
+
id: number
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface SleepData {
|
|
61
|
+
version: number;
|
|
62
|
+
num: number;
|
|
63
|
+
nodes: SleepItem[]
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface SleepUIData {
|
|
67
|
+
version: number;
|
|
68
|
+
num: number;
|
|
69
|
+
nodes: SleepUIItem[]
|
|
70
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {NavigationRoute} from "tuya-panel-kit";
|
|
2
|
+
import NewSleepWakeUpPage from './SleepWakeUpPage'
|
|
3
|
+
import NewSleepWakeUpDetailPage from './SleepWakeUpDetailPage'
|
|
4
|
+
import {ui_biz_routerKey} from "../../navigation/Routers";
|
|
5
|
+
|
|
6
|
+
const NewSleepWakeUpPageRouters: NavigationRoute[] = [
|
|
7
|
+
{
|
|
8
|
+
name: ui_biz_routerKey.ui_biz_sleep_wakeUp_new,
|
|
9
|
+
component: NewSleepWakeUpPage,
|
|
10
|
+
options: {
|
|
11
|
+
hideTopbar: true,
|
|
12
|
+
showOfflineView: false,
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: ui_biz_routerKey.ui_biz_sleep_wakeUp_edit_new,
|
|
17
|
+
component: NewSleepWakeUpDetailPage,
|
|
18
|
+
options: {
|
|
19
|
+
hideTopbar: true,
|
|
20
|
+
showOfflineView: false,
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
export default NewSleepWakeUpPageRouters
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react'
|
|
2
|
+
import { useDp, useDeviceId } from '@ledvance/base/src/models/modules/NativePropsSlice'
|
|
3
|
+
import { getFeature, putFeature } from '@ledvance/base/src/api/native'
|
|
4
|
+
import { hex2Int, spliceByStep } from '@ledvance/base/src/utils/common'
|
|
5
|
+
import { SleepData, SleepItem, SleepUIData, SleepUIItem, WakeUpData, WakeUpItem, WakeUpUIData, WakeUpUIItem } from './Interface'
|
|
6
|
+
import { cloneDeep, padStart } from 'lodash'
|
|
7
|
+
import { parseJSON, to16 } from '@tuya/tuya-panel-lamp-sdk/lib/utils'
|
|
8
|
+
import { Result } from '@ledvance/base/src/models/modules/Result'
|
|
9
|
+
import I18n from '@ledvance/base/src/i18n'
|
|
10
|
+
const sleepPlanFeatureId = 'SleepPlan'
|
|
11
|
+
const wakeUpPlanFeatureId = 'WakeUpPlan'
|
|
12
|
+
|
|
13
|
+
// 接口失败重试
|
|
14
|
+
let retryNumber = 0
|
|
15
|
+
const putFeatureFn = async (devId, featureId, data) => {
|
|
16
|
+
let status;
|
|
17
|
+
await putFeature(devId, featureId, data).then(res => {
|
|
18
|
+
if (!res?.result && retryNumber < 3) {
|
|
19
|
+
retryNumber += 1
|
|
20
|
+
putFeatureFn(devId, featureId, data).then()
|
|
21
|
+
}
|
|
22
|
+
if (res?.result) {
|
|
23
|
+
retryNumber = 0
|
|
24
|
+
status = res?.result
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
return status
|
|
28
|
+
}
|
|
29
|
+
let wakeUpTimerId: number | undefined = undefined
|
|
30
|
+
type WakeUpType = (wakeUpDp: string, disableFeature?: boolean) => [WakeUpUIItem[], (wakeUpData: WakeUpUIData) => Promise<Result<any>>, boolean]
|
|
31
|
+
// @ts-ignore
|
|
32
|
+
export const useWakeUp: WakeUpType = (wakeUpDp, disableFeature) => {
|
|
33
|
+
const devId = useDeviceId()
|
|
34
|
+
const [wakeUp, setWakeUp]: [string, (wakeUp: string) => Promise<Result<any>>] = useDp(wakeUpDp)
|
|
35
|
+
const [wakeUpList, setWakeUpList] = useState(wakeUpDp2Obj(wakeUp)?.nodes || [])
|
|
36
|
+
const [isComplete, setIsComplete] = useState(false)
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if(disableFeature) {
|
|
39
|
+
setIsComplete(true)
|
|
40
|
+
setWakeUpList(wakeUpDp2Obj(wakeUp)?.nodes || [])
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
wakeUpTimerId = setTimeout(() => {
|
|
44
|
+
setIsComplete(false)
|
|
45
|
+
getFeature(devId, wakeUpPlanFeatureId).then(res => {
|
|
46
|
+
setIsComplete(true)
|
|
47
|
+
if (res.result) {
|
|
48
|
+
const nodes = wakeUpDp2Obj(wakeUp)?.nodes || []
|
|
49
|
+
const uiPlan = nodes.map((item, idx) => {
|
|
50
|
+
const plan = res.data[idx]
|
|
51
|
+
const dp = parseJSON(plan?.startTime)?.dp
|
|
52
|
+
const featureItem = (plan && dp) ? plan : res.data.find(p => parseJSON(p?.startTime)?.dp)?.includes(item.nodeHex)
|
|
53
|
+
return {
|
|
54
|
+
...item,
|
|
55
|
+
id: idx,
|
|
56
|
+
name: featureItem ? featureItem?.name : `${I18n.getLang('sleepwakeschedule_field_3_Times_chips_text')} ${idx + 1}`
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
setWakeUpList(uiPlan || [])
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
}, 250)
|
|
63
|
+
|
|
64
|
+
return () =>{
|
|
65
|
+
if(wakeUpTimerId) clearTimeout(wakeUpTimerId)
|
|
66
|
+
}
|
|
67
|
+
}, [wakeUp])
|
|
68
|
+
|
|
69
|
+
const setWakeUpFn = async (wakeUp: WakeUpUIData) => {
|
|
70
|
+
const featureData = wakeUp?.nodes.map(item => {
|
|
71
|
+
return {
|
|
72
|
+
name: item.name,
|
|
73
|
+
startTime: JSON.stringify({
|
|
74
|
+
dp: wakeUpNode2Dp(item)
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
const res = await putFeature(devId, wakeUpPlanFeatureId, featureData || [])
|
|
79
|
+
if (res.result) {
|
|
80
|
+
setWakeUp(wakeUpObj2Dp(wakeUp)).then()
|
|
81
|
+
return {
|
|
82
|
+
success: true
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
success: false
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return [wakeUpList, setWakeUpFn, isComplete]
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
const wakeUpDp2Obj = (dp: string): WakeUpData | undefined => {
|
|
94
|
+
if (!dp || dp?.length <= 6) return
|
|
95
|
+
const version = hex2Int(dp.slice(0, 2))
|
|
96
|
+
const num = hex2Int(dp.slice(2, 4))
|
|
97
|
+
const nodes = spliceByStep(dp.slice(4), 24).map((plan) => {
|
|
98
|
+
const enable = !!hex2Int(plan.slice(0, 2))
|
|
99
|
+
const weeks = parseInt(plan.slice(2, 4), 16).toString(2).padStart(8, '0')
|
|
100
|
+
.split('')
|
|
101
|
+
.reverse()
|
|
102
|
+
.map(v => parseInt(v, 10))
|
|
103
|
+
const delay = hex2Int(plan.slice(4, 6))
|
|
104
|
+
const hour = hex2Int(plan.slice(6, 8))
|
|
105
|
+
const minute = hex2Int(plan.slice(8, 10))
|
|
106
|
+
const h = hex2Int(plan.slice(10, 12)) * 100 + hex2Int(plan.slice(12, 14))
|
|
107
|
+
const s = hex2Int(plan.slice(14, 16))
|
|
108
|
+
const v = hex2Int(plan.slice(16, 18))
|
|
109
|
+
const brightness = hex2Int(plan.slice(18, 20))
|
|
110
|
+
const temperature = hex2Int(plan.slice(20, 22))
|
|
111
|
+
const last = hex2Int(plan.slice(22, 24))
|
|
112
|
+
const endTime = hour * 60 + minute
|
|
113
|
+
const endMin = endTime - delay * 5
|
|
114
|
+
const startTime = endMin < 0 ? 1440 + endMin : endMin
|
|
115
|
+
const cloneWeek = cloneDeep(weeks)
|
|
116
|
+
cloneWeek.pop()
|
|
117
|
+
const weeksValue = padStart([...cloneWeek].join(''), 8, '0')
|
|
118
|
+
const weeksHex = to16(parseInt(weeksValue, 2), 2)
|
|
119
|
+
const nodeHex = plan.slice(0, 2) + weeksHex + plan.slice(4)
|
|
120
|
+
return {
|
|
121
|
+
enable, weeks, delay, hour, minute, h, s, v, brightness, temperature, last, nodeHex, isSleep: false,
|
|
122
|
+
startTime,
|
|
123
|
+
endTime,
|
|
124
|
+
isColorMode: !!(h && s && v)
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
return {
|
|
128
|
+
version,
|
|
129
|
+
num,
|
|
130
|
+
nodes
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const wakeUpObj2Dp = (wakeUp: WakeUpData) => {
|
|
135
|
+
const { version, nodes } = wakeUp
|
|
136
|
+
const versionHex = to16(version)
|
|
137
|
+
const numHex = to16(nodes.length)
|
|
138
|
+
const nodeHex = nodes.map(node => {
|
|
139
|
+
const enableHex = node.enable ? '01' : '00'
|
|
140
|
+
const weeksValue = padStart([...node.weeks].reverse().join(''), 8, '0')
|
|
141
|
+
const weeksHex = to16(parseInt(weeksValue, 2), 2)
|
|
142
|
+
const delayHex = to16(node.delay)
|
|
143
|
+
const hourHex = to16(node.hour)
|
|
144
|
+
const minuteHex = to16(node.minute)
|
|
145
|
+
const hString = node.h.toString().padStart(4, '0')
|
|
146
|
+
const h = to16(Number(hString.slice(0, 2))) + to16(Number(hString.slice(2, 4)))
|
|
147
|
+
const s = to16(node.s)
|
|
148
|
+
const v = to16(node.v)
|
|
149
|
+
const brightness = to16(node.brightness)
|
|
150
|
+
const temperature = to16(node.temperature)
|
|
151
|
+
const lastHex = to16(node.last)
|
|
152
|
+
return `${enableHex}${weeksHex}${delayHex}${hourHex}${minuteHex}${h}${s}${v}${brightness}${temperature}${lastHex}`
|
|
153
|
+
}).join('')
|
|
154
|
+
return versionHex + numHex + nodeHex
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export const wakeUpNode2Dp = (node: WakeUpItem) =>{
|
|
158
|
+
const enableHex = node.enable ? '01' : '00'
|
|
159
|
+
const cloneWeek = cloneDeep(node.weeks)
|
|
160
|
+
cloneWeek.pop()
|
|
161
|
+
const weeksValue = padStart([...cloneWeek].join(''), 8, '0')
|
|
162
|
+
const weeksHex = to16(parseInt(weeksValue, 2), 2)
|
|
163
|
+
const delayHex = to16(node.delay)
|
|
164
|
+
const hourHex = to16(node.hour)
|
|
165
|
+
const minuteHex = to16(node.minute)
|
|
166
|
+
const hString = node.h.toString().padStart(4, '0')
|
|
167
|
+
const h = to16(Number(hString.slice(0, 2))) + to16(Number(hString.slice(2, 4)))
|
|
168
|
+
const s = to16(node.s)
|
|
169
|
+
const v = to16(node.v)
|
|
170
|
+
const brightness = to16(node.brightness)
|
|
171
|
+
const temperature = to16(node.temperature)
|
|
172
|
+
const lastHex = to16(node.last)
|
|
173
|
+
return `${enableHex}${weeksHex}${delayHex}${hourHex}${minuteHex}${h}${s}${v}${brightness}${temperature}${lastHex}`
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
let sleepTimerId: number | undefined = undefined
|
|
177
|
+
type SleepModeType = (sleepDp: string, disableFeature?: boolean) => [SleepUIItem[], (sleepData: SleepUIData) => Promise<Result<any>>, boolean]
|
|
178
|
+
// @ts-ignore
|
|
179
|
+
export const useSleepMode: SleepModeType = (sleepDp, disableFeature) => {
|
|
180
|
+
const devId = useDeviceId()
|
|
181
|
+
const [sleepMode, setSleepMode]: [string, (sleep: string) => Promise<Result<any>>] = useDp(sleepDp)
|
|
182
|
+
const [sleepPlan, setSleepPlan] = useState(sleepDp2Obj(sleepMode)?.nodes || [])
|
|
183
|
+
const [isComplete, setIsComplete] = useState(false)
|
|
184
|
+
useEffect(() => {
|
|
185
|
+
if(disableFeature) {
|
|
186
|
+
setIsComplete(true)
|
|
187
|
+
setSleepPlan(sleepDp2Obj(sleepMode)?.nodes || [])
|
|
188
|
+
return
|
|
189
|
+
}
|
|
190
|
+
sleepTimerId = setTimeout(() =>{
|
|
191
|
+
setIsComplete(false)
|
|
192
|
+
getFeature(devId, sleepPlanFeatureId).then(res => {
|
|
193
|
+
setIsComplete(true)
|
|
194
|
+
if (res.result) {
|
|
195
|
+
const nodes = sleepDp2Obj(sleepMode)?.nodes || []
|
|
196
|
+
const uiPlan = nodes.map((item, idx) => {
|
|
197
|
+
const plan = res.data[idx]
|
|
198
|
+
const dp = parseJSON(plan?.startTime)?.dp
|
|
199
|
+
const featureItem = (plan && dp) ? plan : res.data.find(p => parseJSON(p?.startTime)?.dp)?.includes(item.nodeHex)
|
|
200
|
+
return {
|
|
201
|
+
...item,
|
|
202
|
+
id: idx,
|
|
203
|
+
name: featureItem ? featureItem?.name : `${I18n.getLang('sleepwakeschedule_field_3_Times_chips2_text')} ${idx + 1}`
|
|
204
|
+
}
|
|
205
|
+
})
|
|
206
|
+
setSleepPlan(uiPlan || [])
|
|
207
|
+
}
|
|
208
|
+
})
|
|
209
|
+
}, 250)
|
|
210
|
+
|
|
211
|
+
return () =>{
|
|
212
|
+
if(sleepTimerId) clearTimeout(sleepTimerId)
|
|
213
|
+
}
|
|
214
|
+
}, [sleepMode])
|
|
215
|
+
|
|
216
|
+
const setSleepPlanFn = async (sleep: SleepUIData) => {
|
|
217
|
+
const featureData = sleep?.nodes.map(item => {
|
|
218
|
+
return {
|
|
219
|
+
name: item.name,
|
|
220
|
+
startTime: JSON.stringify({
|
|
221
|
+
dp: sleepNode2Dp(item)
|
|
222
|
+
})
|
|
223
|
+
}
|
|
224
|
+
})
|
|
225
|
+
const res = await putFeature(devId, sleepPlanFeatureId, featureData || [])
|
|
226
|
+
if (res.result) {
|
|
227
|
+
setSleepMode(sleepObj2Dp(sleep)).then()
|
|
228
|
+
return {
|
|
229
|
+
success: true
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return {
|
|
233
|
+
success: false
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return [sleepPlan, setSleepPlanFn, isComplete]
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export const sleepDp2Obj = (dp: string): SleepData | undefined => {
|
|
240
|
+
if (!dp || dp?.length <= 6) return
|
|
241
|
+
const version = hex2Int(dp.slice(0, 2))
|
|
242
|
+
const num = hex2Int(dp.slice(2, 4))
|
|
243
|
+
const nodes = spliceByStep(dp.slice(4), 22).map(plan => {
|
|
244
|
+
const enable = !!hex2Int(plan.slice(0, 2))
|
|
245
|
+
const weeks = parseInt(plan.slice(2, 4), 16).toString(2).padStart(8, '0')
|
|
246
|
+
.split('')
|
|
247
|
+
.reverse()
|
|
248
|
+
.map(v => parseInt(v, 10))
|
|
249
|
+
const delay = hex2Int(plan.slice(4, 6))
|
|
250
|
+
const hour = hex2Int(plan.slice(6, 8))
|
|
251
|
+
const minute = hex2Int(plan.slice(8, 10))
|
|
252
|
+
const h = hex2Int(plan.slice(10, 12)) * 100 + hex2Int(plan.slice(12, 14))
|
|
253
|
+
const s = hex2Int(plan.slice(14, 16))
|
|
254
|
+
const v = hex2Int(plan.slice(16, 18))
|
|
255
|
+
const brightness = hex2Int(plan.slice(18, 20))
|
|
256
|
+
const temperature = hex2Int(plan.slice(20, 22))
|
|
257
|
+
const startTime = hour * 60 + minute
|
|
258
|
+
const endMin = startTime + delay * 5
|
|
259
|
+
const endTime = endMin > 1440 ? endMin - 1440 : endMin
|
|
260
|
+
const cloneWeek = cloneDeep(weeks)
|
|
261
|
+
cloneWeek.pop()
|
|
262
|
+
const weeksValue = padStart([...cloneWeek].join(''), 8, '0')
|
|
263
|
+
const weeksHex = to16(parseInt(weeksValue, 2), 2)
|
|
264
|
+
const nodeHex = plan.slice(0, 2) + weeksHex + plan.slice(4)
|
|
265
|
+
return {
|
|
266
|
+
enable, weeks, delay, hour, minute, h, s, v, brightness, temperature, nodeHex, isSleep: true,
|
|
267
|
+
startTime,
|
|
268
|
+
endTime,
|
|
269
|
+
isColorMode: !!(h && s && v)
|
|
270
|
+
}
|
|
271
|
+
})
|
|
272
|
+
return {
|
|
273
|
+
version,
|
|
274
|
+
num,
|
|
275
|
+
nodes
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
export const sleepObj2Dp = (sleep: SleepData) => {
|
|
280
|
+
const { version, nodes } = sleep
|
|
281
|
+
const versionHex = to16(version)
|
|
282
|
+
const numHex = to16(nodes.length)
|
|
283
|
+
const nodeHex = nodes.map(node => {
|
|
284
|
+
const enableHex = node.enable ? '01' : '00'
|
|
285
|
+
const weeksValue = padStart([...node.weeks].reverse().join(''), 8, '0')
|
|
286
|
+
const weeksHex = to16(parseInt(weeksValue, 2), 2)
|
|
287
|
+
const delayHex = to16(node.delay)
|
|
288
|
+
const hourHex = to16(node.hour)
|
|
289
|
+
const minuteHex = to16(node.minute)
|
|
290
|
+
const hString = node.h.toString().padStart(4, '0')
|
|
291
|
+
const h = to16(Number(hString.slice(0, 2))) + to16(Number(hString.slice(2, 4)))
|
|
292
|
+
const s = to16(node.s)
|
|
293
|
+
const v = to16(node.v)
|
|
294
|
+
const brightness = to16(node.brightness)
|
|
295
|
+
const temperature = to16(node.temperature)
|
|
296
|
+
return `${enableHex}${weeksHex}${delayHex}${hourHex}${minuteHex}${h}${s}${v}${brightness}${temperature}`
|
|
297
|
+
}).join('')
|
|
298
|
+
return versionHex + numHex + nodeHex
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export const sleepNode2Dp = (node: SleepItem) => {
|
|
302
|
+
const enableHex = node.enable ? '01' : '00'
|
|
303
|
+
const cloneWeek = cloneDeep(node.weeks)
|
|
304
|
+
cloneWeek.pop()
|
|
305
|
+
const weeksValue = padStart([...cloneWeek].join(''), 8, '0')
|
|
306
|
+
const weeksHex = to16(parseInt(weeksValue, 2), 2)
|
|
307
|
+
const delayHex = to16(node.delay)
|
|
308
|
+
const hourHex = to16(node.hour)
|
|
309
|
+
const minuteHex = to16(node.minute)
|
|
310
|
+
const hString = node.h.toString().padStart(4, '0')
|
|
311
|
+
const h = to16(Number(hString.slice(0, 2))) + to16(Number(hString.slice(2, 4)))
|
|
312
|
+
const s = to16(node.s)
|
|
313
|
+
const v = to16(node.v)
|
|
314
|
+
const brightness = to16(node.brightness)
|
|
315
|
+
const temperature = to16(node.temperature)
|
|
316
|
+
return `${enableHex}${weeksHex}${delayHex}${hourHex}${minuteHex}${h}${s}${v}${brightness}${temperature}`
|
|
317
|
+
}
|