@eohjsc/react-native-smart-city 0.3.21 → 0.3.24

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 (104) hide show
  1. package/index.js +2 -0
  2. package/package.json +2 -1
  3. package/src/Images/Common/buttonLeftCurtain.png +0 -0
  4. package/src/Images/Common/buttonLeftCurtain@2x.png +0 -0
  5. package/src/Images/Common/buttonLeftCurtain@3x.png +0 -0
  6. package/src/commons/Action/ItemQuickAction.js +1 -12
  7. package/src/commons/Action/__test__/ItemQuickAction.test.js +1 -1
  8. package/src/commons/ActionGroup/ColorPickerTemplate.js +2 -9
  9. package/src/commons/ActionGroup/CurtainButtonTemplate.js +14 -21
  10. package/src/commons/ActionGroup/CurtainButtonTemplateStyle.js +5 -0
  11. package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +12 -24
  12. package/src/commons/ActionGroup/OnOffSmartLock/OnOffSmartLock.js +10 -17
  13. package/src/commons/ActionGroup/OnOffTemplate/index.js +10 -35
  14. package/src/commons/ActionGroup/OneBigButtonTemplate.js +2 -3
  15. package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +7 -8
  16. package/src/commons/ActionGroup/SliderRangeTemplate.js +3 -10
  17. package/src/commons/ActionGroup/StatesGridActionTemplate.js +9 -24
  18. package/src/commons/ActionGroup/ThreeButtonTemplate.js +6 -9
  19. package/src/commons/ActionGroup/TimerActionTemplate.js +11 -4
  20. package/src/commons/ActionGroup/TwoButtonTemplate/index.js +18 -33
  21. package/src/commons/ActionGroup/__test__/CurtainButtonTemplate.test.js +3 -15
  22. package/src/commons/ActionGroup/__test__/NumberUpDownTemplate.test.js +38 -4
  23. package/src/commons/ActionGroup/__test__/OnOffButtonTemplate.test.js +7 -0
  24. package/src/commons/ActionGroup/__test__/OnOffSmartLock.test.js +17 -12
  25. package/src/commons/ActionGroup/__test__/OnOffTemplate.test.js +11 -16
  26. package/src/commons/ActionGroup/__test__/OneBigButtonTemplate.test.js +1 -1
  27. package/src/commons/ActionGroup/__test__/OptionsDropdownTemplate.test.js +11 -10
  28. package/src/commons/ActionGroup/__test__/StatesGridActionTemplate.test.js +8 -7
  29. package/src/commons/ActionGroup/__test__/TimerActionTemplate.test.js +8 -1
  30. package/src/commons/ActionGroup/__test__/TimerActionTemplateWithutConfigValue.test.js +7 -0
  31. package/src/commons/ActionGroup/__test__/TwoButtonTemplate.test.js +17 -2
  32. package/src/commons/ActionGroup/__test__/index.test.js +15 -18
  33. package/src/commons/ConnectingProcess/index.js +6 -25
  34. package/src/commons/Device/HistoryChart.js +8 -6
  35. package/src/commons/Device/ItemDevice.js +79 -35
  36. package/src/commons/MediaPlayerDetail/index.js +5 -0
  37. package/src/commons/RowItem/index.js +6 -2
  38. package/src/commons/SubUnit/Favorites/index.js +24 -6
  39. package/src/commons/SubUnit/ShortDetail.js +31 -5
  40. package/src/commons/SubUnit/__test__/Favorites.test.js +1 -0
  41. package/src/commons/SubUnit/__test__/ShortDetail.test.js +1 -0
  42. package/src/configs/API.js +9 -4
  43. package/src/configs/Constants.js +8 -2
  44. package/src/configs/SCConfig.js +4 -0
  45. package/src/context/actionType.ts +7 -5
  46. package/src/context/mockStore.ts +10 -3
  47. package/src/context/reducer.ts +29 -15
  48. package/src/hoc/index.js +3 -0
  49. package/src/hoc/withRemoteControl.js +10 -0
  50. package/src/hooks/Common/index.js +2 -2
  51. package/src/hooks/Common/useDevicesStatus.js +57 -0
  52. package/src/hooks/Common/useGGHomeDeviceConnected.js +3 -3
  53. package/src/hooks/IoT/__test__/useGGHomeConnection.test.js +1 -2
  54. package/src/hooks/IoT/__test__/useRemoteControl.test.js +9 -11
  55. package/src/hooks/IoT/index.js +9 -1
  56. package/src/hooks/IoT/useGGHomeConnection.js +0 -1
  57. package/src/hooks/IoT/useRemoteControl.js +2 -3
  58. package/src/hooks/IoT/useUnwatchLGDeviceConfigControl.js +29 -0
  59. package/src/hooks/IoT/useValueEvaluation.js +17 -4
  60. package/src/hooks/IoT/useWatchConfigs.js +34 -0
  61. package/src/iot/Monitor.js +13 -20
  62. package/src/iot/RemoteControl/GoogleHome.js +12 -13
  63. package/src/iot/RemoteControl/Internet.js +1 -8
  64. package/src/iot/RemoteControl/LG.js +1 -0
  65. package/src/iot/RemoteControl/__test__/GoogleHome.test.js +7 -2
  66. package/src/navigations/UnitStack.js +27 -3
  67. package/src/screens/AddNewAction/SelectAction.js +1 -1
  68. package/src/screens/AddNewAction/SetupSensor.js +4 -0
  69. package/src/screens/AddNewGateway/PlugAndPlay/ConnectWifiWarning.js +44 -78
  70. package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +15 -35
  71. package/src/screens/AddNewGateway/PlugAndPlay/__test__/GatewayWifiList.test.js +2 -0
  72. package/src/screens/AllCamera/__test__/index.test.js +1 -1
  73. package/src/screens/Device/__test__/detail.test.js +1 -54
  74. package/src/screens/Device/components/SensorConnectStatusViewHeader.js +18 -8
  75. package/src/screens/Device/components/SensorDisplayItem.js +2 -2
  76. package/src/screens/Device/detail.js +36 -30
  77. package/src/screens/Device/hooks/__test__/useEvaluateValue.test.js +102 -0
  78. package/src/screens/Device/hooks/useDeviceWatchConfigControl.js +20 -0
  79. package/src/screens/Device/utils/index.js +45 -0
  80. package/src/screens/Device/utils/index.test.js +111 -0
  81. package/src/screens/EmergencyContacts/EmergencyContactsAddNew.js +35 -22
  82. package/src/screens/EmergencyContacts/EmergencyContactsSelectContacts.js +2 -1
  83. package/src/screens/EmergencyContacts/__test__/EmergencyContactAddNew.test.js +36 -2
  84. package/src/screens/MoveToAnotherSubUnit/__test__/index.test.js +0 -2
  85. package/src/screens/Notification/__test__/NotificationItem.test.js +84 -19
  86. package/src/screens/Notification/components/NotificationItem.js +64 -31
  87. package/src/screens/PlayBackCamera/index.js +22 -6
  88. package/src/screens/ScriptDetail/hooks/useStarredScript.js +2 -2
  89. package/src/screens/SubUnit/AddSubUnit.js +2 -1
  90. package/src/screens/Unit/AddMenu.js +4 -0
  91. package/src/screens/Unit/{SelectFavoritesDevices.js → SelectAddToFavorites.js} +81 -26
  92. package/src/screens/Unit/{SelectFavoritesDevicesStyles.js → SelectAddToFavoritesStyles.js} +0 -0
  93. package/src/screens/Unit/__test__/CheckSendEmail.test.js +12 -0
  94. package/src/screens/Unit/__test__/Detail.test.js +2 -3
  95. package/src/screens/Unit/__test__/SelectAddToFavorites.test.js +267 -0
  96. package/src/screens/Unit/components/AutomateScript/index.js +65 -0
  97. package/src/screens/Unit/components/AutomateScript/styles.js +48 -0
  98. package/src/screens/Unit/components/MyUnitDevice/index.js +4 -2
  99. package/src/screens/UnitSummary/components/3PPowerConsumption/index.js +4 -2
  100. package/src/utils/I18n/translations/en.json +7 -2
  101. package/src/utils/I18n/translations/vi.json +6 -1
  102. package/src/utils/Route/index.js +1 -1
  103. package/src/hooks/Common/useSensorsStatus.js +0 -62
  104. package/src/screens/Unit/__test__/SelectFavoritesDevices.test.js +0 -110
@@ -63,10 +63,11 @@ export const initialState = {
63
63
  },
64
64
  iot: {
65
65
  googlehome: {
66
- isFirstTimeConnect: true,
67
- isConnecting: false,
68
66
  connections: {},
69
67
  },
68
+ internet: {
69
+ statuses: {},
70
+ },
70
71
  },
71
72
  valueEvaluations: {},
72
73
  fetchedValueEvaluationUnits: [],
@@ -235,7 +236,7 @@ export const reducer = (currentState: ContextData, action: Action) => {
235
236
  starredScriptIds: payload,
236
237
  },
237
238
  };
238
- case Action.STAR_SCRIPT:
239
+ case Action.STAR_SCRIPTS:
239
240
  return {
240
241
  ...currentState,
241
242
  automate: {
@@ -245,13 +246,13 @@ export const reducer = (currentState: ContextData, action: Action) => {
245
246
  ),
246
247
  },
247
248
  };
248
- case Action.UNSTAR_SCRIPT:
249
+ case Action.UNSTAR_SCRIPTS:
249
250
  return {
250
251
  ...currentState,
251
252
  automate: {
252
253
  ...currentState.automate,
253
254
  starredScriptIds: currentState.automate.starredScriptIds.filter(
254
- (scriptId) => scriptId !== payload
255
+ (scriptId) => !payload.includes(scriptId)
255
256
  ),
256
257
  },
257
258
  };
@@ -263,8 +264,6 @@ export const reducer = (currentState: ContextData, action: Action) => {
263
264
  ...currentState.iot,
264
265
  googlehome: {
265
266
  ...currentState.iot.googlehome,
266
- isFirstTimeConnect: false,
267
- isConnecting: false,
268
267
  connections: payload,
269
268
  },
270
269
  },
@@ -276,8 +275,6 @@ export const reducer = (currentState: ContextData, action: Action) => {
276
275
  ...currentState.iot,
277
276
  googlehome: {
278
277
  ...currentState.iot.googlehome,
279
- isFirstTimeConnect: false,
280
- isConnecting: false,
281
278
  connections: {
282
279
  ...currentState.iot.googlehome.connections,
283
280
  [payload.option.chip_id]: payload.data,
@@ -285,16 +282,24 @@ export const reducer = (currentState: ContextData, action: Action) => {
285
282
  },
286
283
  },
287
284
  };
288
- case Action.CONNECTING_GOOGLE_HOME:
285
+
286
+ case Action.SET_DEVICES_STATUS:
287
+ // eslint-disable-next-line no-case-declarations
288
+ let newStatuses = currentState.iot.internet.statuses;
289
+ (payload || []).map(
290
+ (i) =>
291
+ (newStatuses[i.id] = {
292
+ ...(newStatuses[i.id] || {}),
293
+ isConnected: i.is_connected,
294
+ })
295
+ );
289
296
  return {
290
297
  ...currentState,
291
298
  iot: {
292
299
  ...currentState.iot,
293
- googlehome: {
294
- ...currentState.iot.googlehome,
295
- isConnecting: currentState.iot.googlehome.isFirstTimeConnect
296
- ? true
297
- : false,
300
+ internet: {
301
+ ...currentState.iot.internet,
302
+ statuses: newStatuses,
298
303
  },
299
304
  },
300
305
  };
@@ -318,6 +323,15 @@ export const reducer = (currentState: ContextData, action: Action) => {
318
323
  currentState.valueEvaluations
319
324
  ),
320
325
  };
326
+ case Action.NEED_UPDATE_VALUE_EVALUATIONS:
327
+ return {
328
+ ...currentState,
329
+ fetchedValueEvaluationUnits:
330
+ currentState.fetchedValueEvaluationUnits.filter(
331
+ // eslint-disable-next-line no-shadow
332
+ (unitId) => unitId !== payload
333
+ ),
334
+ };
321
335
 
322
336
  case Action.ON_RECEIVE_NOTIFICATION:
323
337
  return {
@@ -0,0 +1,3 @@
1
+ import withRemoteControl from './withRemoteControl';
2
+
3
+ export { withRemoteControl };
@@ -0,0 +1,10 @@
1
+ import { useRemoteControl } from '../hooks/IoT';
2
+
3
+ function withRemoteControl(Component) {
4
+ return function WrappedComponent(props) {
5
+ const sendRemoteCommand = useRemoteControl();
6
+ return <Component {...props} sendRemoteCommand={sendRemoteCommand} />;
7
+ };
8
+ }
9
+
10
+ export default withRemoteControl;
@@ -4,7 +4,7 @@ import useForceUpdate from './useForceUpdate';
4
4
  import useKeyboardShow from './useKeyboardShow';
5
5
  import usePopover from './usePopover';
6
6
  import useTitleHeader from './useTitleHeader';
7
- import useSensorsStatus from './useSensorsStatus';
7
+ import useDevicesStatus from './useDevicesStatus';
8
8
  import useGGHomeDeviceConnected from './useGGHomeDeviceConnected';
9
9
  import { useBlockBackAndroid } from './useBlockBackAndroid';
10
10
  import { useIsOwnerOfUnit } from './useIsOwnerOfUnit';
@@ -22,6 +22,6 @@ export {
22
22
  useIsOwnerOfUnit,
23
23
  useStatusBar,
24
24
  useGetIdUser,
25
- useSensorsStatus,
25
+ useDevicesStatus,
26
26
  useGGHomeDeviceConnected,
27
27
  };
@@ -0,0 +1,57 @@
1
+ import { useCallback, useContext } from 'react';
2
+ import { useFocusEffect } from '@react-navigation/native';
3
+ import { SCContext, useSCContextSelector } from '../../context';
4
+ import { axiosGet } from '../../utils/Apis/axios';
5
+ import { API } from '../../configs';
6
+ import { Action } from '../../context/actionType';
7
+
8
+ let timeoutId;
9
+
10
+ const useDevicesStatus = (unit, devices) => {
11
+ const { setAction } = useContext(SCContext);
12
+ const isNetworkConnected = useSCContextSelector(
13
+ (state) => state.app.isNetworkConnected
14
+ );
15
+
16
+ const getDevicesStatus = useCallback(async (_unit, _devices) => {
17
+ const params = new URLSearchParams();
18
+ _devices.forEach((device) => {
19
+ params.append('sensors', device.id);
20
+ });
21
+ const { success, data } = await axiosGet(
22
+ API.UNIT.SENSORS_STATUS(_unit.id),
23
+ {
24
+ params: params,
25
+ }
26
+ );
27
+ if (success) {
28
+ setAction(Action.SET_DEVICES_STATUS, data);
29
+ }
30
+ timeoutId = setTimeout(() => getDevicesStatus(_unit, _devices), 5000);
31
+ // eslint-disable-next-line react-hooks/exhaustive-deps
32
+ }, []);
33
+
34
+ useFocusEffect(
35
+ useCallback(() => {
36
+ if (!devices?.length || !isNetworkConnected) {
37
+ return;
38
+ }
39
+
40
+ const managedDevices = devices.filter(
41
+ (device) => device?.is_managed_by_backend
42
+ );
43
+ if (!managedDevices.length) {
44
+ return;
45
+ }
46
+
47
+ timeoutId = setTimeout(() => getDevicesStatus(unit, managedDevices), 200);
48
+
49
+ return () => {
50
+ clearTimeout(timeoutId);
51
+ };
52
+ // eslint-disable-next-line react-hooks/exhaustive-deps
53
+ }, [unit, devices, isNetworkConnected])
54
+ );
55
+ };
56
+
57
+ export default useDevicesStatus;
@@ -1,9 +1,9 @@
1
1
  import { useSCContextSelector } from '../../context';
2
2
 
3
3
  const useGGHomeDeviceConnected = (device) => {
4
- const { connections, isConnecting } = useSCContextSelector(
5
- (state) => state.iot.googlehome
6
- );
4
+ const { connections } = useSCContextSelector((state) => state.iot.googlehome);
5
+
6
+ const isConnecting = !!device?.chip_id && !(device.chip_id in connections);
7
7
 
8
8
  const isConnected =
9
9
  !!device?.chip_id &&
@@ -167,8 +167,7 @@ describe('Test useGGHomeConnection', () => {
167
167
  await act(async () => {
168
168
  await result.current.connectGoogleHome(options);
169
169
  });
170
- expect(mockedSetAction).toBeCalledTimes(3);
171
- expect(mockedSetAction).toBeCalledWith(Action.CONNECTING_GOOGLE_HOME);
170
+ expect(mockedSetAction).toBeCalledTimes(2);
172
171
  expect(mockedSetAction).toBeCalledWith(
173
172
  Action.SET_GOOGLE_HOME_CONNECTIONS,
174
173
  conns
@@ -28,7 +28,7 @@ const mockUseContext = jest.fn().mockImplementation(() => ({
28
28
  React.useContext = mockUseContext;
29
29
 
30
30
  describe('Test useRemoteControl', () => {
31
- let sensor, action, data, userId, actionName;
31
+ let sensor, action, data, userId;
32
32
 
33
33
  beforeEach(() => {
34
34
  sendCommandOverBluetooth.mockClear();
@@ -51,7 +51,6 @@ describe('Test useRemoteControl', () => {
51
51
  };
52
52
  data = null;
53
53
  userId = 1;
54
- actionName = 'action name';
55
54
  });
56
55
 
57
56
  it('test send remote command action null', async () => {
@@ -60,7 +59,7 @@ describe('Test useRemoteControl', () => {
60
59
  wrapper,
61
60
  });
62
61
  act(() => {
63
- sendRemoteCommand.current(sensor, action, data, userId, actionName);
62
+ sendRemoteCommand.current(sensor, action, data, userId);
64
63
  });
65
64
  expect(sendCommandOverInternet).not.toBeCalled();
66
65
  expect(sendCommandOverGoogleHome).not.toBeCalled();
@@ -75,7 +74,7 @@ describe('Test useRemoteControl', () => {
75
74
 
76
75
  sendCommandOverBluetooth.mockImplementation(async () => true);
77
76
  act(() => {
78
- sendRemoteCommand.current(sensor, action, data, userId, actionName);
77
+ sendRemoteCommand.current(sensor, action, data, userId);
79
78
  });
80
79
  expect(sendCommandOverBluetooth).toBeCalledWith(
81
80
  sensor,
@@ -98,7 +97,7 @@ describe('Test useRemoteControl', () => {
98
97
  });
99
98
  sendCommandOverInternet.mockImplementation(async () => true);
100
99
  act(() => {
101
- sendRemoteCommand.current(sensor, action, data, userId, actionName);
100
+ sendRemoteCommand.current(sensor, action, data, userId);
102
101
  });
103
102
  expect(sendCommandOverBluetooth).toBeCalledWith(
104
103
  sensor,
@@ -110,8 +109,7 @@ describe('Test useRemoteControl', () => {
110
109
  sensor,
111
110
  action,
112
111
  data,
113
- 'bluetooth',
114
- actionName
112
+ 'bluetooth'
115
113
  );
116
114
  expect(sendCommandOverInternet).toBeCalledTimes(1);
117
115
  expect(sendCommandOverGoogleHome).not.toBeCalled();
@@ -128,7 +126,7 @@ describe('Test useRemoteControl', () => {
128
126
  });
129
127
  sendCommandOverInternet.mockImplementation(async () => true);
130
128
  act(() => {
131
- sendRemoteCommand.current(sensor, action, data, userId, actionName);
129
+ sendRemoteCommand.current(sensor, action, data, userId);
132
130
  });
133
131
  expect(sendCommandOverBluetooth).toBeCalledWith(
134
132
  sensor,
@@ -150,7 +148,7 @@ describe('Test useRemoteControl', () => {
150
148
 
151
149
  sendCommandOverInternet.mockImplementation(async () => true);
152
150
  act(() => {
153
- sendRemoteCommand.current(sensor, action, data, userId, actionName);
151
+ sendRemoteCommand.current(sensor, action, data, userId);
154
152
  });
155
153
  expect(sendCommandOverInternet).toBeCalledWith(
156
154
  sensor,
@@ -172,7 +170,7 @@ describe('Test useRemoteControl', () => {
172
170
 
173
171
  sendCommandOverGoogleHome.mockImplementation(async () => true);
174
172
  act(() => {
175
- sendRemoteCommand.current(sensor, action, data, userId, actionName);
173
+ sendRemoteCommand.current(sensor, action, data, userId);
176
174
  });
177
175
  expect(sendCommandOverGoogleHome).toBeCalledWith({}, sensor, action, data);
178
176
  expect(sendCommandOverBluetooth).not.toBeCalled();
@@ -189,7 +187,7 @@ describe('Test useRemoteControl', () => {
189
187
 
190
188
  sendCommandOverLGThinq.mockImplementation(async () => true);
191
189
  act(() => {
192
- sendRemoteCommand.current(sensor, action, data, userId, actionName);
190
+ sendRemoteCommand.current(sensor, action, data, userId);
193
191
  });
194
192
  expect(sendCommandOverBluetooth).not.toBeCalled();
195
193
  expect(sendCommandOverGoogleHome).not.toBeCalled();
@@ -1,5 +1,13 @@
1
1
  import useGGHomeConnection from './useGGHomeConnection';
2
2
  import useRemoteControl from './useRemoteControl';
3
3
  import useValueEvaluations from './useValueEvaluation';
4
+ import useWatchConfigs from './useWatchConfigs';
5
+ import useUnwatchLGDeviceConfigControl from './useUnwatchLGDeviceConfigControl';
4
6
 
5
- export { useGGHomeConnection, useRemoteControl, useValueEvaluations };
7
+ export {
8
+ useGGHomeConnection,
9
+ useRemoteControl,
10
+ useValueEvaluations,
11
+ useWatchConfigs,
12
+ useUnwatchLGDeviceConfigControl,
13
+ };
@@ -63,7 +63,6 @@ const useGGHomeConnection = () => {
63
63
 
64
64
  const connectGoogleHome = useCallback(
65
65
  async (options) => {
66
- setAction(Action.CONNECTING_GOOGLE_HOME);
67
66
  await googleHomeConnect(
68
67
  connections,
69
68
  options,
@@ -15,7 +15,7 @@ const useRemoteControl = () => {
15
15
  );
16
16
 
17
17
  const sendRemoteCommand = useCallback(
18
- async (sensor, action, data, userId, actionName) => {
18
+ async (sensor, action, data, userId) => {
19
19
  // No action, raise not authorized
20
20
  let result = false;
21
21
 
@@ -36,8 +36,7 @@ const useRemoteControl = () => {
36
36
  sensor,
37
37
  action,
38
38
  data,
39
- 'bluetooth',
40
- actionName
39
+ 'bluetooth'
41
40
  );
42
41
  } else {
43
42
  throw err;
@@ -0,0 +1,29 @@
1
+ import { useCallback } from 'react';
2
+ import { useFocusEffect } from '@react-navigation/native';
3
+ import { unwatchMultiConfigs } from '../../iot/Monitor';
4
+ import { DEVICE_TYPE } from '../../configs/Constants';
5
+
6
+ const useUnwatchLGDeviceConfigControl = (device, configs) => {
7
+ const unwatch = useCallback(
8
+ (_configs) => {
9
+ if (
10
+ device?.is_managed_by_backend &&
11
+ device?.device_type === DEVICE_TYPE.LG_THINQ
12
+ ) {
13
+ unwatchMultiConfigs(configs.map((config) => config));
14
+ }
15
+ },
16
+ [device, configs]
17
+ );
18
+
19
+ useFocusEffect(
20
+ useCallback(() => {
21
+ return () => {
22
+ unwatch();
23
+ };
24
+ // eslint-disable-next-line react-hooks/exhaustive-deps
25
+ }, [])
26
+ );
27
+ };
28
+
29
+ export default useUnwatchLGDeviceConfigControl;
@@ -1,4 +1,4 @@
1
- import { useCallback, useContext, useEffect } from 'react';
1
+ import { useCallback, useContext, useEffect, useState } from 'react';
2
2
  import { API } from '../../configs';
3
3
  import { SCContext, useSCContextSelector } from '../../context';
4
4
  import { Action } from '../../context/actionType';
@@ -6,12 +6,14 @@ import { axiosGet } from '../../utils/Apis/axios';
6
6
 
7
7
  const useValueEvaluations = (unitId) => {
8
8
  const { setAction } = useContext(SCContext);
9
+ const [fetching, setFetching] = useState(false);
9
10
 
10
11
  const fetchConfigValueEvaluations = useCallback(
11
12
  async (page = 1) => {
12
13
  if (!unitId) {
13
14
  return;
14
15
  }
16
+ setFetching(true);
15
17
  const params = new URLSearchParams();
16
18
  params.append('config__end_device__station__unit', unitId);
17
19
  params.append('page', page);
@@ -24,9 +26,15 @@ const useValueEvaluations = (unitId) => {
24
26
  data: data.results,
25
27
  });
26
28
  if (data.next) {
27
- await fetchConfigValueEvaluations(page + 1);
29
+ return await fetchConfigValueEvaluations(page + 1);
28
30
  }
31
+ } else {
32
+ setAction(Action.UPDATE_VALUE_EVALUATIONS, {
33
+ unitId,
34
+ data: [],
35
+ });
29
36
  }
37
+ setFetching(false);
30
38
  },
31
39
  [unitId, setAction]
32
40
  );
@@ -36,10 +44,15 @@ const useValueEvaluations = (unitId) => {
36
44
  });
37
45
 
38
46
  useEffect(() => {
39
- if (!(fetchedValueEvaluationUnits.indexOf(unitId) !== -1)) {
47
+ if (!fetching && !(fetchedValueEvaluationUnits.indexOf(unitId) !== -1)) {
40
48
  fetchConfigValueEvaluations();
41
49
  }
42
- }, [unitId, fetchConfigValueEvaluations, fetchedValueEvaluationUnits]);
50
+ }, [
51
+ unitId,
52
+ fetching,
53
+ fetchConfigValueEvaluations,
54
+ fetchedValueEvaluationUnits,
55
+ ]);
43
56
  };
44
57
 
45
58
  export default useValueEvaluations;
@@ -0,0 +1,34 @@
1
+ import { useCallback } from 'react';
2
+ import { useFocusEffect } from '@react-navigation/native';
3
+ import { useSCContextSelector } from '../../context';
4
+ import { watchMultiConfigs, unwatchMultiConfigs } from '../../iot/Monitor';
5
+ import { SCConfig } from '../../configs';
6
+
7
+ let intervalId;
8
+
9
+ const useWatchConfigs = (configIds) => {
10
+ const isNetworkConnected = useSCContextSelector(
11
+ (state) => state.app.isNetworkConnected
12
+ );
13
+
14
+ useFocusEffect(
15
+ useCallback(() => {
16
+ if (!configIds.length || !isNetworkConnected) {
17
+ return;
18
+ }
19
+
20
+ watchMultiConfigs(configIds);
21
+ clearInterval(intervalId);
22
+ intervalId = setInterval(() => {
23
+ watchMultiConfigs(configIds);
24
+ }, SCConfig.intervalWatchConfigTime);
25
+
26
+ return () => {
27
+ unwatchMultiConfigs(configIds);
28
+ clearInterval(intervalId);
29
+ };
30
+ }, [configIds, isNetworkConnected])
31
+ );
32
+ };
33
+
34
+ export default useWatchConfigs;
@@ -2,8 +2,10 @@ import { API } from '../configs';
2
2
  import { getConfigGlobalState, setConfigGlobalState } from './states';
3
3
  import _ from 'lodash';
4
4
  import Pusher from 'pusher-js/react-native';
5
+ import PusherBatchAuthorizer from 'pusher-js-auth';
5
6
  import { axiosPost } from '../utils/Apis/axios';
6
7
  import { SCConfig } from '../configs';
8
+ import api from '../utils/Apis/axios';
7
9
 
8
10
  Pusher.logToConsole = true;
9
11
  let pusher = null;
@@ -12,23 +14,14 @@ const getPusher = () => {
12
14
  if (!pusher) {
13
15
  pusher = new Pusher(SCConfig.pusherAppKey, {
14
16
  cluster: 'ap1',
15
- authorizer: function (channel, option) {
16
- return {
17
- // eslint-disable-next-line promise/prefer-await-to-callbacks
18
- authorize: async function (socketId, callback) {
19
- const { success, data } = await axiosPost(
20
- API.IOT.CHIP_MANAGER.PUSHER_AUTH(),
21
- {
22
- channel_name: channel.name,
23
- socket_id: socketId,
24
- }
25
- );
26
- if (success) {
27
- // eslint-disable-next-line promise/prefer-await-to-callbacks
28
- callback(null, data);
29
- }
30
- },
31
- };
17
+ authorizer: PusherBatchAuthorizer,
18
+ authEndpoint: SCConfig.apiRoot + API.IOT.CHIP_MANAGER.PUSHER_AUTH(),
19
+ authDelay: 300,
20
+ auth: {
21
+ headers: {
22
+ Accept: 'application/json',
23
+ Authorization: api.headers.Authorization,
24
+ },
32
25
  },
33
26
  });
34
27
  }
@@ -55,7 +48,7 @@ const watchConfig = (configId) => {
55
48
  return;
56
49
  }
57
50
  watchingConfigs[configId] = 1;
58
- const channel = getPusher().subscribe(`private-config-${configId}`);
51
+ const channel = getPusher().subscribe(`private-config_v2-${configId}`);
59
52
  channel.bind('new-value', updateGlobalValue.bind(channel, configId));
60
53
  };
61
54
 
@@ -66,7 +59,7 @@ const unwatchConfig = (configId) => {
66
59
  watchingConfigs[configId] -= 1;
67
60
  if (!watchingConfigs[configId]) {
68
61
  delete watchingConfigs[configId];
69
- getPusher().unsubscribe(`private-config-${configId}`);
62
+ getPusher().unsubscribe(`private-config_v2-${configId}`);
70
63
  if (_.isEmpty(watchingConfigs)) {
71
64
  destroyPusher();
72
65
  }
@@ -84,7 +77,7 @@ export const watchMultiConfigs = async (configIds) => {
84
77
  waitWatchConfigIds = [];
85
78
  clearTimeout(waitWatchConfigTimerId);
86
79
  waitWatchConfigTimerId = 0;
87
- }, 100);
80
+ }, 200);
88
81
  }
89
82
  };
90
83
 
@@ -48,10 +48,9 @@ async function stateChangeCallback(event) {
48
48
  isChanged = true;
49
49
  const [configId, type] = configMaps[entityId];
50
50
  const typeConverter = valueTypes[type] || keepValue;
51
- configValues[configId] = typeConverter(
52
- event.data.new_state.state,
53
- entityId
54
- );
51
+ configValues[configId] = {
52
+ value: typeConverter(event.data.new_state.state, entityId),
53
+ };
55
54
  }
56
55
 
57
56
  if (entityId in attributeMaps) {
@@ -66,10 +65,9 @@ async function stateChangeCallback(event) {
66
65
 
67
66
  const [configId, type] = attributeMap;
68
67
  const typeConverter = valueTypes[type] || keepValue;
69
- configValues[configId] = typeConverter(
70
- entity.attributes[attributeName],
71
- entityId
72
- );
68
+ configValues[configId] = {
69
+ value: typeConverter(entity.attributes[attributeName], entityId),
70
+ };
73
71
  }
74
72
  }
75
73
 
@@ -91,7 +89,9 @@ async function fetchConnectionEntities(connection) {
91
89
  const [configId, type] = configMaps[entityId];
92
90
  const typeConverter = valueTypes[type] || keepValue;
93
91
 
94
- configValues[configId] = typeConverter(entity.state, entityId);
92
+ configValues[configId] = {
93
+ value: typeConverter(entity.state, entityId),
94
+ };
95
95
  }
96
96
 
97
97
  if (Object.prototype.hasOwnProperty.call(attributeMaps, entityId)) {
@@ -105,10 +105,9 @@ async function fetchConnectionEntities(connection) {
105
105
 
106
106
  const [configId, type] = attributeMap;
107
107
  const typeConverter = valueTypes[type] || keepValue;
108
- configValues[configId] = typeConverter(
109
- entity.attributes[attributeName],
110
- entityId
111
- );
108
+ configValues[configId] = {
109
+ value: typeConverter(entity.attributes[attributeName], entityId),
110
+ };
112
111
  }
113
112
  }
114
113
  }
@@ -4,13 +4,7 @@ import { ToastBottomHelper } from '../../utils/Utils';
4
4
  import { axiosPost } from '../../utils/Apis/axios';
5
5
  import { API } from '../../configs';
6
6
 
7
- export const sendCommandOverInternet = async (
8
- sensor,
9
- action,
10
- data,
11
- source,
12
- actionName
13
- ) => {
7
+ export const sendCommandOverInternet = async (sensor, action, data, source) => {
14
8
  if (data !== null) {
15
9
  if (Number.isInteger(data)) {
16
10
  data = data.toString(16).toUpperCase();
@@ -21,7 +15,6 @@ export const sendCommandOverInternet = async (
21
15
  key: action.key,
22
16
  data,
23
17
  source,
24
- action_name: actionName,
25
18
  });
26
19
  if (success) {
27
20
  ToastBottomHelper.success(t('Command is sent to device via internet'));
@@ -3,6 +3,7 @@ import { axiosGet } from '../../utils/Apis/axios';
3
3
  import { getConfigGlobalState, setConfigGlobalState } from '../states';
4
4
  import { sendCommandOverInternet } from './Internet';
5
5
 
6
+ // TODO update show config name of camelCase and snakeCase
6
7
  let deviceMaps = {};
7
8
  const propertyListMaps = {
8
9
  temperature: 'targetTemperature',
@@ -122,7 +122,12 @@ describe('Remote Control Google Home', () => {
122
122
  expect(getStates).toBeCalledTimes(1);
123
123
 
124
124
  configValues = getConfigGlobalState('configValues');
125
- expect(configValues).toEqual({ 1: true, 2: 50, 3: 10, 4: 123.4 });
125
+ expect(configValues).toEqual({
126
+ 1: { value: true },
127
+ 2: { value: 50 },
128
+ 3: { value: 10 },
129
+ 4: { value: 123.4 },
130
+ });
126
131
  });
127
132
 
128
133
  it('When state change, global config value also change', async () => {
@@ -162,7 +167,7 @@ describe('Remote Control Google Home', () => {
162
167
  );
163
168
 
164
169
  configValues = getConfigGlobalState('configValues');
165
- expect(configValues).toEqual({ 1: true });
170
+ expect(configValues).toEqual({ 1: { value: true } });
166
171
  });
167
172
 
168
173
  it('Connect to same google home will be skipped', async () => {