@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.
- package/index.js +2 -0
- package/package.json +2 -1
- package/src/Images/Common/buttonLeftCurtain.png +0 -0
- package/src/Images/Common/buttonLeftCurtain@2x.png +0 -0
- package/src/Images/Common/buttonLeftCurtain@3x.png +0 -0
- package/src/commons/Action/ItemQuickAction.js +1 -12
- package/src/commons/Action/__test__/ItemQuickAction.test.js +1 -1
- package/src/commons/ActionGroup/ColorPickerTemplate.js +2 -9
- package/src/commons/ActionGroup/CurtainButtonTemplate.js +14 -21
- package/src/commons/ActionGroup/CurtainButtonTemplateStyle.js +5 -0
- package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +12 -24
- package/src/commons/ActionGroup/OnOffSmartLock/OnOffSmartLock.js +10 -17
- package/src/commons/ActionGroup/OnOffTemplate/index.js +10 -35
- package/src/commons/ActionGroup/OneBigButtonTemplate.js +2 -3
- package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +7 -8
- package/src/commons/ActionGroup/SliderRangeTemplate.js +3 -10
- package/src/commons/ActionGroup/StatesGridActionTemplate.js +9 -24
- package/src/commons/ActionGroup/ThreeButtonTemplate.js +6 -9
- package/src/commons/ActionGroup/TimerActionTemplate.js +11 -4
- package/src/commons/ActionGroup/TwoButtonTemplate/index.js +18 -33
- package/src/commons/ActionGroup/__test__/CurtainButtonTemplate.test.js +3 -15
- package/src/commons/ActionGroup/__test__/NumberUpDownTemplate.test.js +38 -4
- package/src/commons/ActionGroup/__test__/OnOffButtonTemplate.test.js +7 -0
- package/src/commons/ActionGroup/__test__/OnOffSmartLock.test.js +17 -12
- package/src/commons/ActionGroup/__test__/OnOffTemplate.test.js +11 -16
- package/src/commons/ActionGroup/__test__/OneBigButtonTemplate.test.js +1 -1
- package/src/commons/ActionGroup/__test__/OptionsDropdownTemplate.test.js +11 -10
- package/src/commons/ActionGroup/__test__/StatesGridActionTemplate.test.js +8 -7
- package/src/commons/ActionGroup/__test__/TimerActionTemplate.test.js +8 -1
- package/src/commons/ActionGroup/__test__/TimerActionTemplateWithutConfigValue.test.js +7 -0
- package/src/commons/ActionGroup/__test__/TwoButtonTemplate.test.js +17 -2
- package/src/commons/ActionGroup/__test__/index.test.js +15 -18
- package/src/commons/ConnectingProcess/index.js +6 -25
- package/src/commons/Device/HistoryChart.js +8 -6
- package/src/commons/Device/ItemDevice.js +79 -35
- package/src/commons/MediaPlayerDetail/index.js +5 -0
- package/src/commons/RowItem/index.js +6 -2
- package/src/commons/SubUnit/Favorites/index.js +24 -6
- package/src/commons/SubUnit/ShortDetail.js +31 -5
- package/src/commons/SubUnit/__test__/Favorites.test.js +1 -0
- package/src/commons/SubUnit/__test__/ShortDetail.test.js +1 -0
- package/src/configs/API.js +9 -4
- package/src/configs/Constants.js +8 -2
- package/src/configs/SCConfig.js +4 -0
- package/src/context/actionType.ts +7 -5
- package/src/context/mockStore.ts +10 -3
- package/src/context/reducer.ts +29 -15
- package/src/hoc/index.js +3 -0
- package/src/hoc/withRemoteControl.js +10 -0
- package/src/hooks/Common/index.js +2 -2
- package/src/hooks/Common/useDevicesStatus.js +57 -0
- package/src/hooks/Common/useGGHomeDeviceConnected.js +3 -3
- package/src/hooks/IoT/__test__/useGGHomeConnection.test.js +1 -2
- package/src/hooks/IoT/__test__/useRemoteControl.test.js +9 -11
- package/src/hooks/IoT/index.js +9 -1
- package/src/hooks/IoT/useGGHomeConnection.js +0 -1
- package/src/hooks/IoT/useRemoteControl.js +2 -3
- package/src/hooks/IoT/useUnwatchLGDeviceConfigControl.js +29 -0
- package/src/hooks/IoT/useValueEvaluation.js +17 -4
- package/src/hooks/IoT/useWatchConfigs.js +34 -0
- package/src/iot/Monitor.js +13 -20
- package/src/iot/RemoteControl/GoogleHome.js +12 -13
- package/src/iot/RemoteControl/Internet.js +1 -8
- package/src/iot/RemoteControl/LG.js +1 -0
- package/src/iot/RemoteControl/__test__/GoogleHome.test.js +7 -2
- package/src/navigations/UnitStack.js +27 -3
- package/src/screens/AddNewAction/SelectAction.js +1 -1
- package/src/screens/AddNewAction/SetupSensor.js +4 -0
- package/src/screens/AddNewGateway/PlugAndPlay/ConnectWifiWarning.js +44 -78
- package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +15 -35
- package/src/screens/AddNewGateway/PlugAndPlay/__test__/GatewayWifiList.test.js +2 -0
- package/src/screens/AllCamera/__test__/index.test.js +1 -1
- package/src/screens/Device/__test__/detail.test.js +1 -54
- package/src/screens/Device/components/SensorConnectStatusViewHeader.js +18 -8
- package/src/screens/Device/components/SensorDisplayItem.js +2 -2
- package/src/screens/Device/detail.js +36 -30
- package/src/screens/Device/hooks/__test__/useEvaluateValue.test.js +102 -0
- package/src/screens/Device/hooks/useDeviceWatchConfigControl.js +20 -0
- package/src/screens/Device/utils/index.js +45 -0
- package/src/screens/Device/utils/index.test.js +111 -0
- package/src/screens/EmergencyContacts/EmergencyContactsAddNew.js +35 -22
- package/src/screens/EmergencyContacts/EmergencyContactsSelectContacts.js +2 -1
- package/src/screens/EmergencyContacts/__test__/EmergencyContactAddNew.test.js +36 -2
- package/src/screens/MoveToAnotherSubUnit/__test__/index.test.js +0 -2
- package/src/screens/Notification/__test__/NotificationItem.test.js +84 -19
- package/src/screens/Notification/components/NotificationItem.js +64 -31
- package/src/screens/PlayBackCamera/index.js +22 -6
- package/src/screens/ScriptDetail/hooks/useStarredScript.js +2 -2
- package/src/screens/SubUnit/AddSubUnit.js +2 -1
- package/src/screens/Unit/AddMenu.js +4 -0
- package/src/screens/Unit/{SelectFavoritesDevices.js → SelectAddToFavorites.js} +81 -26
- package/src/screens/Unit/{SelectFavoritesDevicesStyles.js → SelectAddToFavoritesStyles.js} +0 -0
- package/src/screens/Unit/__test__/CheckSendEmail.test.js +12 -0
- package/src/screens/Unit/__test__/Detail.test.js +2 -3
- package/src/screens/Unit/__test__/SelectAddToFavorites.test.js +267 -0
- package/src/screens/Unit/components/AutomateScript/index.js +65 -0
- package/src/screens/Unit/components/AutomateScript/styles.js +48 -0
- package/src/screens/Unit/components/MyUnitDevice/index.js +4 -2
- package/src/screens/UnitSummary/components/3PPowerConsumption/index.js +4 -2
- package/src/utils/I18n/translations/en.json +7 -2
- package/src/utils/I18n/translations/vi.json +6 -1
- package/src/utils/Route/index.js +1 -1
- package/src/hooks/Common/useSensorsStatus.js +0 -62
- package/src/screens/Unit/__test__/SelectFavoritesDevices.test.js +0 -110
package/src/context/reducer.ts
CHANGED
|
@@ -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.
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
294
|
-
...currentState.iot.
|
|
295
|
-
|
|
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 {
|
package/src/hoc/index.js
ADDED
|
@@ -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
|
|
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
|
-
|
|
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
|
|
5
|
-
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
190
|
+
sendRemoteCommand.current(sensor, action, data, userId);
|
|
193
191
|
});
|
|
194
192
|
expect(sendCommandOverBluetooth).not.toBeCalled();
|
|
195
193
|
expect(sendCommandOverGoogleHome).not.toBeCalled();
|
package/src/hooks/IoT/index.js
CHANGED
|
@@ -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 {
|
|
7
|
+
export {
|
|
8
|
+
useGGHomeConnection,
|
|
9
|
+
useRemoteControl,
|
|
10
|
+
useValueEvaluations,
|
|
11
|
+
useWatchConfigs,
|
|
12
|
+
useUnwatchLGDeviceConfigControl,
|
|
13
|
+
};
|
|
@@ -15,7 +15,7 @@ const useRemoteControl = () => {
|
|
|
15
15
|
);
|
|
16
16
|
|
|
17
17
|
const sendRemoteCommand = useCallback(
|
|
18
|
-
async (sensor, action, data, userId
|
|
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
|
-
}, [
|
|
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;
|
package/src/iot/Monitor.js
CHANGED
|
@@ -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:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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-
|
|
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-
|
|
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
|
-
},
|
|
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] =
|
|
52
|
-
event.data.new_state.state,
|
|
53
|
-
|
|
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] =
|
|
70
|
-
entity.attributes[attributeName],
|
|
71
|
-
|
|
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] =
|
|
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] =
|
|
109
|
-
entity.attributes[attributeName],
|
|
110
|
-
|
|
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({
|
|
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 () => {
|