@ray-js/lamp-schedule-core 1.0.0-beta-1

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.
Files changed (246) hide show
  1. package/README.md +565 -0
  2. package/lib/config/dpCodes.d.ts +27 -0
  3. package/lib/config/dpCodes.js +30 -0
  4. package/lib/config/index.d.ts +2 -0
  5. package/lib/config/index.js +2 -0
  6. package/lib/config/rhythms/defaultValue.d.ts +18 -0
  7. package/lib/config/rhythms/defaultValue.js +72 -0
  8. package/lib/config/rhythms/index.d.ts +10 -0
  9. package/lib/config/rhythms/index.js +35 -0
  10. package/lib/conflict/ConflictResolver.d.ts +2 -0
  11. package/lib/conflict/ConflictResolver.js +284 -0
  12. package/lib/conflict/__test__/ConflictResolver.test.d.ts +1 -0
  13. package/lib/conflict/__test__/ConflictResolver.test.js +183 -0
  14. package/lib/conflict/__test__/index.test.d.ts +1 -0
  15. package/lib/conflict/__test__/index.test.js +385 -0
  16. package/lib/conflict/__test__/scheduleDataManager.test.d.ts +1 -0
  17. package/lib/conflict/__test__/scheduleDataManager.test.js +170 -0
  18. package/lib/conflict/__test__/transform.test.d.ts +1 -0
  19. package/lib/conflict/__test__/transform.test.js +454 -0
  20. package/lib/conflict/__test__/updateDeviceDp.d.ts +1 -0
  21. package/lib/conflict/__test__/updateDeviceDp.js +114 -0
  22. package/lib/conflict/index.d.ts +42 -0
  23. package/lib/conflict/index.js +103 -0
  24. package/lib/conflict/scheduleDataManager.d.ts +12 -0
  25. package/lib/conflict/scheduleDataManager.js +79 -0
  26. package/lib/conflict/transform.d.ts +71 -0
  27. package/lib/conflict/transform.js +251 -0
  28. package/lib/conflict/type.d.ts +55 -0
  29. package/lib/conflict/type.js +17 -0
  30. package/lib/conflict/updateDeviceDp.d.ts +1 -0
  31. package/lib/conflict/updateDeviceDp.js +41 -0
  32. package/lib/constant/index.d.ts +5 -0
  33. package/lib/constant/index.js +5 -0
  34. package/lib/context/index.d.ts +3 -0
  35. package/lib/context/index.js +3 -0
  36. package/lib/context/rhythms/actions.d.ts +20 -0
  37. package/lib/context/rhythms/actions.js +52 -0
  38. package/lib/context/rhythms/index.d.ts +5 -0
  39. package/lib/context/rhythms/index.js +51 -0
  40. package/lib/context/rhythms/reducer.d.ts +24 -0
  41. package/lib/context/rhythms/reducer.js +38 -0
  42. package/lib/context/schedule/actions.d.ts +7 -0
  43. package/lib/context/schedule/actions.js +51 -0
  44. package/lib/context/schedule/context.d.ts +6 -0
  45. package/lib/context/schedule/context.js +52 -0
  46. package/lib/context/schedule/index.d.ts +1 -0
  47. package/lib/context/schedule/index.js +1 -0
  48. package/lib/context/schedule/reducer.d.ts +16 -0
  49. package/lib/context/schedule/reducer.js +104 -0
  50. package/lib/context/schedule/type.d.ts +41 -0
  51. package/lib/context/schedule/type.js +11 -0
  52. package/lib/context/timer/actions.d.ts +8 -0
  53. package/lib/context/timer/actions.js +52 -0
  54. package/lib/context/timer/context.d.ts +10 -0
  55. package/lib/context/timer/context.js +53 -0
  56. package/lib/context/timer/index.d.ts +1 -0
  57. package/lib/context/timer/index.js +1 -0
  58. package/lib/context/timer/reducer.d.ts +15 -0
  59. package/lib/context/timer/reducer.js +70 -0
  60. package/lib/context/timer/type.d.ts +46 -0
  61. package/lib/context/timer/type.js +24 -0
  62. package/lib/dpParser/README.md +63 -0
  63. package/lib/dpParser/__test__/cycle.test.d.ts +1 -0
  64. package/lib/dpParser/__test__/cycle.test.js +258 -0
  65. package/lib/dpParser/__test__/random.test.d.ts +1 -0
  66. package/lib/dpParser/__test__/random.test.js +211 -0
  67. package/lib/dpParser/__test__/rhythms.test.d.ts +1 -0
  68. package/lib/dpParser/__test__/rhythms.test.js +71 -0
  69. package/lib/dpParser/__test__/rtcTimer.test.d.ts +1 -0
  70. package/lib/dpParser/__test__/rtcTimer.test.js +235 -0
  71. package/lib/dpParser/__test__/sleep.test.d.ts +1 -0
  72. package/lib/dpParser/__test__/sleep.test.js +71 -0
  73. package/lib/dpParser/__test__/sleepCommon.test.d.ts +1 -0
  74. package/lib/dpParser/__test__/sleepCommon.test.js +197 -0
  75. package/lib/dpParser/__test__/timerReport.test.d.ts +1 -0
  76. package/lib/dpParser/__test__/timerReport.test.js +100 -0
  77. package/lib/dpParser/__test__/wakeup.test.d.ts +1 -0
  78. package/lib/dpParser/__test__/wakeup.test.js +69 -0
  79. package/lib/dpParser/__test__/wakeupCommon.test.d.ts +1 -0
  80. package/lib/dpParser/__test__/wakeupCommon.test.js +131 -0
  81. package/lib/dpParser/cycle/index.d.ts +15 -0
  82. package/lib/dpParser/cycle/index.js +134 -0
  83. package/lib/dpParser/index.d.ts +23 -0
  84. package/lib/dpParser/index.js +43 -0
  85. package/lib/dpParser/random/index.d.ts +15 -0
  86. package/lib/dpParser/random/index.js +127 -0
  87. package/lib/dpParser/rhythms.d.ts +41 -0
  88. package/lib/dpParser/rhythms.js +116 -0
  89. package/lib/dpParser/rtcTimer.d.ts +17 -0
  90. package/lib/dpParser/rtcTimer.js +300 -0
  91. package/lib/dpParser/sleep/index.d.ts +9 -0
  92. package/lib/dpParser/sleep/index.js +29 -0
  93. package/lib/dpParser/sleep/sleepCommon.d.ts +11 -0
  94. package/lib/dpParser/sleep/sleepCommon.js +117 -0
  95. package/lib/dpParser/sleep/sleepSigmesh.d.ts +0 -0
  96. package/lib/dpParser/sleep/sleepSigmesh.js +101 -0
  97. package/lib/dpParser/timerReport.d.ts +11 -0
  98. package/lib/dpParser/timerReport.js +43 -0
  99. package/lib/dpParser/utils.d.ts +27 -0
  100. package/lib/dpParser/utils.js +53 -0
  101. package/lib/dpParser/wakeup/index.d.ts +10 -0
  102. package/lib/dpParser/wakeup/index.js +34 -0
  103. package/lib/dpParser/wakeup/wakeupCommon.d.ts +11 -0
  104. package/lib/dpParser/wakeup/wakeupCommon.js +106 -0
  105. package/lib/dpParser/wakeup/wakeupSigmesh.d.ts +15 -0
  106. package/lib/dpParser/wakeup/wakeupSigmesh.js +86 -0
  107. package/lib/hooks/__test__/useCommon.test.d.ts +1 -0
  108. package/lib/hooks/__test__/useCommon.test.js +72 -0
  109. package/lib/hooks/__test__/useCountdownDp.test.d.ts +1 -0
  110. package/lib/hooks/__test__/useCountdownDp.test.js +82 -0
  111. package/lib/hooks/__test__/useCycleDp.test.d.ts +1 -0
  112. package/lib/hooks/__test__/useCycleDp.test.js +92 -0
  113. package/lib/hooks/__test__/useRandomDp.test.d.ts +1 -0
  114. package/lib/hooks/__test__/useRandomDp.test.js +88 -0
  115. package/lib/hooks/__test__/useRhythmsDp.test.d.ts +1 -0
  116. package/lib/hooks/__test__/useRhythmsDp.test.js +81 -0
  117. package/lib/hooks/__test__/useSleepDp.test.d.ts +1 -0
  118. package/lib/hooks/__test__/useSleepDp.test.js +127 -0
  119. package/lib/hooks/__test__/useTimeFlush.test.d.ts +1 -0
  120. package/lib/hooks/__test__/useTimeFlush.test.js +109 -0
  121. package/lib/hooks/__test__/useTimerDp.test.d.ts +1 -0
  122. package/lib/hooks/__test__/useTimerDp.test.js +79 -0
  123. package/lib/hooks/__test__/useTimerOperate.test.d.ts +1 -0
  124. package/lib/hooks/__test__/useTimerOperate.test.js +286 -0
  125. package/lib/hooks/__test__/useTimerOperateCloud.test.d.ts +1 -0
  126. package/lib/hooks/__test__/useTimerOperateCloud.test.js +190 -0
  127. package/lib/hooks/__test__/useTimerOperateLocal.test.d.ts +1 -0
  128. package/lib/hooks/__test__/useTimerOperateLocal.test.js +216 -0
  129. package/lib/hooks/__test__/useTimerReportDp.test.d.ts +1 -0
  130. package/lib/hooks/__test__/useTimerReportDp.test.js +93 -0
  131. package/lib/hooks/__test__/useTimerSupport.test.d.ts +1 -0
  132. package/lib/hooks/__test__/useTimerSupport.test.js +110 -0
  133. package/lib/hooks/__test__/useWakeUpDp.test.d.ts +1 -0
  134. package/lib/hooks/__test__/useWakeUpDp.test.js +129 -0
  135. package/lib/hooks/useBaseLightDp.d.ts +21 -0
  136. package/lib/hooks/useBaseLightDp.js +165 -0
  137. package/lib/hooks/useCommon.d.ts +29 -0
  138. package/lib/hooks/useCommon.js +59 -0
  139. package/lib/hooks/useCommonSupport.d.ts +25 -0
  140. package/lib/hooks/useCommonSupport.js +241 -0
  141. package/lib/hooks/useCountdownDp.d.ts +13 -0
  142. package/lib/hooks/useCountdownDp.js +28 -0
  143. package/lib/hooks/useCountdownSupport.d.ts +9 -0
  144. package/lib/hooks/useCountdownSupport.js +13 -0
  145. package/lib/hooks/useCycleDp.d.ts +7 -0
  146. package/lib/hooks/useCycleDp.js +21 -0
  147. package/lib/hooks/useCycleSupport.d.ts +12 -0
  148. package/lib/hooks/useCycleSupport.js +16 -0
  149. package/lib/hooks/useRandomDp.d.ts +7 -0
  150. package/lib/hooks/useRandomDp.js +21 -0
  151. package/lib/hooks/useRandomSupport.d.ts +12 -0
  152. package/lib/hooks/useRandomSupport.js +16 -0
  153. package/lib/hooks/useRhythmsDp.d.ts +7 -0
  154. package/lib/hooks/useRhythmsDp.js +23 -0
  155. package/lib/hooks/useSleepDp.d.ts +6 -0
  156. package/lib/hooks/useSleepDp.js +21 -0
  157. package/lib/hooks/useSleepSupport.d.ts +8 -0
  158. package/lib/hooks/useSleepSupport.js +13 -0
  159. package/lib/hooks/useTimeFlush.d.ts +8 -0
  160. package/lib/hooks/useTimeFlush.js +31 -0
  161. package/lib/hooks/useTimerDp.d.ts +5 -0
  162. package/lib/hooks/useTimerDp.js +25 -0
  163. package/lib/hooks/useTimerFlushList.d.ts +11 -0
  164. package/lib/hooks/useTimerFlushList.js +53 -0
  165. package/lib/hooks/useTimerOperate.d.ts +68 -0
  166. package/lib/hooks/useTimerOperate.js +403 -0
  167. package/lib/hooks/useTimerOperateCloud.d.ts +31 -0
  168. package/lib/hooks/useTimerOperateCloud.js +233 -0
  169. package/lib/hooks/useTimerOperateLocal.d.ts +40 -0
  170. package/lib/hooks/useTimerOperateLocal.js +310 -0
  171. package/lib/hooks/useTimerReportDp.d.ts +15 -0
  172. package/lib/hooks/useTimerReportDp.js +48 -0
  173. package/lib/hooks/useTimerSupport.d.ts +13 -0
  174. package/lib/hooks/useTimerSupport.js +38 -0
  175. package/lib/hooks/useWakeUpDp.d.ts +6 -0
  176. package/lib/hooks/useWakeUpDp.js +21 -0
  177. package/lib/hooks/useWakeUpSupport.d.ts +8 -0
  178. package/lib/hooks/useWakeUpSupport.js +13 -0
  179. package/lib/hooks/useWakeupDp.d.ts +6 -0
  180. package/lib/hooks/useWakeupDp.js +21 -0
  181. package/lib/hooks/useWakeupSupport.d.ts +8 -0
  182. package/lib/hooks/useWakeupSupport.js +13 -0
  183. package/lib/i18n/index.d.ts +142 -0
  184. package/lib/i18n/index.js +7 -0
  185. package/lib/i18n/rhythms.d.ts +73 -0
  186. package/lib/i18n/rhythms.js +72 -0
  187. package/lib/i18n/strings.d.ts +73 -0
  188. package/lib/i18n/strings.js +6 -0
  189. package/lib/index.d.ts +51 -0
  190. package/lib/index.js +64 -0
  191. package/lib/types/countdown.d.ts +3 -0
  192. package/lib/types/countdown.js +1 -0
  193. package/lib/types/cycle.d.ts +22 -0
  194. package/lib/types/cycle.js +1 -0
  195. package/lib/types/global.d.ts +9 -0
  196. package/lib/types/index.d.ts +331 -0
  197. package/lib/types/index.js +76 -0
  198. package/lib/types/random.d.ts +20 -0
  199. package/lib/types/random.js +1 -0
  200. package/lib/types/rhythms.d.ts +79 -0
  201. package/lib/types/rhythms.js +15 -0
  202. package/lib/types/sleep.d.ts +36 -0
  203. package/lib/types/sleep.js +1 -0
  204. package/lib/types/timer.d.ts +107 -0
  205. package/lib/types/timer.js +1 -0
  206. package/lib/types/wakeup.d.ts +38 -0
  207. package/lib/types/wakeup.js +1 -0
  208. package/lib/utils/ScheduleCache.d.ts +19 -0
  209. package/lib/utils/ScheduleCache.js +39 -0
  210. package/lib/utils/ScheduleCloudProperty.d.ts +75 -0
  211. package/lib/utils/ScheduleCloudProperty.js +220 -0
  212. package/lib/utils/ScheduleDataSync.d.ts +82 -0
  213. package/lib/utils/ScheduleDataSync.js +127 -0
  214. package/lib/utils/ScheduleEmit.d.ts +67 -0
  215. package/lib/utils/ScheduleEmit.js +61 -0
  216. package/lib/utils/ScheduleLogger.d.ts +19 -0
  217. package/lib/utils/ScheduleLogger.js +71 -0
  218. package/lib/utils/ScheduleSupport.d.ts +131 -0
  219. package/lib/utils/ScheduleSupport.js +373 -0
  220. package/lib/utils/ScheduleUtils.d.ts +12 -0
  221. package/lib/utils/ScheduleUtils.js +51 -0
  222. package/lib/utils/__test__/ScheduleCloudProperty.test.d.ts +1 -0
  223. package/lib/utils/__test__/ScheduleCloudProperty.test.js +320 -0
  224. package/lib/utils/__test__/ScheduleSupport.test.d.ts +1 -0
  225. package/lib/utils/__test__/ScheduleSupport.test.js +211 -0
  226. package/lib/utils/__test__/ScheduleUtils.test.d.ts +1 -0
  227. package/lib/utils/__test__/ScheduleUtils.test.js +119 -0
  228. package/lib/utils/__test__/common.test.d.ts +1 -0
  229. package/lib/utils/__test__/common.test.js +147 -0
  230. package/lib/utils/__test__/storage.test.d.ts +1 -0
  231. package/lib/utils/__test__/storage.test.js +98 -0
  232. package/lib/utils/__test__/time.test.d.ts +1 -0
  233. package/lib/utils/__test__/time.test.js +146 -0
  234. package/lib/utils/common.d.ts +23 -0
  235. package/lib/utils/common.js +109 -0
  236. package/lib/utils/dpState.d.ts +5 -0
  237. package/lib/utils/dpState.js +27 -0
  238. package/lib/utils/getCachedSystemInfo.d.ts +39 -0
  239. package/lib/utils/getCachedSystemInfo.js +20 -0
  240. package/lib/utils/isInIDE.d.ts +1 -0
  241. package/lib/utils/isInIDE.js +5 -0
  242. package/lib/utils/storage.d.ts +5 -0
  243. package/lib/utils/storage.js +32 -0
  244. package/lib/utils/time.d.ts +40 -0
  245. package/lib/utils/time.js +84 -0
  246. package/package.json +78 -0
@@ -0,0 +1,93 @@
1
+ import { renderHook, act } from '@testing-library/react-hooks';
2
+ import { useTimerReportDp, useTimerReportDpPull } from '../useTimerReportDp';
3
+ import { useBaseLightDp, useFetchDpDataByMesh } from '../useBaseLightDp';
4
+ import { useSupport } from '../useCommonSupport';
5
+ import { scheduleDpCodes } from '../../config/dpCodes';
6
+ import { timerReportParser } from '../../dpParser';
7
+ import { scheduleLogger } from '../../utils/ScheduleLogger';
8
+ // Mock dependencies
9
+ jest.mock('../useBaseLightDp');
10
+ jest.mock('../useCommonSupport');
11
+ jest.mock('../../dpParser');
12
+ jest.mock('../../utils/ScheduleLogger');
13
+ describe('useTimerReportDp', () => {
14
+ const mockDpValue = [{
15
+ id: '1',
16
+ status: true
17
+ }];
18
+ beforeEach(() => {
19
+ jest.clearAllMocks();
20
+ useBaseLightDp.mockReturnValue({
21
+ dpValue: mockDpValue,
22
+ updateDp: jest.fn()
23
+ });
24
+ useSupport.mockReturnValue({
25
+ isSupportDp: jest.fn().mockReturnValue(true)
26
+ });
27
+ timerReportParser.formatter.mockImplementation(data => data);
28
+ timerReportParser.parser.mockImplementation(data => data);
29
+ });
30
+ it('should return correct initial values', () => {
31
+ const {
32
+ result
33
+ } = renderHook(() => useTimerReportDp());
34
+ expect(result.current.isSupport).toBe(true);
35
+ expect(result.current.dpValue).toEqual(mockDpValue);
36
+ expect(typeof result.current.updateDp).toBe('function');
37
+ });
38
+ it('should call updateDp with formatted data', () => {
39
+ const mockUpdateDp = jest.fn();
40
+ useBaseLightDp.mockReturnValue({
41
+ dpValue: mockDpValue,
42
+ updateDp: mockUpdateDp
43
+ });
44
+ const {
45
+ result
46
+ } = renderHook(() => useTimerReportDp());
47
+ act(() => {
48
+ result.current.updateDp(mockDpValue);
49
+ });
50
+ expect(timerReportParser.formatter).toHaveBeenCalledWith(mockDpValue);
51
+ expect(mockUpdateDp).toHaveBeenCalledWith(mockDpValue);
52
+ });
53
+ it('should parse string dpValue correctly', () => {
54
+ const stringDpValue = JSON.stringify(mockDpValue);
55
+ useBaseLightDp.mockReturnValue({
56
+ dpValue: stringDpValue,
57
+ updateDp: jest.fn()
58
+ });
59
+ const {
60
+ result
61
+ } = renderHook(() => useTimerReportDp());
62
+ expect(timerReportParser.parser).toHaveBeenCalledWith(stringDpValue);
63
+ });
64
+ });
65
+ describe('useTimerReportDpPull', () => {
66
+ const mockRefresh = jest.fn();
67
+ beforeEach(() => {
68
+ jest.clearAllMocks();
69
+ useFetchDpDataByMesh.mockReturnValue({
70
+ refresh: mockRefresh
71
+ });
72
+ });
73
+ it('should return refresh function', () => {
74
+ const {
75
+ result
76
+ } = renderHook(() => useTimerReportDpPull());
77
+ expect(typeof result.current.refresh).toBe('function');
78
+ expect(scheduleLogger.debug).toHaveBeenCalledWith('useTimerReportDpPull 执行');
79
+ });
80
+ it('should call refresh when refresh function is called', () => {
81
+ const {
82
+ result
83
+ } = renderHook(() => useTimerReportDpPull());
84
+ act(() => {
85
+ result.current.refresh();
86
+ });
87
+ expect(mockRefresh).toHaveBeenCalled();
88
+ });
89
+ it('should use correct dpCode', () => {
90
+ renderHook(() => useTimerReportDpPull());
91
+ expect(useFetchDpDataByMesh).toHaveBeenCalledWith([scheduleDpCodes.TIMER_REPORT]);
92
+ });
93
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,110 @@
1
+ import { renderHook } from '@testing-library/react-hooks';
2
+ import { useSupportLocalTimer, useSupportCloudTimer, useTimerSupport } from '../useTimerSupport';
3
+ import { useCommonSupport, useSupport } from '../useCommonSupport';
4
+ import { scheduleDpCodes } from '../../config/dpCodes';
5
+
6
+ // Mock dependencies
7
+ jest.mock('../useCommonSupport');
8
+ describe('useTimerSupport Hooks', () => {
9
+ beforeEach(() => {
10
+ jest.clearAllMocks();
11
+ });
12
+ describe('useSupportLocalTimer', () => {
13
+ it('should return correct support status for non-group device', () => {
14
+ useCommonSupport.mockReturnValue({
15
+ isReady: true,
16
+ isSupport: true
17
+ });
18
+ const {
19
+ result
20
+ } = renderHook(() => useSupportLocalTimer());
21
+ expect(result.current).toEqual({
22
+ isReady: true,
23
+ isSupport: true
24
+ });
25
+ expect(useCommonSupport).toHaveBeenCalledWith([scheduleDpCodes.LOCAL_TIMER, scheduleDpCodes.RTC_TIMER, scheduleDpCodes.STRIP_LOCAL_TIMER], []);
26
+ });
27
+ it('should return false support for group device', () => {
28
+ useSupport.mockReturnValue({
29
+ isGroupDevice: () => true
30
+ });
31
+ useCommonSupport.mockReturnValue({
32
+ isReady: true,
33
+ isSupport: true
34
+ });
35
+ const {
36
+ result
37
+ } = renderHook(() => useSupportLocalTimer());
38
+ expect(result.current).toEqual({
39
+ isReady: true,
40
+ isSupport: false
41
+ });
42
+ });
43
+ it('should handle custom dpCodeList', () => {
44
+ const customDpCodeList = ['custom_dp_1', 'custom_dp_2'];
45
+ useSupport.mockReturnValue({
46
+ isGroupDevice: () => false
47
+ });
48
+ useCommonSupport.mockReturnValue({
49
+ isReady: true,
50
+ isSupport: true
51
+ });
52
+ renderHook(() => useSupportLocalTimer(customDpCodeList));
53
+ expect(useCommonSupport).toHaveBeenCalledWith([scheduleDpCodes.LOCAL_TIMER, scheduleDpCodes.RTC_TIMER, scheduleDpCodes.STRIP_LOCAL_TIMER], customDpCodeList);
54
+ });
55
+ });
56
+ describe('useSupportCloudTimer', () => {
57
+ it('should return cloud timer support status', () => {
58
+ useSupport.mockReturnValue({
59
+ isSupportCloudTimer: () => true
60
+ });
61
+ const {
62
+ result
63
+ } = renderHook(() => useSupportCloudTimer());
64
+ expect(result.current).toBe(true);
65
+ });
66
+ it('should return false when cloud timer is not supported', () => {
67
+ useSupport.mockReturnValue({
68
+ isSupportCloudTimer: () => false
69
+ });
70
+ const {
71
+ result
72
+ } = renderHook(() => useSupportCloudTimer());
73
+ expect(result.current).toBe(false);
74
+ });
75
+ });
76
+ describe('useTimerSupport', () => {
77
+ it('should return true when either local or cloud timer is supported', () => {
78
+ useSupport.mockReturnValue({
79
+ isGroupDevice: () => false,
80
+ isSupportCloudTimer: () => true
81
+ });
82
+ useCommonSupport.mockReturnValue({
83
+ isReady: true,
84
+ isSupport: true
85
+ });
86
+ const {
87
+ result
88
+ } = renderHook(() => useTimerSupport());
89
+ expect(result.current).toEqual({
90
+ isSupport: true
91
+ });
92
+ });
93
+ it('should return false when neither local nor cloud timer is supported', () => {
94
+ useSupport.mockReturnValue({
95
+ isGroupDevice: () => true,
96
+ isSupportCloudTimer: () => false
97
+ });
98
+ useCommonSupport.mockReturnValue({
99
+ isReady: true,
100
+ isSupport: true
101
+ });
102
+ const {
103
+ result
104
+ } = renderHook(() => useTimerSupport());
105
+ expect(result.current).toEqual({
106
+ isSupport: false
107
+ });
108
+ });
109
+ });
110
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,129 @@
1
+ import { renderHook, act } from '@testing-library/react-hooks';
2
+ import { useWakeUpDp } from '../useWakeUpDp';
3
+ import { useBaseLightDp } from '../useBaseLightDp';
4
+ import { scheduleDpCodes } from '../../config/dpCodes';
5
+ import { getWakeUpParser } from '../../dpParser/wakeup';
6
+ // Mock dependencies
7
+ jest.mock('../useBaseLightDp');
8
+ jest.mock('../../dpParser/wakeup');
9
+ describe('useWakeUpDp', () => {
10
+ const mockWakeUpData = {
11
+ version: 1,
12
+ number: 1,
13
+ nodes: [{
14
+ onOff: true,
15
+ loops: '0000000',
16
+ step: 1,
17
+ hour: 8,
18
+ minute: 0,
19
+ hue: 0,
20
+ saturation: 100,
21
+ value: 100,
22
+ brightness: 100,
23
+ temperature: 5000,
24
+ duration: 1,
25
+ index: 0,
26
+ time: '08:00'
27
+ }]
28
+ };
29
+ const mockWakeUpDataSigmesh = {
30
+ version: 1,
31
+ dataMode: '01',
32
+ length: 1,
33
+ nodes: [{
34
+ onOff: true,
35
+ loops: '0000000',
36
+ step: 1,
37
+ hour: 8,
38
+ minute: 0,
39
+ brightness: 100,
40
+ temperature: 5000,
41
+ duration: 1,
42
+ index: 0,
43
+ time: '08:00'
44
+ }]
45
+ };
46
+ const mockParser = {
47
+ formatter: jest.fn(),
48
+ parser: jest.fn()
49
+ };
50
+ beforeEach(() => {
51
+ jest.clearAllMocks();
52
+ useBaseLightDp.mockReturnValue({
53
+ dpValue: mockWakeUpData,
54
+ updateDp: jest.fn()
55
+ });
56
+ getWakeUpParser.mockReturnValue(mockParser);
57
+ mockParser.formatter.mockImplementation(data => data);
58
+ mockParser.parser.mockImplementation(data => data);
59
+ });
60
+ it('should return correct initial values with TWakeUpData', () => {
61
+ const {
62
+ result
63
+ } = renderHook(() => useWakeUpDp());
64
+ expect(result.current.dpValue).toEqual(mockWakeUpData);
65
+ expect(typeof result.current.updateDp).toBe('function');
66
+ });
67
+ it('should return correct initial values with TWakeUpDataSigmesh', () => {
68
+ useBaseLightDp.mockReturnValue({
69
+ dpValue: mockWakeUpDataSigmesh,
70
+ updateDp: jest.fn()
71
+ });
72
+ const {
73
+ result
74
+ } = renderHook(() => useWakeUpDp());
75
+ expect(result.current.dpValue).toEqual(mockWakeUpDataSigmesh);
76
+ expect(typeof result.current.updateDp).toBe('function');
77
+ });
78
+ it('should call updateDp with formatted data for TWakeUpData', () => {
79
+ const mockUpdateDp = jest.fn();
80
+ useBaseLightDp.mockReturnValue({
81
+ dpValue: mockWakeUpData,
82
+ updateDp: mockUpdateDp
83
+ });
84
+ const {
85
+ result
86
+ } = renderHook(() => useWakeUpDp());
87
+ act(() => {
88
+ result.current.updateDp(mockWakeUpData);
89
+ });
90
+ expect(mockParser.formatter).toHaveBeenCalledWith(mockWakeUpData);
91
+ expect(mockUpdateDp).toHaveBeenCalledWith(mockWakeUpData);
92
+ });
93
+ it('should call updateDp with formatted data for TWakeUpDataSigmesh', () => {
94
+ const mockUpdateDp = jest.fn();
95
+ useBaseLightDp.mockReturnValue({
96
+ dpValue: mockWakeUpDataSigmesh,
97
+ updateDp: mockUpdateDp
98
+ });
99
+ const {
100
+ result
101
+ } = renderHook(() => useWakeUpDp());
102
+ act(() => {
103
+ result.current.updateDp(mockWakeUpDataSigmesh);
104
+ });
105
+ expect(mockParser.formatter).toHaveBeenCalledWith(mockWakeUpDataSigmesh);
106
+ expect(mockUpdateDp).toHaveBeenCalledWith(mockWakeUpDataSigmesh);
107
+ });
108
+ it('should parse string dpValue correctly', () => {
109
+ const stringDpValue = JSON.stringify(mockWakeUpData);
110
+ useBaseLightDp.mockReturnValue({
111
+ dpValue: stringDpValue,
112
+ updateDp: jest.fn()
113
+ });
114
+ const {
115
+ result
116
+ } = renderHook(() => useWakeUpDp());
117
+ expect(mockParser.parser).toHaveBeenCalledWith(stringDpValue);
118
+ expect(result.current.dpValue).toEqual(JSON.stringify(mockWakeUpData));
119
+ });
120
+ it('should use correct dpCode', () => {
121
+ renderHook(() => useWakeUpDp());
122
+ expect(useBaseLightDp).toHaveBeenCalledWith(scheduleDpCodes.WAKE_UP_MODE);
123
+ });
124
+ it('should handle custom dpCode', () => {
125
+ const customDpCode = scheduleDpCodes.WAKE_UP_MODE;
126
+ renderHook(() => useWakeUpDp(customDpCode));
127
+ expect(useBaseLightDp).toHaveBeenCalledWith(customDpCode);
128
+ });
129
+ });
@@ -0,0 +1,21 @@
1
+ import { DpValue } from '../types';
2
+ type TDpRes<T> = {
3
+ dpValue: T | null;
4
+ /**
5
+ * 更新 dp 函数
6
+ * @param value dp 值
7
+ * @param errCallback 错误回调
8
+ */
9
+ updateDp: (value: DpValue, errCallback?: (err: Error) => void) => void;
10
+ };
11
+ export declare function useBaseLightDp<T>(dpCode: string, defaultDpValue?: T): TDpRes<T>;
12
+ export declare const getDpDataByMesh: (dpCodes?: string[]) => void;
13
+ /**
14
+ * 主动拉取 dp 数据
15
+ * @param dpCodes dpCode 数组
16
+ * @returns refresh 刷新 dp 数据
17
+ */
18
+ export declare const useFetchDpDataByMesh: (dpCodes: string[]) => {
19
+ refresh: () => void;
20
+ };
21
+ export {};
@@ -0,0 +1,165 @@
1
+ import "core-js/modules/esnext.iterator.constructor.js";
2
+ import "core-js/modules/esnext.iterator.filter.js";
3
+ import "core-js/modules/esnext.iterator.map.js";
4
+ /* eslint-disable no-console */
5
+ import { useState, useEffect, useCallback, useRef } from 'react';
6
+ import { isEqual } from 'lodash-es';
7
+ import { queryDps } from '@ray-js/ray';
8
+ import { scheduleLogger } from '../utils/ScheduleLogger';
9
+ import { devIdOrGroupIdCache } from '../utils/ScheduleCache';
10
+ import { updateDeviceDp } from '../conflict/updateDeviceDp';
11
+ import { isInitFn, useSupport } from '../hooks/useCommonSupport';
12
+ import { getDpIdByDpCode } from '../utils/ScheduleUtils';
13
+ import { emitter } from '../utils/ScheduleEmit';
14
+ import { DP_CHANGE_EVENT_KEY } from '../constant';
15
+ import { getDpState, setDpState } from '../utils/dpState';
16
+ export function useBaseLightDp(dpCode, defaultDpValue) {
17
+ const {
18
+ devId: deviceId,
19
+ groupId
20
+ } = devIdOrGroupIdCache.get();
21
+ const [dpValue, setDpValue] = useState(defaultDpValue !== null && defaultDpValue !== void 0 ? defaultDpValue : null);
22
+ const isInit = isInitFn();
23
+ const preDpValue = useRef(null);
24
+ const callback = useCallback(dpData => {
25
+ if (!isInit) {
26
+ scheduleLogger.warn('useBaseLightDp callback is not init');
27
+ return;
28
+ }
29
+ let dpId = dpCode;
30
+ // eslint-disable-next-line no-self-compare
31
+ if (+dpCode !== +dpCode) {
32
+ dpId = getDpIdByDpCode(dpCode);
33
+ }
34
+ if (dpData.deviceId === deviceId && dpId in dpData.dps) {
35
+ scheduleLogger.debug(`${dpCode} ==> emitter will changed:`, dpData);
36
+ const _dpValue = dpData.dps[dpId];
37
+ if (isEqual(preDpValue.current, _dpValue)) {
38
+ scheduleLogger.warn(`emitter 重复触发 ${DP_CHANGE_EVENT_KEY}, 已过滤`, dpData);
39
+ return;
40
+ }
41
+ scheduleLogger.debug(`${dpCode} ==> emitter changed:`, preDpValue.current, _dpValue);
42
+ preDpValue.current = _dpValue;
43
+ setDpState(dpCode, _dpValue);
44
+ setDpValue(_dpValue);
45
+ }
46
+ }, [deviceId, groupId, isInit, dpCode]);
47
+ const fetchRef = useRef(false);
48
+ useEffect(() => {
49
+ emitter.off(DP_CHANGE_EVENT_KEY, callback);
50
+ emitter.on(DP_CHANGE_EVENT_KEY, callback);
51
+ return () => {
52
+ scheduleLogger.warn(`${DP_CHANGE_EVENT_KEY} off`);
53
+ emitter.off(DP_CHANGE_EVENT_KEY, callback);
54
+ };
55
+ }, [deviceId, groupId, isInit, dpCode]);
56
+
57
+ // 获取设备类型和dp值
58
+ useEffect(() => {
59
+ if (!isInit) {
60
+ return;
61
+ }
62
+ // 首次进入拉取一次, 后续通过事件获取最新的 dp 数据
63
+ if (fetchRef.current) {
64
+ return;
65
+ }
66
+ fetchRef.current = true;
67
+ (async () => {
68
+ const dpValue = getDpState(dpCode);
69
+ fetchRef.current = true;
70
+ dpValue !== undefined && setDpValue(dpValue);
71
+ })();
72
+ }, [deviceId, groupId, dpCode, isInit]);
73
+
74
+ // 更新dp值
75
+
76
+ return {
77
+ dpValue,
78
+ updateDp: (value, errCallback) => {
79
+ try {
80
+ const dpId = getDpIdByDpCode(dpCode);
81
+ if (!dpId) {
82
+ scheduleLogger.error('updateDp error: ', dpCode, '未匹配到 dpId');
83
+ return;
84
+ }
85
+ const dps = {
86
+ [dpId]: value
87
+ };
88
+ scheduleLogger.debug('updateDp dps:', dps);
89
+ updateDeviceDp(deviceId, groupId, dps);
90
+ } catch (error) {
91
+ scheduleLogger.error('Failed to update dp:', error);
92
+ errCallback && errCallback(error);
93
+ }
94
+ }
95
+ };
96
+ }
97
+
98
+ // 查询 mesh 设备的 DP
99
+ export const getDpDataByMesh = function () {
100
+ let dpCodes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
101
+ if (!Array.isArray(dpCodes)) {
102
+ scheduleLogger.error('getDpDataByMesh: 参数dpCodes必须是数组');
103
+ return;
104
+ }
105
+ if (dpCodes.length >= 5) {
106
+ scheduleLogger.warn('getDpDataByMesh: 单次查询 dp 数过多,dp 可能响应不及时,请分次查询');
107
+ }
108
+ scheduleLogger.debug('getDpDataByMesh 开始查询DP参数 dpCodes:', dpCodes);
109
+ const deviceData = devIdOrGroupIdCache.get();
110
+ const deviceId = deviceData === null || deviceData === void 0 ? void 0 : deviceData.devId;
111
+ if (!deviceId) {
112
+ scheduleLogger.error('getDpDataByMesh: 未能获取到deviceId');
113
+ return;
114
+ }
115
+ const dpIds = dpCodes.map(item => getDpIdByDpCode(item)).filter(i => !!i).map(String); // 简化字符串转换
116
+
117
+ if (dpIds.length === 0) {
118
+ scheduleLogger.warn('getDpDataByMesh', dpCodes, '未匹配到 dp');
119
+ return;
120
+ }
121
+ scheduleLogger.debug('getDpDataByMesh 查询DP转换后参数 dpIds:', dpIds);
122
+ try {
123
+ queryDps({
124
+ deviceId,
125
+ dpIds,
126
+ success: e => {
127
+ scheduleLogger.debug('getDpDataByMesh 查询DP参数 success:', e);
128
+ },
129
+ fail: err => {
130
+ scheduleLogger.warn('getDpDataByMesh 查询DP参数 fail:', err);
131
+ }
132
+ });
133
+ } catch (error) {
134
+ scheduleLogger.error('getDpDataByMesh 调用失败:', error);
135
+ }
136
+ };
137
+ /**
138
+ * 主动拉取 dp 数据
139
+ * @param dpCodes dpCode 数组
140
+ * @returns refresh 刷新 dp 数据
141
+ */
142
+ export const useFetchDpDataByMesh = dpCodes => {
143
+ const support = useSupport();
144
+ const getDpDataByMeshFn = () => {
145
+ const isSigMeshDevice = support === null || support === void 0 ? void 0 : support.isSigMeshDevice();
146
+ if (!isSigMeshDevice) {
147
+ scheduleLogger.info('useFetchDpDataByMesh 当前设备为', support === null || support === void 0 ? void 0 : support.deviceType, ' 只支持 sigmesh 设备');
148
+ return;
149
+ }
150
+ scheduleLogger.debug('getDpDataByMeshFn get:', dpCodes);
151
+ getDpDataByMesh(dpCodes);
152
+ };
153
+ useEffect(() => {
154
+ const isSigMeshDevice = support === null || support === void 0 ? void 0 : support.isSigMeshDevice();
155
+ if (!isSigMeshDevice) {
156
+ scheduleLogger.info('useFetchDpDataByMesh 当前设备为', support === null || support === void 0 ? void 0 : support.deviceType, ' 只支持 sigmesh 设备');
157
+ return;
158
+ }
159
+ scheduleLogger.debug('useFetchDpDataByMesh get:', dpCodes);
160
+ getDpDataByMeshFn();
161
+ }, [dpCodes.join(','), support]);
162
+ return {
163
+ refresh: getDpDataByMeshFn
164
+ };
165
+ };
@@ -0,0 +1,29 @@
1
+ export declare enum Themes {
2
+ dark = "dark",
3
+ light = "light"
4
+ }
5
+ export declare enum Orientation {
6
+ portrait = "portrait",
7
+ landscape = "landscape"
8
+ }
9
+ /**
10
+ * 获取手机系统时间制式
11
+ */
12
+ export declare const useHourType: () => {
13
+ is12Hour: boolean;
14
+ };
15
+ /**
16
+ * 获取手机屏幕底部安全区域高度
17
+ */
18
+ export declare const useSafeArea: () => number;
19
+ /**
20
+ * 获取手机当前使用的语言
21
+ * @returns string // default: en
22
+ */
23
+ export declare const useLanguage: () => string;
24
+ export declare const useIsIOS: () => boolean;
25
+ /**
26
+ * 隐藏菜单按钮
27
+ * @param returnShowMenu 返回页面后是否隐藏按钮
28
+ */
29
+ export declare const useHideMenu: () => void;
@@ -0,0 +1,59 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import { hideMenuButton } from '@ray-js/ray';
3
+ import { getCachedSystemInfo } from '../utils/getCachedSystemInfo';
4
+ export let Themes = /*#__PURE__*/function (Themes) {
5
+ Themes["dark"] = "dark";
6
+ Themes["light"] = "light";
7
+ return Themes;
8
+ }({});
9
+ export let Orientation = /*#__PURE__*/function (Orientation) {
10
+ Orientation["portrait"] = "portrait";
11
+ Orientation["landscape"] = "landscape";
12
+ return Orientation;
13
+ }({});
14
+
15
+ /**
16
+ * 获取手机系统时间制式
17
+ */
18
+ export const useHourType = () => {
19
+ var _systemInfoRef$curren;
20
+ const systemInfoRef = useRef(getCachedSystemInfo());
21
+ const is24Hour = systemInfoRef === null || systemInfoRef === void 0 || (_systemInfoRef$curren = systemInfoRef.current) === null || _systemInfoRef$curren === void 0 ? void 0 : _systemInfoRef$curren.is24Hour;
22
+ return {
23
+ is12Hour: !is24Hour
24
+ };
25
+ };
26
+
27
+ /**
28
+ * 获取手机屏幕底部安全区域高度
29
+ */
30
+ export const useSafeArea = () => {
31
+ var _systemInfoRef$curren2;
32
+ const systemInfoRef = useRef(getCachedSystemInfo());
33
+ return (systemInfoRef === null || systemInfoRef === void 0 || (_systemInfoRef$curren2 = systemInfoRef.current) === null || _systemInfoRef$curren2 === void 0 ? void 0 : _systemInfoRef$curren2.statusBarHeight) || 24;
34
+ };
35
+
36
+ /**
37
+ * 获取手机当前使用的语言
38
+ * @returns string // default: en
39
+ */
40
+ export const useLanguage = () => {
41
+ var _systemInfoRef$curren3;
42
+ const systemInfoRef = useRef(getCachedSystemInfo());
43
+ return (systemInfoRef === null || systemInfoRef === void 0 || (_systemInfoRef$curren3 = systemInfoRef.current) === null || _systemInfoRef$curren3 === void 0 ? void 0 : _systemInfoRef$curren3.language) || 'en';
44
+ };
45
+ export const useIsIOS = () => {
46
+ var _systemInfoRef$curren4;
47
+ const systemInfoRef = useRef(getCachedSystemInfo());
48
+ return (systemInfoRef === null || systemInfoRef === void 0 || (_systemInfoRef$curren4 = systemInfoRef.current) === null || _systemInfoRef$curren4 === void 0 || (_systemInfoRef$curren4 = _systemInfoRef$curren4.platform) === null || _systemInfoRef$curren4 === void 0 ? void 0 : _systemInfoRef$curren4.toLocaleLowerCase()) === 'ios';
49
+ };
50
+
51
+ /**
52
+ * 隐藏菜单按钮
53
+ * @param returnShowMenu 返回页面后是否隐藏按钮
54
+ */
55
+ export const useHideMenu = () => {
56
+ useEffect(() => {
57
+ hideMenuButton();
58
+ }, []);
59
+ };
@@ -0,0 +1,25 @@
1
+ import { Support } from '../utils/ScheduleSupport';
2
+ export declare const useSupport: () => Support | null;
3
+ type TScheduleInitState = {
4
+ isReady: boolean;
5
+ };
6
+ export declare const resetIsInit: () => void;
7
+ export declare const useScheduleInit: (props: {
8
+ devId: string;
9
+ groupId?: string;
10
+ }) => TScheduleInitState;
11
+ export declare const getSupportIns: () => Support;
12
+ export declare const isInitFn: () => boolean;
13
+ export declare const useInit: () => boolean;
14
+ /**
15
+ * @description: 判断是否支持某个功能 通过dpCode 来判断
16
+ * @param defaultCodes: 默认检测的 dpCode
17
+ * @param dpCodeList: dpCode 列表 string[], 非必填,默认为 [], 会检测标准计划 dp,如果不为 [],则检测 dpCodeList 中的 dp 支持情况
18
+ * @param checkType: 检测类型,every 必须支持 dpCodeList或defaultCodes 中所有的 dp 值,some 为支持其中一个即可。
19
+ * @return boolean
20
+ */
21
+ export declare const useCommonSupport: (defaultCodes: string[], dpCodeList?: string[], checkType?: 'every' | 'some') => {
22
+ isReady: boolean;
23
+ isSupport: boolean;
24
+ };
25
+ export {};