@eohjsc/react-native-smart-city 0.3.22 → 0.3.25

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 (96) 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 +22 -5
  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 +3 -3
  43. package/src/configs/Constants.js +12 -2
  44. package/src/configs/SCConfig.js +4 -0
  45. package/src/context/actionType.ts +5 -3
  46. package/src/context/mockStore.ts +10 -3
  47. package/src/context/reducer.ts +26 -12
  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/useWatchConfigs.js +34 -0
  60. package/src/iot/Monitor.js +13 -20
  61. package/src/iot/RemoteControl/GoogleHome.js +12 -13
  62. package/src/iot/RemoteControl/Internet.js +1 -8
  63. package/src/iot/RemoteControl/LG.js +1 -0
  64. package/src/iot/RemoteControl/__test__/GoogleHome.test.js +7 -2
  65. package/src/navigations/UnitStack.js +24 -0
  66. package/src/screens/AddNewAction/SelectAction.js +1 -1
  67. package/src/screens/AddNewAction/SetupSensor.js +4 -0
  68. package/src/screens/AddNewGateway/PlugAndPlay/ConnectWifiWarning.js +44 -78
  69. package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +15 -35
  70. package/src/screens/AddNewGateway/PlugAndPlay/__test__/GatewayWifiList.test.js +2 -0
  71. package/src/screens/AllCamera/__test__/index.test.js +1 -1
  72. package/src/screens/Device/__test__/detail.test.js +1 -54
  73. package/src/screens/Device/components/SensorConnectStatusViewHeader.js +18 -8
  74. package/src/screens/Device/components/SensorDisplayItem.js +2 -2
  75. package/src/screens/Device/detail.js +22 -19
  76. package/src/screens/Device/hooks/__test__/useEvaluateValue.test.js +102 -0
  77. package/src/screens/Device/hooks/useDeviceWatchConfigControl.js +20 -0
  78. package/src/screens/Device/utils/index.js +45 -0
  79. package/src/screens/Device/utils/index.test.js +111 -0
  80. package/src/screens/MoveToAnotherSubUnit/__test__/index.test.js +0 -2
  81. package/src/screens/Notification/__test__/NotificationItem.test.js +84 -19
  82. package/src/screens/Notification/components/NotificationItem.js +64 -31
  83. package/src/screens/PlayBackCamera/Timer.js +3 -0
  84. package/src/screens/PlayBackCamera/__test__/index.test.js +8 -1
  85. package/src/screens/PlayBackCamera/index.js +86 -49
  86. package/src/screens/SubUnit/AddSubUnit.js +2 -1
  87. package/src/screens/Unit/AddMenu.js +4 -0
  88. package/src/screens/Unit/Detail.js +16 -10
  89. package/src/screens/Unit/__test__/CheckSendEmail.test.js +12 -0
  90. package/src/screens/Unit/__test__/Detail.test.js +2 -3
  91. package/src/screens/Unit/components/MyUnitDevice/index.js +4 -2
  92. package/src/screens/Unit/components/__test__/AutomateScript.test.js +116 -0
  93. package/src/screens/UnitSummary/components/3PPowerConsumption/index.js +4 -2
  94. package/src/utils/I18n/translations/en.json +5 -1
  95. package/src/utils/I18n/translations/vi.json +4 -0
  96. package/src/hooks/Common/useSensorsStatus.js +0 -62
@@ -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;
@@ -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 () => {
@@ -4,10 +4,12 @@ import { IconOutline } from '@ant-design/icons-react-native';
4
4
  import { createStackNavigator } from '@react-navigation/stack';
5
5
  import { BleManager } from 'react-native-ble-plx';
6
6
  import NetInfo from '@react-native-community/netinfo';
7
+ import { AppState } from 'react-native';
7
8
  import { get } from 'lodash';
8
9
 
9
10
  import Text from '../commons/Text';
10
11
  import { useTranslations } from '../hooks/Common/useTranslations';
12
+ import { unwatchAllConfigs } from '../iot/Monitor';
11
13
  import { Colors, Device } from '../configs';
12
14
  import Route from '../utils/Route';
13
15
  import ActivityLogScreen from '../screens/ActivityLog';
@@ -107,6 +109,28 @@ export const UnitStack = memo((props) => {
107
109
  // eslint-disable-next-line react-hooks/exhaustive-deps
108
110
  }, []);
109
111
 
112
+ useEffect(() => {
113
+ const subscription = AppState.addEventListener('change', (nextAppState) => {
114
+ if (nextAppState === 'background') {
115
+ unwatchAllConfigs();
116
+ }
117
+ });
118
+ return () => {
119
+ subscription?.remove();
120
+ };
121
+ }, []);
122
+
123
+ useEffect(() => {
124
+ return () => {
125
+ const id = unitId || unitData?.id;
126
+ if (!id) {
127
+ return;
128
+ }
129
+ setAction(Action.NEED_UPDATE_VALUE_EVALUATIONS, id);
130
+ };
131
+ // eslint-disable-next-line react-hooks/exhaustive-deps
132
+ }, []);
133
+
110
134
  return (
111
135
  <Stack.Navigator
112
136
  screenOptions={{
@@ -349,7 +349,7 @@ const SelectAction = memo(({ route }) => {
349
349
  <LoadingSelectAction style={styles.container} />
350
350
  ) : (
351
351
  sensorData.map((item) => {
352
- const isHasValue = !!item?.value || item?.value === 0;
352
+ const isHasValue = !!item?.value;
353
353
  return (
354
354
  <View style={styles.wrapItem} key={item?.id}>
355
355
  <TitleCheckBox
@@ -149,6 +149,10 @@ const SetUpSensor = () => {
149
149
  // eslint-disable-next-line react-hooks/exhaustive-deps
150
150
  }, [minimum, maximum, value]);
151
151
 
152
+ useEffect(() => {
153
+ !isNumberValue && setValue(1);
154
+ }, [isNumberValue]);
155
+
152
156
  useEffect(() => {
153
157
  if (!isHasLimit && maximum - 150 <= value * 10) {
154
158
  setMaximum(maximum + 200);
@@ -28,14 +28,9 @@ import { Action } from '../../../context/actionType';
28
28
  import { TESTID } from '../../../configs/Constants';
29
29
  import Connecting from '../../../commons/Connecting';
30
30
 
31
- const isIos = Platform.OS === 'ios';
32
31
  const isAndroid = Platform.OS === 'android';
33
-
34
- let socket = null;
35
- if (isIos) {
36
- socket = dgram.createSocket({ type: 'udp4' });
37
- socket.bind(54321);
38
- }
32
+ let socket,
33
+ intervalSend = null;
39
34
 
40
35
  const ConnectWifiWarning = memo(({ route }) => {
41
36
  const {
@@ -83,77 +78,44 @@ const ConnectWifiWarning = memo(({ route }) => {
83
78
  }, [getPermissionWifiAndroid]);
84
79
 
85
80
  const handleSend = async () => {
86
- let intervalSend = null;
87
- if (isIos) {
88
- await setIsPercentConnect(1);
89
- await socket.on('message', (msg, rinfo) => {
90
- clearInterval(intervalSend);
91
- const data = JSON.parse(msg.toString());
92
- if (Object.prototype.hasOwnProperty.call(data, 'wifi')) {
93
- navigate(Routes.GatewayWifiList, {
94
- list_wifi: data.wifi,
95
- unit_id: unit_id,
96
- chip_id: chip_id,
97
- scan_sensor_data: { ...body },
98
- wifi_ssid: wifi_ssid,
99
- wifi_pass: wifi_pass,
100
- unit_name: unit_name,
101
- devicePrefixName: devicePrefixName,
102
- socket: socket,
103
- });
104
- }
105
- });
106
- intervalSend = setInterval(() => {
107
- socket.send(
108
- JSON.stringify({ type: 'scan', data: { wifi: '' } }),
109
- undefined,
110
- undefined,
111
- 54321,
112
- '192.168.27.1',
113
- undefined
114
- );
115
- }, 1000);
116
- socket.on('error', () => {
117
- ToastBottomHelper.error(t('server_error'));
118
- setAction(Action.IS_CONNECT_WIFI_GATEWAY, false);
119
- goBack();
120
- });
121
- } else {
122
- const dgSocket = dgram.createSocket({ type: 'udp4' });
123
- await setIsPercentConnect(1);
124
- await dgSocket.bind(54321);
125
- await dgSocket.on('message', (msg, rinfo) => {
126
- const data = JSON.parse(msg.toString());
127
- if (Object.prototype.hasOwnProperty.call(data, 'wifi')) {
128
- navigate(Routes.GatewayWifiList, {
129
- list_wifi: data.wifi,
130
- unit_id: unit_id,
131
- chip_id: chip_id,
132
- scan_sensor_data: { ...body },
133
- wifi_ssid: wifi_ssid,
134
- wifi_pass: wifi_pass,
135
- unit_name: unit_name,
136
- devicePrefixName: devicePrefixName,
137
- socket: dgSocket,
138
- });
139
- }
140
- });
141
- await dgSocket.once('listening', async () => {
142
- await dgSocket.send(
143
- JSON.stringify({ type: 'scan', data: { wifi: '' } }),
144
- undefined,
145
- undefined,
146
- 54321,
147
- '192.168.27.1',
148
- undefined
149
- );
150
- });
151
- dgSocket.on('error', () => {
152
- ToastBottomHelper.error(t('server_error'));
153
- setAction(Action.IS_CONNECT_WIFI_GATEWAY, false);
154
- goBack();
155
- });
156
- }
81
+ socket = dgram.createSocket({ type: 'udp4' });
82
+ socket.bind(54321);
83
+ setIsPercentConnect(1);
84
+
85
+ socket.on('message', (msg, rinfo) => {
86
+ clearInterval(intervalSend);
87
+ const data = JSON.parse(msg.toString());
88
+ if (Object.prototype.hasOwnProperty.call(data, 'wifi')) {
89
+ navigate(Routes.GatewayWifiList, {
90
+ list_wifi: data.wifi,
91
+ unit_id: unit_id,
92
+ chip_id: chip_id,
93
+ scan_sensor_data: { ...body },
94
+ wifi_ssid: wifi_ssid,
95
+ wifi_pass: wifi_pass,
96
+ unit_name: unit_name,
97
+ devicePrefixName: devicePrefixName,
98
+ socket: socket,
99
+ });
100
+ }
101
+ });
102
+
103
+ socket.on('error', () => {
104
+ ToastBottomHelper.error(t('server_error'));
105
+ setAction(Action.IS_CONNECT_WIFI_GATEWAY, false);
106
+ goBack();
107
+ });
108
+
109
+ intervalSend = setInterval(() => {
110
+ socket.send(
111
+ JSON.stringify({ type: 'scan', data: { wifi: '' } }),
112
+ undefined,
113
+ undefined,
114
+ 54321,
115
+ '192.168.27.1',
116
+ undefined
117
+ );
118
+ }, 5000); // workaround, todo Bang continue research
157
119
  };
158
120
 
159
121
  const handleConnectWifiGateway = async () => {
@@ -171,6 +133,10 @@ const ConnectWifiWarning = memo(({ route }) => {
171
133
  );
172
134
  };
173
135
 
136
+ useEffect(() => {
137
+ return () => intervalSend && clearInterval(intervalSend);
138
+ }, []);
139
+
174
140
  return (
175
141
  <View style={styles.screen}>
176
142
  {!isLoading ? (