@ray-js/lamp-schedule-core 1.0.5-beta.1 → 1.0.5-beta.10
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/lib/config/dpCodes.d.ts +18 -1
- package/lib/config/dpCodes.js +34 -1
- package/lib/conflict/index.d.ts +13 -3
- package/lib/conflict/index.js +27 -1
- package/lib/conflict/scheduleDataManager.js +7 -3
- package/lib/conflict/transform.js +2 -1
- package/lib/conflict/type.d.ts +4 -0
- package/lib/dpParser/__test__/sleepSigmesh.test.js +4 -2
- package/lib/dpParser/__test__/wakeupSigmesh.test.js +4 -2
- package/lib/dpParser/brightAdjustData.d.ts +10 -0
- package/lib/dpParser/brightAdjustData.js +43 -0
- package/lib/dpParser/colourDataRaw.d.ts +14 -0
- package/lib/dpParser/colourDataRaw.js +56 -0
- package/lib/dpParser/index.d.ts +3 -0
- package/lib/dpParser/index.js +13 -0
- package/lib/dpParser/sleep/sleepSigmesh.js +6 -3
- package/lib/dpParser/stripLocalTimer.d.ts +41 -0
- package/lib/dpParser/stripLocalTimer.js +275 -0
- package/lib/dpParser/wakeup/wakeupSigmesh.js +4 -3
- package/lib/hooks/__test__/useBaseLightDp.test.js +10 -2
- package/lib/hooks/__test__/useTimerDp.test.js +5 -5
- package/lib/hooks/useBaseLightDp.d.ts +6 -1
- package/lib/hooks/useBaseLightDp.js +33 -16
- package/lib/hooks/useCycleDp.js +1 -1
- package/lib/hooks/useDPByProtocol.d.ts +11 -0
- package/lib/hooks/useRandomDp.js +1 -1
- package/lib/hooks/useRhythmsDp.js +1 -1
- package/lib/hooks/useSleepDp.js +1 -1
- package/lib/hooks/useTimerDp.d.ts +4 -3
- package/lib/hooks/useTimerDp.js +21 -4
- package/lib/hooks/useTimerReportDp.js +1 -0
- package/lib/hooks/useWakeUpDp.js +1 -1
- package/lib/hooks/useWakeupDp.js +1 -1
- package/lib/types/timer.d.ts +11 -0
- package/lib/utils/ScheduleDataSync.js +1 -0
- package/lib/utils/ScheduleSupport.d.ts +4 -0
- package/lib/utils/ScheduleSupport.js +21 -3
- package/lib/utils/__test__/ScheduleDataSync.test.d.ts +1 -0
- package/lib/utils/__test__/ScheduleDataSync.test.js +2 -0
- package/lib/utils/__test__/objectToId.test.d.ts +1 -0
- package/lib/utils/__test__/objectToId.test.js +98 -0
- package/lib/utils/getDPByProtocol.d.ts +22 -0
- package/lib/utils/matterDeviceUtils.d.ts +22 -0
- package/package.json +1 -1
package/lib/config/dpCodes.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export declare const scheduleDpCodes: {
|
|
|
19
19
|
readonly CYCLE_TIMING: "cycle_timing";
|
|
20
20
|
/** 通用本地定时 */
|
|
21
21
|
readonly LOCAL_TIMER: "local_timer";
|
|
22
|
-
/** 灯带本地定时 */
|
|
22
|
+
/** 灯带本地定时 Beacon */
|
|
23
23
|
readonly STRIP_LOCAL_TIMER: "strip_local_timer";
|
|
24
24
|
/** 定时同步 一般用于 Beacon */
|
|
25
25
|
readonly TIMER_SYNC: "timer_sync";
|
|
@@ -33,6 +33,23 @@ export declare const scheduleDpCodes: {
|
|
|
33
33
|
readonly BRIGHTNESS: "bright_value";
|
|
34
34
|
/** 彩光 */
|
|
35
35
|
readonly COLOUR_DATA: "colour_data";
|
|
36
|
+
/** 彩光原始数据 Beacon */
|
|
37
|
+
readonly COLOUR_DATA_RAW: "colour_data_raw";
|
|
38
|
+
/** 亮度调节 Beacon */
|
|
39
|
+
readonly BRIGHT_ADJUST_DATA: "bright_adjust_data";
|
|
40
|
+
/** ------ 风扇灯 Beacon DP -------- */
|
|
41
|
+
/** 风扇模式 Beacon */
|
|
42
|
+
readonly FAN_MODE: "fan_mode";
|
|
43
|
+
/** 风向 Beacon */
|
|
44
|
+
readonly FAN_DIRECTION: "fan_direction";
|
|
45
|
+
/** 摇头 Beacon */
|
|
46
|
+
readonly SHAKE: "shake";
|
|
47
|
+
readonly WHITE_SWITCH: "white_switch";
|
|
48
|
+
readonly COLOUR_SWITCH: "colour_switch";
|
|
49
|
+
readonly FAN_SWITCH: "fan_switch";
|
|
50
|
+
readonly FAN_SPEED: "fan_speed";
|
|
51
|
+
readonly FAN_BEEP: "fan_beep";
|
|
52
|
+
readonly STRIP_SCENE: "strip_scene";
|
|
36
53
|
/** 模式 */
|
|
37
54
|
readonly WORK_MODE: "work_mode";
|
|
38
55
|
};
|
package/lib/config/dpCodes.js
CHANGED
|
@@ -22,7 +22,7 @@ export const scheduleDpCodes = {
|
|
|
22
22
|
[EScheduleType.CYCLE_TIMING]: 'cycle_timing',
|
|
23
23
|
/** 通用本地定时 */
|
|
24
24
|
[EScheduleType.LOCAL_TIMER]: 'local_timer',
|
|
25
|
-
/** 灯带本地定时 */
|
|
25
|
+
/** 灯带本地定时 Beacon */
|
|
26
26
|
[EScheduleType.STRIP_LOCAL_TIMER]: 'strip_local_timer',
|
|
27
27
|
/** 定时同步 一般用于 Beacon */
|
|
28
28
|
[EScheduleType.TIMER_SYNC]: 'timer_sync',
|
|
@@ -36,6 +36,39 @@ export const scheduleDpCodes = {
|
|
|
36
36
|
BRIGHTNESS: 'bright_value',
|
|
37
37
|
/** 彩光 */
|
|
38
38
|
COLOUR_DATA: 'colour_data',
|
|
39
|
+
/** 彩光原始数据 Beacon */
|
|
40
|
+
COLOUR_DATA_RAW: 'colour_data_raw',
|
|
41
|
+
/** 亮度调节 Beacon */
|
|
42
|
+
BRIGHT_ADJUST_DATA: 'bright_adjust_data',
|
|
43
|
+
/** ------ 风扇灯 Beacon DP -------- */
|
|
44
|
+
/** 风扇模式 Beacon */
|
|
45
|
+
FAN_MODE: 'fan_mode',
|
|
46
|
+
// 枚举值: fresh, nature
|
|
47
|
+
/** 风向 Beacon */
|
|
48
|
+
FAN_DIRECTION: 'fan_direction',
|
|
49
|
+
// 枚举值: forward, reverse
|
|
50
|
+
/** 摇头 Beacon */
|
|
51
|
+
SHAKE: 'shake',
|
|
52
|
+
// boolean
|
|
53
|
+
// 主灯开关
|
|
54
|
+
WHITE_SWITCH: 'white_switch',
|
|
55
|
+
// boolean
|
|
56
|
+
// 氛围灯开关
|
|
57
|
+
COLOUR_SWITCH: 'colour_switch',
|
|
58
|
+
// boolean
|
|
59
|
+
// 风扇开关
|
|
60
|
+
FAN_SWITCH: 'fan_switch',
|
|
61
|
+
// boolean
|
|
62
|
+
// 风扇速度
|
|
63
|
+
FAN_SPEED: 'fan_speed',
|
|
64
|
+
// number 1-100
|
|
65
|
+
// 声音
|
|
66
|
+
FAN_BEEP: 'fan_beep',
|
|
67
|
+
// boolean
|
|
68
|
+
// 情景
|
|
69
|
+
STRIP_SCENE: 'strip_scene',
|
|
70
|
+
// beacon mesh情景功能,支持速度,亮度编辑
|
|
71
|
+
|
|
39
72
|
/** 模式 */
|
|
40
73
|
WORK_MODE: 'work_mode'
|
|
41
74
|
};
|
package/lib/conflict/index.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import { TConflictRes, ConflictRule, TFoldScheduleList, TSchedule } from './type';
|
|
1
|
+
import { TConflictRes, ConflictRule, TFoldScheduleList, TSchedule, PartialSchedule } from './type';
|
|
2
|
+
import { EScheduleFunctionType } from '../types';
|
|
2
3
|
/**
|
|
3
4
|
* 冲突检测
|
|
4
5
|
*/
|
|
5
6
|
export declare class Conflict {
|
|
6
7
|
static rule: ConflictRule;
|
|
7
8
|
static isInit: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* 获取冲突检测数据
|
|
11
|
+
*/
|
|
12
|
+
static getData(): Record<string, any>[];
|
|
8
13
|
/**
|
|
9
14
|
* 添加冲突规则
|
|
10
15
|
*/
|
|
@@ -18,13 +23,18 @@ export declare class Conflict {
|
|
|
18
23
|
* conflictList - 具体的冲突检测结果数组
|
|
19
24
|
*/
|
|
20
25
|
static add(current: TSchedule): TConflictRes;
|
|
26
|
+
/**
|
|
27
|
+
* 删除指定类型的日程
|
|
28
|
+
* @param type - 日程类型
|
|
29
|
+
*/
|
|
30
|
+
static removeByType(type: EScheduleFunctionType): void;
|
|
21
31
|
/**
|
|
22
32
|
* 删除日程
|
|
23
33
|
*
|
|
24
|
-
* @param current - 待添加的日程对象,类型为 Schedule
|
|
34
|
+
* @param current - 待添加的日程对象,类型为 Schedule, 如果没有 detail 则认为是删除指定类型的日程
|
|
25
35
|
* @returns void
|
|
26
36
|
*/
|
|
27
|
-
static remove(current: TSchedule): void;
|
|
37
|
+
static remove(current: TSchedule | PartialSchedule): void;
|
|
28
38
|
/**
|
|
29
39
|
* 更新新日程时检测冲突
|
|
30
40
|
*
|
package/lib/conflict/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
2
|
import "core-js/modules/es.json.stringify.js";
|
|
3
3
|
import "core-js/modules/esnext.iterator.constructor.js";
|
|
4
|
+
import "core-js/modules/esnext.iterator.filter.js";
|
|
4
5
|
import "core-js/modules/esnext.iterator.find.js";
|
|
5
6
|
import { scheduleLogger } from '../utils/ScheduleLogger';
|
|
6
7
|
import { checkConflicts } from './ConflictResolver';
|
|
@@ -12,6 +13,13 @@ import { EScheduleFunctionType } from '../types';
|
|
|
12
13
|
* 冲突检测
|
|
13
14
|
*/
|
|
14
15
|
export class Conflict {
|
|
16
|
+
/**
|
|
17
|
+
* 获取冲突检测数据
|
|
18
|
+
*/
|
|
19
|
+
static getData() {
|
|
20
|
+
return ScheduleDataManager.getInstance().getData();
|
|
21
|
+
}
|
|
22
|
+
|
|
15
23
|
/**
|
|
16
24
|
* 添加冲突规则
|
|
17
25
|
*/
|
|
@@ -50,13 +58,31 @@ export class Conflict {
|
|
|
50
58
|
};
|
|
51
59
|
}
|
|
52
60
|
|
|
61
|
+
/**
|
|
62
|
+
* 删除指定类型的日程
|
|
63
|
+
* @param type - 日程类型
|
|
64
|
+
*/
|
|
65
|
+
static removeByType(type) {
|
|
66
|
+
const instance = ScheduleDataManager.getInstance();
|
|
67
|
+
const list = instance.getData() || [];
|
|
68
|
+
const filteredList = list.filter(item => item.type !== type);
|
|
69
|
+
ScheduleDataManager.list = filteredList;
|
|
70
|
+
}
|
|
71
|
+
|
|
53
72
|
/**
|
|
54
73
|
* 删除日程
|
|
55
74
|
*
|
|
56
|
-
* @param current - 待添加的日程对象,类型为 Schedule
|
|
75
|
+
* @param current - 待添加的日程对象,类型为 Schedule, 如果没有 detail 则认为是删除指定类型的日程
|
|
57
76
|
* @returns void
|
|
58
77
|
*/
|
|
59
78
|
static remove(current) {
|
|
79
|
+
if (!current) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (current.type && !current.detail) {
|
|
83
|
+
this.removeByType(current.type);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
60
86
|
const [cur] = transScheduleListToConflictList([current]);
|
|
61
87
|
scheduleLogger.debug('Conflict.remove cur, current:', cur, current);
|
|
62
88
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import "core-js/modules/es.json.stringify.js";
|
|
1
2
|
import "core-js/modules/esnext.iterator.constructor.js";
|
|
2
3
|
import "core-js/modules/esnext.iterator.filter.js";
|
|
3
4
|
import "core-js/modules/esnext.iterator.for-each.js";
|
|
@@ -63,10 +64,11 @@ export class ScheduleDataManager {
|
|
|
63
64
|
}
|
|
64
65
|
const idsToAdd = new Set(itemsMap.keys());
|
|
65
66
|
const filteredList = ScheduleDataManager.list.filter(item => !idsToAdd.has(item.id));
|
|
66
|
-
|
|
67
|
+
const newList = [...filteredList, ...itemsMap.values()].filter(item => {
|
|
67
68
|
var _item$data;
|
|
68
69
|
return (item === null || item === void 0 || (_item$data = item.data) === null || _item$data === void 0 ? void 0 : _item$data.status) === true;
|
|
69
70
|
});
|
|
71
|
+
ScheduleDataManager.list = newList;
|
|
70
72
|
}
|
|
71
73
|
clearData() {
|
|
72
74
|
scheduleLogger.debug('ScheduleDataManager.clearData pre', ScheduleDataManager.list);
|
|
@@ -76,12 +78,14 @@ export class ScheduleDataManager {
|
|
|
76
78
|
if (!current) {
|
|
77
79
|
return;
|
|
78
80
|
}
|
|
79
|
-
scheduleLogger.debug('ScheduleDataManager.deleteData pre', current);
|
|
81
|
+
scheduleLogger.debug('ScheduleDataManager.deleteData pre', current, JSON.stringify(ScheduleDataManager.list));
|
|
80
82
|
const index = ScheduleDataManager.list.findIndex(item => item.id === current.id);
|
|
81
83
|
if (index !== -1) {
|
|
82
84
|
ScheduleDataManager.list.splice(index, 1);
|
|
85
|
+
scheduleLogger.debug('ScheduleDataManager.deleteData post', JSON.stringify(ScheduleDataManager.list));
|
|
86
|
+
} else {
|
|
87
|
+
scheduleLogger.debug('ScheduleDataManager.deleteData post not found', JSON.stringify(ScheduleDataManager.list));
|
|
83
88
|
}
|
|
84
|
-
scheduleLogger.debug('ScheduleDataManager.deleteData post', ScheduleDataManager.list);
|
|
85
89
|
}
|
|
86
90
|
|
|
87
91
|
// 添加remove方法作为deleteData的别名,用于测试
|
|
@@ -18,6 +18,7 @@ import { scheduleLogger } from '../utils/ScheduleLogger';
|
|
|
18
18
|
export const timerDataToSchedule = data => {
|
|
19
19
|
var _data$status;
|
|
20
20
|
scheduleLogger.debug('timerDataToSchedule:', data);
|
|
21
|
+
const stableTimerId = data.timerId || (data === null || data === void 0 ? void 0 : data.id);
|
|
21
22
|
const _data = {
|
|
22
23
|
status: (_data$status = data.status) !== null && _data$status !== void 0 ? _data$status : false,
|
|
23
24
|
weeks: data.loops.split('').map(item => Number(item)),
|
|
@@ -26,7 +27,7 @@ export const timerDataToSchedule = data => {
|
|
|
26
27
|
dps: data.dps,
|
|
27
28
|
aliasName: data.aliasName || '',
|
|
28
29
|
isAppPush: data.isAppPush || false,
|
|
29
|
-
id:
|
|
30
|
+
id: stableTimerId
|
|
30
31
|
};
|
|
31
32
|
const timerId = `${EScheduleFunctionType.TIMER}_${_data.id}`;
|
|
32
33
|
return {
|
package/lib/conflict/type.d.ts
CHANGED
|
@@ -52,5 +52,9 @@ export type TSchedule = {
|
|
|
52
52
|
type: EScheduleFunctionType;
|
|
53
53
|
detail: ScheduleNodeType[];
|
|
54
54
|
};
|
|
55
|
+
export type PartialSchedule = {
|
|
56
|
+
type: EScheduleFunctionType;
|
|
57
|
+
detail?: ScheduleNodeType[];
|
|
58
|
+
};
|
|
55
59
|
export type TFoldScheduleList = TSchedule[];
|
|
56
60
|
export {};
|
|
@@ -121,6 +121,7 @@ describe('SleepSigmesh parser & formatter', () => {
|
|
|
121
121
|
index: 0
|
|
122
122
|
}]
|
|
123
123
|
});
|
|
124
|
+
// formatter 固定输出 version=1, dataMode=1
|
|
124
125
|
expect(result).toBe(buildDpStr([{
|
|
125
126
|
onOff: 1,
|
|
126
127
|
loops: loopsToHex('1000000'),
|
|
@@ -129,7 +130,7 @@ describe('SleepSigmesh parser & formatter', () => {
|
|
|
129
130
|
minute: 15,
|
|
130
131
|
brightness: 90,
|
|
131
132
|
temperature: 50
|
|
132
|
-
}], 1,
|
|
133
|
+
}], 1, 1));
|
|
133
134
|
});
|
|
134
135
|
it('round-trips dp string through parser and formatter', () => {
|
|
135
136
|
const nodes = [{
|
|
@@ -144,7 +145,8 @@ describe('SleepSigmesh parser & formatter', () => {
|
|
|
144
145
|
const dpStr = buildDpStr(nodes, 2, 3);
|
|
145
146
|
const parsed = sleepParserSigmesh.parser(dpStr);
|
|
146
147
|
const formatted = sleepParserSigmesh.formatter(parsed);
|
|
147
|
-
|
|
148
|
+
// formatter 固定输出 version=1, dataMode=1,故 round-trip 后与原始 dpStr 不同
|
|
149
|
+
expect(formatted).toBe(buildDpStr(nodes, 1, 1));
|
|
148
150
|
});
|
|
149
151
|
it('handles multiple nodes correctly', () => {
|
|
150
152
|
const nodes = [{
|
|
@@ -97,6 +97,7 @@ describe('WakeUpSigmesh parser & formatter', () => {
|
|
|
97
97
|
index: 0
|
|
98
98
|
}]
|
|
99
99
|
});
|
|
100
|
+
// formatter 固定输出 version=1, dataMode=1(与 parser 可解析的格式一致)
|
|
100
101
|
expect(result).toBe(buildDpStr([{
|
|
101
102
|
onOff: 1,
|
|
102
103
|
loops: loopsToHex('1000000'),
|
|
@@ -106,7 +107,7 @@ describe('WakeUpSigmesh parser & formatter', () => {
|
|
|
106
107
|
brightness: 90,
|
|
107
108
|
temperature: 50,
|
|
108
109
|
duration: 20
|
|
109
|
-
}], 1,
|
|
110
|
+
}], 1, 1));
|
|
110
111
|
});
|
|
111
112
|
it('round-trips dp string through parser and formatter', () => {
|
|
112
113
|
const nodes = [{
|
|
@@ -122,6 +123,7 @@ describe('WakeUpSigmesh parser & formatter', () => {
|
|
|
122
123
|
const dpStr = buildDpStr(nodes, 2, 3);
|
|
123
124
|
const parsed = wakeupParserSigmesh.parser(dpStr);
|
|
124
125
|
const formatted = wakeupParserSigmesh.formatter(parsed);
|
|
125
|
-
|
|
126
|
+
// formatter 固定输出 version=1, dataMode=1,故 round-trip 后与原始 dpStr 不同
|
|
127
|
+
expect(formatted).toBe(buildDpStr(nodes, 1, 1));
|
|
126
128
|
});
|
|
127
129
|
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { TBrightAdjustData } from '../types';
|
|
2
|
+
export declare class BrightAdjustDataFormatter {
|
|
3
|
+
parser(dpValue: string): TBrightAdjustData;
|
|
4
|
+
formatter(data: TBrightAdjustData): string;
|
|
5
|
+
}
|
|
6
|
+
export declare const brightAdjustDataParser: {
|
|
7
|
+
parser: (dpValue: string) => TBrightAdjustData;
|
|
8
|
+
formatter: (data: TBrightAdjustData) => string;
|
|
9
|
+
};
|
|
10
|
+
export declare const getBrightAdjustDataParser: () => BrightAdjustDataFormatter;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
|
|
3
|
+
import { scheduleLogger as ScheduleLogger } from '../utils/ScheduleLogger';
|
|
4
|
+
export class BrightAdjustDataFormatter {
|
|
5
|
+
parser(dpValue) {
|
|
6
|
+
try {
|
|
7
|
+
ScheduleLogger.debug('dpParser ===> BrightAdjustDataFormatter parser dpValue:', dpValue);
|
|
8
|
+
if (!dpValue || dpValue.length < 6) {
|
|
9
|
+
return {
|
|
10
|
+
mode: 0,
|
|
11
|
+
brightness: 0
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
const mode = parseInt(dpValue.substring(0, 2), 16);
|
|
15
|
+
const brightness = parseInt(dpValue.substring(2, 6), 16);
|
|
16
|
+
return {
|
|
17
|
+
mode,
|
|
18
|
+
brightness
|
|
19
|
+
};
|
|
20
|
+
} catch (error) {
|
|
21
|
+
ScheduleLogger.error('dpParser ===> BrightAdjustDataFormatter parser error:', error);
|
|
22
|
+
return {
|
|
23
|
+
mode: 0,
|
|
24
|
+
brightness: 0
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
formatter(data) {
|
|
29
|
+
try {
|
|
30
|
+
ScheduleLogger.debug('dpParser ===> BrightAdjustDataFormatter formatter data:', data);
|
|
31
|
+
const modeStr = data.mode.toString(16).padStart(2, '0');
|
|
32
|
+
const brightnessStr = data.brightness.toString(16).padStart(4, '0');
|
|
33
|
+
return `${modeStr}${brightnessStr}`;
|
|
34
|
+
} catch (error) {
|
|
35
|
+
ScheduleLogger.error('dpParser ===> BrightAdjustDataFormatter formatter error:', error);
|
|
36
|
+
return '';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export const brightAdjustDataParser = new BrightAdjustDataFormatter();
|
|
41
|
+
export const getBrightAdjustDataParser = () => {
|
|
42
|
+
return brightAdjustDataParser;
|
|
43
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { TColourDataRaw } from '../types';
|
|
2
|
+
export declare class ColourDataRawFormatter {
|
|
3
|
+
parser(dpValue: string): TColourDataRaw;
|
|
4
|
+
formatter(data: {
|
|
5
|
+
hue: number;
|
|
6
|
+
saturation: number;
|
|
7
|
+
value: number;
|
|
8
|
+
} | TColourDataRaw): string;
|
|
9
|
+
}
|
|
10
|
+
export declare const colourDataRawParser: {
|
|
11
|
+
parser: (dpValue: string) => TColourDataRaw;
|
|
12
|
+
formatter: (data: any) => string;
|
|
13
|
+
};
|
|
14
|
+
export declare const getColourDataRawParser: () => ColourDataRawFormatter;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import { numToHexString } from '@ray-js/panel-sdk/lib/utils';
|
|
3
|
+
import { scheduleLogger as ScheduleLogger } from '../utils/ScheduleLogger';
|
|
4
|
+
const toHex = function (value) {
|
|
5
|
+
let len = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
|
|
6
|
+
return numToHexString(value).padStart(len, '0');
|
|
7
|
+
};
|
|
8
|
+
export class ColourDataRawFormatter {
|
|
9
|
+
parser(dpValue) {
|
|
10
|
+
try {
|
|
11
|
+
ScheduleLogger.debug('dpParser ===> ColourDataRawFormatter parser dpValue:', dpValue);
|
|
12
|
+
if (!dpValue || dpValue.length < 8) {
|
|
13
|
+
return {
|
|
14
|
+
hue: 0,
|
|
15
|
+
saturation: 1000,
|
|
16
|
+
value: 1000
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const hue = parseInt(dpValue.substring(0, 4), 16);
|
|
20
|
+
const saturation = parseInt(dpValue.substring(4, 6), 16) * 10;
|
|
21
|
+
const value = parseInt(dpValue.substring(6, 8), 16) * 10;
|
|
22
|
+
return {
|
|
23
|
+
hue,
|
|
24
|
+
saturation,
|
|
25
|
+
value
|
|
26
|
+
};
|
|
27
|
+
} catch (error) {
|
|
28
|
+
ScheduleLogger.error('dpParser ===> ColourDataRawFormatter parser error:', error);
|
|
29
|
+
return {
|
|
30
|
+
hue: 0,
|
|
31
|
+
saturation: 1000,
|
|
32
|
+
value: 1000
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
formatter(data) {
|
|
37
|
+
try {
|
|
38
|
+
ScheduleLogger.debug('dpParser ===> ColourDataRawFormatter formatter data:', data);
|
|
39
|
+
// 兼容两种数据格式: { hue, saturation, value } 或 { h, s, v }
|
|
40
|
+
const h = 'hue' in data ? data.hue : data.h;
|
|
41
|
+
const s = 'saturation' in data ? data.saturation : data.s;
|
|
42
|
+
const v = 'value' in data ? data.value : data.v;
|
|
43
|
+
const hStr = toHex(Math.floor(h), 4);
|
|
44
|
+
const sStr = toHex(Math.floor(s / 10), 2);
|
|
45
|
+
const vStr = toHex(Math.floor(v / 10), 2);
|
|
46
|
+
return `${hStr}${sStr}${vStr}`;
|
|
47
|
+
} catch (error) {
|
|
48
|
+
ScheduleLogger.error('dpParser ===> ColourDataRawFormatter formatter error:', error);
|
|
49
|
+
return '';
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export const colourDataRawParser = new ColourDataRawFormatter();
|
|
54
|
+
export const getColourDataRawParser = () => {
|
|
55
|
+
return colourDataRawParser;
|
|
56
|
+
};
|
package/lib/dpParser/index.d.ts
CHANGED
|
@@ -7,6 +7,9 @@ export { rtcTimerParser, getRtcParser } from './rtcTimer';
|
|
|
7
7
|
export { cycleParser, getCycleParser } from './cycle';
|
|
8
8
|
export { wakeupParserCommon as wakeupParser, getWakeUpParser, WakeUpParser } from './wakeup';
|
|
9
9
|
export { timerReportParser } from './timerReport';
|
|
10
|
+
export { stripLocalTimerParser, getStripLocalTimerParser } from './stripLocalTimer';
|
|
11
|
+
export { brightAdjustDataParser, getBrightAdjustDataParser } from './brightAdjustData';
|
|
12
|
+
export { colourDataRawParser, getColourDataRawParser } from './colourDataRaw';
|
|
10
13
|
type DpCode = keyof typeof scheduleDpCodes;
|
|
11
14
|
/**
|
|
12
15
|
* 自动匹配 dp 解析函数
|
package/lib/dpParser/index.js
CHANGED
|
@@ -7,6 +7,9 @@ import { getSleepParser } from './sleep';
|
|
|
7
7
|
import { rtcTimerParser } from './rtcTimer';
|
|
8
8
|
import { timerReportParser } from './timerReport';
|
|
9
9
|
import { getWakeUpParser } from './wakeup';
|
|
10
|
+
import { stripLocalTimerParser } from './stripLocalTimer';
|
|
11
|
+
import { brightAdjustDataParser } from './brightAdjustData';
|
|
12
|
+
import { colourDataRawParser } from './colourDataRaw';
|
|
10
13
|
export { randomParser, getRandomParser } from './random';
|
|
11
14
|
export { rhythmParser, getRhythmParser } from './rhythms';
|
|
12
15
|
export { sleepParserCommon as sleepParser, getSleepParser, SleepParser, sleepParserSigmesh } from './sleep';
|
|
@@ -14,6 +17,9 @@ export { rtcTimerParser, getRtcParser } from './rtcTimer';
|
|
|
14
17
|
export { cycleParser, getCycleParser } from './cycle';
|
|
15
18
|
export { wakeupParserCommon as wakeupParser, getWakeUpParser, WakeUpParser } from './wakeup';
|
|
16
19
|
export { timerReportParser } from './timerReport';
|
|
20
|
+
export { stripLocalTimerParser, getStripLocalTimerParser } from './stripLocalTimer';
|
|
21
|
+
export { brightAdjustDataParser, getBrightAdjustDataParser } from './brightAdjustData';
|
|
22
|
+
export { colourDataRawParser, getColourDataRawParser } from './colourDataRaw';
|
|
17
23
|
/**
|
|
18
24
|
* 自动匹配 dp 解析函数
|
|
19
25
|
*
|
|
@@ -37,6 +43,13 @@ export const autoDispatchTransDpFun = dpCode => {
|
|
|
37
43
|
return timerReportParser;
|
|
38
44
|
case scheduleDpCodes.WAKE_UP_MODE:
|
|
39
45
|
return getWakeUpParser();
|
|
46
|
+
// Beacon 设备专属 dp
|
|
47
|
+
case scheduleDpCodes.STRIP_LOCAL_TIMER:
|
|
48
|
+
return stripLocalTimerParser;
|
|
49
|
+
case scheduleDpCodes.BRIGHT_ADJUST_DATA:
|
|
50
|
+
return brightAdjustDataParser;
|
|
51
|
+
case scheduleDpCodes.COLOUR_DATA_RAW:
|
|
52
|
+
return colourDataRawParser;
|
|
40
53
|
default:
|
|
41
54
|
return null;
|
|
42
55
|
}
|
|
@@ -75,10 +75,13 @@ export class SleepSigmesh {
|
|
|
75
75
|
var _data$nodes$length, _data$nodes;
|
|
76
76
|
scheduleLogger.debug('Sigmesh dpParser ===> SleepSigmesh formatter: data', data);
|
|
77
77
|
// dataMode 可能是字符串 ('01'/'02'/'03') 或数字 (1/2/3)
|
|
78
|
-
|
|
79
|
-
// 使用 nodes.length 而非 data.length,因为调用方可能未更新 length 字段
|
|
78
|
+
typeof data.dataMode === 'string' ? parseInt(data.dataMode, 10) : data.dataMode; // 使用 nodes.length 而非 data.length,因为调用方可能未更新 length 字段
|
|
80
79
|
const nodeCount = (_data$nodes$length = (_data$nodes = data.nodes) === null || _data$nodes === void 0 ? void 0 : _data$nodes.length) !== null && _data$nodes$length !== void 0 ? _data$nodes$length : data.length;
|
|
81
|
-
|
|
80
|
+
// 版本号固定为 1, 与文档不一致,文档有问题
|
|
81
|
+
|
|
82
|
+
const result = [numToHexString(1), numToHexString(1),
|
|
83
|
+
// 数据模式固定为 1 也就是只支持白光,0x01:仅含BT 0x02:仅含HSV 0x03:含HSVBT
|
|
84
|
+
numToHexString(nodeCount)];
|
|
82
85
|
data.nodes.forEach(node => {
|
|
83
86
|
var _node$loops;
|
|
84
87
|
result.push(numToHexString(node.onOff ? 1 : 0), numToHexString(parseInt(node === null || node === void 0 || (_node$loops = node.loops) === null || _node$loops === void 0 || (_node$loops = _node$loops.split('')) === null || _node$loops === void 0 || (_node$loops = _node$loops.reverse()) === null || _node$loops === void 0 ? void 0 : _node$loops.join(''), 2)), numToHexString(node.step), numToHexString(node.hour), numToHexString(node.minute), numToHexString(node.brightness), numToHexString(node.temperature));
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 用法
|
|
3
|
+
* const stripLocalTimerTrans = new StripLocalTimerTransformer();
|
|
4
|
+
* // 解析dp
|
|
5
|
+
* const result = stripLocalTimerTrans.parser(dpStr);
|
|
6
|
+
* // 格式化
|
|
7
|
+
* const dpStr = stripLocalTimerTrans.formatter({xxx: xxx})
|
|
8
|
+
* */
|
|
9
|
+
import { Transformer } from '@ray-js/panel-sdk/lib/protocols/lamp/interface';
|
|
10
|
+
export type TStripLocalTimerData = {
|
|
11
|
+
timerId: number;
|
|
12
|
+
time: number;
|
|
13
|
+
loops: string;
|
|
14
|
+
power?: boolean;
|
|
15
|
+
status: boolean;
|
|
16
|
+
brightness?: number;
|
|
17
|
+
temperature?: number;
|
|
18
|
+
hue?: number;
|
|
19
|
+
saturation?: number;
|
|
20
|
+
value?: number;
|
|
21
|
+
mode: number;
|
|
22
|
+
dps: Record<string, any>;
|
|
23
|
+
speed?: number;
|
|
24
|
+
fanMode?: number;
|
|
25
|
+
direction?: number;
|
|
26
|
+
shake?: number;
|
|
27
|
+
sceneId?: number;
|
|
28
|
+
};
|
|
29
|
+
export declare class StripLocalTimerTransformer implements Transformer<TStripLocalTimerData> {
|
|
30
|
+
defaultValue: TStripLocalTimerData;
|
|
31
|
+
uuid: string;
|
|
32
|
+
constructor(uuid?: string, defaultValue?: TStripLocalTimerData);
|
|
33
|
+
equal(source: string, target: string): boolean;
|
|
34
|
+
parser(value: string): TStripLocalTimerData;
|
|
35
|
+
isUndefined(value: any): boolean;
|
|
36
|
+
to16(value: number, length?: number): string;
|
|
37
|
+
binTo16(bin: string, len?: number): string;
|
|
38
|
+
formatter(data: TStripLocalTimerData): string;
|
|
39
|
+
}
|
|
40
|
+
export declare const stripLocalTimerParser: StripLocalTimerTransformer;
|
|
41
|
+
export declare const getStripLocalTimerParser: () => StripLocalTimerTransformer;
|