@ledvance/ui-biz-bundle 1.1.66 → 1.1.67

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 CHANGED
@@ -4,7 +4,7 @@
4
4
  "name": "@ledvance/ui-biz-bundle",
5
5
  "pid": [],
6
6
  "uiid": "",
7
- "version": "1.1.66",
7
+ "version": "1.1.67",
8
8
  "scripts": {},
9
9
  "dependencies": {
10
10
  "@ledvance/base": "^1.x",
@@ -46,18 +46,22 @@ interface UIState extends BiorhythmBean {
46
46
  }
47
47
 
48
48
  export interface BiorhythmPageParams {
49
- biorhythmDp: string
50
- sleepPlanDp: string
51
- wakeUpPlanDp: string
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
- isMixRGBWLamp: boolean
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.biorhythmDp)
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.isMixRGBWLamp,
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.isMixRGBWLamp,
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
- randomTimeDp?: string
30
- biorhythmDp?: string
31
- sleepWakeUpDp?: string
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
- fixedTimeDp?: string
31
- biorhythmDp?: string
32
- sleepWakeUpDp?: string
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,6 @@
1
+ import { useDp } from "@ledvance/base/src/models/modules/NativePropsSlice"
2
+ import { Result } from "@ledvance/base/src/models/modules/Result"
3
+
4
+ export const useRemoteControl = (dp: string): [boolean, (v: boolean) => Promise<Result<any>>] =>{
5
+ return useDp(dp)
6
+ }
@@ -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
+ }