@eohjsc/react-native-smart-city 0.3.38 → 0.3.40
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/package.json +1 -1
- package/src/commons/AlertAction/index.js +5 -1
- package/src/commons/Device/ItemDevice.js +21 -34
- package/src/commons/Form/TextInput.js +9 -1
- package/src/commons/StatusBox/index.js +19 -0
- package/src/commons/StatusBox/styles.js +30 -0
- package/src/commons/WrapParallaxScrollView/index.js +6 -1
- package/src/commons/index.js +8 -1
- package/src/configs/API.js +4 -0
- package/src/configs/AccessibilityLabel.js +7 -1
- package/src/configs/Colors.js +1 -0
- package/src/context/actionType.ts +4 -0
- package/src/context/mockStore.ts +3 -0
- package/src/context/reducer.ts +17 -0
- package/src/hooks/Common/index.js +0 -2
- package/src/hooks/Common/useDevicesStatus.js +26 -28
- package/src/hooks/IoT/__test__/useRemoteControl.test.js +3 -0
- package/src/hooks/IoT/index.js +8 -0
- package/src/hooks/IoT/useBluetoothConnection.js +27 -0
- package/src/hooks/IoT/useBluetoothDeviceConnected.js +18 -0
- package/src/hooks/IoT/useEoHBackendDeviceConnected.js +21 -0
- package/src/hooks/{Common → IoT}/useHomeAssistantDeviceConnected.js +0 -0
- package/src/hooks/IoT/useRemoteControl.js +8 -19
- package/src/iot/RemoteControl/Bluetooth.js +5 -12
- package/src/iot/RemoteControl/__test__/Bluetooth.test.js +19 -63
- package/src/navigations/UnitStack.js +11 -1
- package/src/screens/AddLocationMaps/index.js +1 -0
- package/src/screens/AddNewGateway/RenameNewDevices.js +7 -6
- package/src/screens/AddNewGateway/ScanGatewayQR.js +2 -6
- package/src/screens/AddNewGateway/__test__/ScanGatewayQR.test.js +1 -1
- package/src/screens/ConfirmUnitDeletion/index.js +6 -1
- package/src/screens/Device/__test__/detail.test.js +1 -0
- package/src/screens/Device/detail.js +67 -69
- package/src/screens/Gateway/__test__/index.test.js +32 -5
- package/src/screens/Gateway/components/GatewayItem/__test__/index.test.js +83 -0
- package/src/screens/Gateway/components/GatewayItem/index.js +27 -0
- package/src/screens/Gateway/components/GatewayItem/styles.js +62 -0
- package/src/screens/Gateway/hooks/useGateway.js +38 -0
- package/src/screens/Gateway/index.js +77 -5
- package/src/screens/Gateway/styles.js +32 -0
- package/src/screens/SubUnit/AddSubUnit.js +5 -1
- package/src/screens/Unit/MoreMenu.js +3 -3
- package/src/screens/Unit/SelectAddress.js +1 -0
- package/src/screens/Unit/components/MyUnitDevice/index.js +1 -1
- package/src/screens/Unit/hook/useUnitConnectRemoteDevices.js +11 -8
- package/src/screens/UnitSummary/__test__/index.test.js +1 -1
- package/src/screens/UnitSummary/components/RunningDevices/__test__/index.test.js +1 -1
- package/src/screens/UnitSummary/components/RunningDevices/index.js +3 -17
- package/src/utils/I18n/translations/en.json +4 -0
- package/src/utils/I18n/translations/vi.json +4 -0
- package/src/utils/Route/index.js +1 -0
package/package.json
CHANGED
|
@@ -39,7 +39,11 @@ const AlertAction = ({
|
|
|
39
39
|
<Animated.View style={[styles.popoverStyle, animatedStyle]}>
|
|
40
40
|
<View style={styles.modalWrapper}>
|
|
41
41
|
<View style={styles.modalHeader}>
|
|
42
|
-
<Text
|
|
42
|
+
<Text
|
|
43
|
+
semibold
|
|
44
|
+
style={styles.modalHeaderText}
|
|
45
|
+
accessibilityLabel={`${accessibilityLabelPrefix}_TITLE`}
|
|
46
|
+
>
|
|
43
47
|
{title}
|
|
44
48
|
</Text>
|
|
45
49
|
</View>
|
|
@@ -11,9 +11,11 @@ import { useNavigation } from '@react-navigation/native';
|
|
|
11
11
|
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
12
12
|
import ItemQuickAction from '../../commons/Action/ItemQuickAction';
|
|
13
13
|
import Text from '../../commons/Text';
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
import {
|
|
15
|
+
useHomeAssistantDeviceConnected,
|
|
16
|
+
useBluetoothDeviceConnected,
|
|
17
|
+
useEoHBackendDeviceConnected,
|
|
18
|
+
} from '../../hooks/IoT';
|
|
17
19
|
|
|
18
20
|
import { Colors } from '../../configs';
|
|
19
21
|
import {
|
|
@@ -27,20 +29,20 @@ const ItemDevice = memo(
|
|
|
27
29
|
({ svgMain, description, title, sensor, unit, station, wrapStyle }) => {
|
|
28
30
|
const t = useTranslations();
|
|
29
31
|
const navigation = useNavigation();
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const statuses = useSCContextSelector(
|
|
37
|
-
(state) => state.iot.internet.statuses
|
|
38
|
-
);
|
|
32
|
+
|
|
33
|
+
const {
|
|
34
|
+
isConnected: isEoHBackendConnected,
|
|
35
|
+
isFetchingStatus: isFetchingStatusFromEoHBackend,
|
|
36
|
+
} = useEoHBackendDeviceConnected(sensor);
|
|
37
|
+
|
|
39
38
|
const {
|
|
40
39
|
isConnected: isHomeAssistantConnected,
|
|
41
40
|
isConnecting: isHomeAssistantConnecting,
|
|
42
41
|
} = useHomeAssistantDeviceConnected(sensor);
|
|
43
42
|
|
|
43
|
+
const { isConnected: isBluetoothConnected } =
|
|
44
|
+
useBluetoothDeviceConnected(sensor);
|
|
45
|
+
|
|
44
46
|
const goToSensorDisplay = useCallback(() => {
|
|
45
47
|
navigation.navigate(Routes.DeviceDetail, {
|
|
46
48
|
unitData: unit,
|
|
@@ -50,30 +52,15 @@ const ItemDevice = memo(
|
|
|
50
52
|
});
|
|
51
53
|
}, [navigation, sensor, station, title, unit]);
|
|
52
54
|
|
|
53
|
-
const isConnectedViaInternet =
|
|
54
|
-
isNetworkConnected &&
|
|
55
|
-
!!sensor &&
|
|
56
|
-
sensor.id in statuses &&
|
|
57
|
-
statuses[sensor.id]?.isConnected;
|
|
58
|
-
|
|
59
|
-
const isFetchingStatus =
|
|
60
|
-
isNetworkConnected && !!sensor && !(sensor.id in statuses);
|
|
61
|
-
|
|
62
|
-
const isConnectedViaBLE =
|
|
63
|
-
isBluetoothEnabled &&
|
|
64
|
-
isBluetoothDeviceConnected(
|
|
65
|
-
sensor?.remote_control_options?.bluetooth?.address
|
|
66
|
-
);
|
|
67
|
-
|
|
68
55
|
const borderColor = (() => {
|
|
69
56
|
if (!!sensor && sensor?.is_managed_by_backend) {
|
|
70
57
|
if (sensor?.device_type === DEVICE_TYPE.LG_THINQ) {
|
|
71
58
|
return Colors.Gray4;
|
|
72
59
|
}
|
|
73
|
-
if (
|
|
60
|
+
if (isBluetoothConnected) {
|
|
74
61
|
return Colors.Gray4;
|
|
75
62
|
}
|
|
76
|
-
if (
|
|
63
|
+
if (isFetchingStatusFromEoHBackend || isEoHBackendConnected) {
|
|
77
64
|
return Colors.Gray4;
|
|
78
65
|
}
|
|
79
66
|
return Colors.Red6;
|
|
@@ -92,13 +79,13 @@ const ItemDevice = memo(
|
|
|
92
79
|
if (sensor?.device_type === DEVICE_TYPE.LG_THINQ) {
|
|
93
80
|
return t('connected');
|
|
94
81
|
}
|
|
95
|
-
if (
|
|
82
|
+
if (isBluetoothConnected) {
|
|
96
83
|
return t('connected');
|
|
97
84
|
}
|
|
98
|
-
if (
|
|
85
|
+
if (isFetchingStatusFromEoHBackend) {
|
|
99
86
|
return '';
|
|
100
87
|
}
|
|
101
|
-
if (
|
|
88
|
+
if (isEoHBackendConnected) {
|
|
102
89
|
return t('connected');
|
|
103
90
|
}
|
|
104
91
|
return t('disconnected');
|
|
@@ -120,10 +107,10 @@ const ItemDevice = memo(
|
|
|
120
107
|
if (sensor?.device_type === DEVICE_TYPE.LG_THINQ) {
|
|
121
108
|
return true;
|
|
122
109
|
}
|
|
123
|
-
if (
|
|
110
|
+
if (isBluetoothConnected) {
|
|
124
111
|
return true;
|
|
125
112
|
}
|
|
126
|
-
if (
|
|
113
|
+
if (isFetchingStatusFromEoHBackend) {
|
|
127
114
|
return false;
|
|
128
115
|
}
|
|
129
116
|
return true;
|
|
@@ -29,6 +29,7 @@ const _TextInput = ({
|
|
|
29
29
|
accessibilityLabel,
|
|
30
30
|
selection,
|
|
31
31
|
onSelectionChange,
|
|
32
|
+
accessibilityLabelError,
|
|
32
33
|
}) => {
|
|
33
34
|
const errorStyle = !!errorText && styles.errorWrap;
|
|
34
35
|
return (
|
|
@@ -70,7 +71,14 @@ const _TextInput = ({
|
|
|
70
71
|
onSelectionChange={onSelectionChange}
|
|
71
72
|
/>
|
|
72
73
|
{extraText && extraText}
|
|
73
|
-
{!!errorText &&
|
|
74
|
+
{!!errorText && (
|
|
75
|
+
<Text
|
|
76
|
+
accessibilityLabel={accessibilityLabelError}
|
|
77
|
+
style={styles.errorText}
|
|
78
|
+
>
|
|
79
|
+
{errorText}
|
|
80
|
+
</Text>
|
|
81
|
+
)}
|
|
74
82
|
</View>
|
|
75
83
|
);
|
|
76
84
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React, { memo } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import Text from '../Text';
|
|
5
|
+
import styles from './styles';
|
|
6
|
+
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
7
|
+
|
|
8
|
+
const StatusBox = ({ status }) => {
|
|
9
|
+
const t = useTranslations();
|
|
10
|
+
return (
|
|
11
|
+
<View style={[styles.viewStatus, status && styles.viewOnline]}>
|
|
12
|
+
<Text style={[styles.textStatus, status && styles.textOnline]}>
|
|
13
|
+
{t(status ? 'online' : 'offline')}
|
|
14
|
+
</Text>
|
|
15
|
+
</View>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default memo(StatusBox);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
import { Colors } from '../../configs';
|
|
3
|
+
|
|
4
|
+
export default StyleSheet.create({
|
|
5
|
+
viewStatus: {
|
|
6
|
+
width: 65,
|
|
7
|
+
paddingHorizontal: 8,
|
|
8
|
+
paddingVertical: 4,
|
|
9
|
+
borderRadius: 54,
|
|
10
|
+
backgroundColor: Colors.White,
|
|
11
|
+
borderColor: Colors.Neutral.Neutral3,
|
|
12
|
+
borderWidth: 1,
|
|
13
|
+
},
|
|
14
|
+
textStatus: {
|
|
15
|
+
fontStyle: 'normal',
|
|
16
|
+
fontWeight: 600,
|
|
17
|
+
letterSpacing: 0.04,
|
|
18
|
+
fontSize: 12,
|
|
19
|
+
lineHeight: 16,
|
|
20
|
+
textTransform: 'uppercase',
|
|
21
|
+
textAlign: 'center',
|
|
22
|
+
},
|
|
23
|
+
textOnline: {
|
|
24
|
+
fontStyle: 'bold',
|
|
25
|
+
},
|
|
26
|
+
viewOnline: {
|
|
27
|
+
backgroundColor: Colors.LightGreen,
|
|
28
|
+
borderWidth: 0,
|
|
29
|
+
},
|
|
30
|
+
});
|
|
@@ -37,7 +37,12 @@ const WrapParallaxScrollView = ({
|
|
|
37
37
|
hideRightPlus={hideRightPlus}
|
|
38
38
|
idButtonMore={idButtonMore}
|
|
39
39
|
/>
|
|
40
|
-
<Text
|
|
40
|
+
<Text
|
|
41
|
+
numberOfLines={1}
|
|
42
|
+
semibold
|
|
43
|
+
style={styles.nameUnit}
|
|
44
|
+
accessibilityLabel={AccessibilityLabel.HEADER_UNIT_BUTTON_TEXT}
|
|
45
|
+
>
|
|
41
46
|
{title}
|
|
42
47
|
</Text>
|
|
43
48
|
{contentBackground}
|
package/src/commons/index.js
CHANGED
|
@@ -16,7 +16,10 @@ import RadioCircle from './RadioCircle';
|
|
|
16
16
|
import { CircleButton } from './CircleButton';
|
|
17
17
|
import HorizontalPicker from './HorizontalPicker';
|
|
18
18
|
import FullLoading from './FullLoading';
|
|
19
|
-
|
|
19
|
+
import Text from './Text';
|
|
20
|
+
import { HeaderCustom } from './Header';
|
|
21
|
+
import StatusBox from './StatusBox';
|
|
22
|
+
import WrapHeaderScrollable from './Sharing/WrapHeaderScrollable';
|
|
20
23
|
export {
|
|
21
24
|
ButtonPopup,
|
|
22
25
|
CircleView,
|
|
@@ -36,4 +39,8 @@ export {
|
|
|
36
39
|
CircleButton,
|
|
37
40
|
HorizontalPicker,
|
|
38
41
|
FullLoading,
|
|
42
|
+
Text,
|
|
43
|
+
HeaderCustom,
|
|
44
|
+
StatusBox,
|
|
45
|
+
WrapHeaderScrollable,
|
|
39
46
|
};
|
package/src/configs/API.js
CHANGED
|
@@ -211,6 +211,10 @@ const API = {
|
|
|
211
211
|
GET_TEMPLATES: '/property_manager/iot_dashboard/dev_mode/templates/',
|
|
212
212
|
GET_WIDGETS: (templateId) =>
|
|
213
213
|
`/property_manager/iot_dashboard/dev_mode/templates/${templateId}/list_widgets/`,
|
|
214
|
+
GATEWAY: {
|
|
215
|
+
LIST: () => '/chip_manager/developer_mode_chips/',
|
|
216
|
+
DETAIL: (id) => `/chip_manager/developer_mode_chips/${id}/`,
|
|
217
|
+
},
|
|
214
218
|
},
|
|
215
219
|
};
|
|
216
220
|
|
|
@@ -43,6 +43,8 @@ export default {
|
|
|
43
43
|
|
|
44
44
|
// ConfirmUnitDeletion
|
|
45
45
|
CONFIRM_UNIT_DELETION_BUTTON: 'CONFIRM_UNIT_DELETION_BUTTON',
|
|
46
|
+
CONFIRM_UNIT_DELETION_CONFIRM_FIELD: 'CONFIRM_UNIT_DELETION_CONFIRM_FIELD',
|
|
47
|
+
CONFIRM_UNIT_DELETION_CONFIRM_ERROR: 'CONFIRM_UNIT_DELETION_CONFIRM_ERROR',
|
|
46
48
|
|
|
47
49
|
//member list
|
|
48
50
|
SHARING_MEMBER: 'SHARING_MEMBER',
|
|
@@ -252,6 +254,8 @@ export default {
|
|
|
252
254
|
EMERGENCY_BUTTON: 'EMERGENCY_BUTTON',
|
|
253
255
|
|
|
254
256
|
// ADD SUB UNIT
|
|
257
|
+
ADD_SUB_UNIT_SCREEN: 'ADD_SUB_UNIT_SCREEN',
|
|
258
|
+
ADD_SUB_UNIT_NAME_FIELD: 'ADD_SUB_UNIT_NAME_FIELD',
|
|
255
259
|
ADD_SUB_UNIT_BUTTON_CHOOSE_PHOTO: 'ADD_SUB_UNIT_BUTTON_CHOOSE_PHOTO',
|
|
256
260
|
ADD_SUB_UNIT_BUTTON_CHOOSE_LOCATION: 'ADD_SUB_UNIT_BUTTON_CHOOSE_LOCATION',
|
|
257
261
|
|
|
@@ -440,6 +444,7 @@ export default {
|
|
|
440
444
|
|
|
441
445
|
// Header Unit
|
|
442
446
|
HEADER_UNIT_BUTTON_BACK: 'HEADER_UNIT_BUTTON_BACK',
|
|
447
|
+
HEADER_UNIT_BUTTON_TEXT: 'HEADER_UNIT_BUTTON_TEXT',
|
|
443
448
|
HEADER_UNIT_BUTTON_ADD: 'HEADER_UNIT_BUTTON_ADD',
|
|
444
449
|
HEADER_UNIT_BUTTON_MORE: 'HEADER_UNIT_BUTTON_MORE',
|
|
445
450
|
|
|
@@ -633,7 +638,8 @@ export default {
|
|
|
633
638
|
BUTTON_CANCEL_EDIT_ACTION_LIST: 'BUTTON_CANCEL_EDIT_ACTION_LIST',
|
|
634
639
|
BUTTON_SAVE_EDIT_ACTION_LIST: 'BUTTON_SAVE_EDIT_ACTION_LIST',
|
|
635
640
|
BUTTON_REMOVE_EDIT_ACTION_LIST: 'BUTTON_REMOVE_EDIT_ACTION_LIST',
|
|
636
|
-
|
|
641
|
+
// GATEWAY
|
|
642
|
+
LIST_GATEWAY: 'LIST_GATEWAY',
|
|
637
643
|
//Notification
|
|
638
644
|
CUSTOM_TEXT: 'CUSTOM_TEXT',
|
|
639
645
|
//ButtonWrapper
|
package/src/configs/Colors.js
CHANGED
|
@@ -17,6 +17,7 @@ export const Action = {
|
|
|
17
17
|
SET_STARRED_SCRIPTS: 'SET_STARRED_SCRIPTS',
|
|
18
18
|
STAR_SCRIPTS: 'STAR_SCRIPTS',
|
|
19
19
|
UNSTAR_SCRIPTS: 'UNSTAR_SCRIPTS',
|
|
20
|
+
SET_BLUETOOTH_CONNECTED_DEVICE: 'SET_BLUETOOTH_CONNECTED_DEVICE',
|
|
20
21
|
SET_HOME_ASSISTANT_CONNECTIONS: 'SET_HOME_ASSISTANT_CONNECTIONS',
|
|
21
22
|
CHANGE_HOME_ASSISTANT_CONN_STATE: 'CHANGE_HOME_ASSISTANT_CONN_STATE',
|
|
22
23
|
SET_LG_THINQ_CONNECTED: 'SET_LG_THINQ_CONNECTED',
|
|
@@ -95,6 +96,9 @@ export type AppType = {
|
|
|
95
96
|
};
|
|
96
97
|
|
|
97
98
|
export type IoTType = {
|
|
99
|
+
bluetooth: {
|
|
100
|
+
connectedDevices: {};
|
|
101
|
+
};
|
|
98
102
|
homeassistant: {
|
|
99
103
|
connections: {};
|
|
100
104
|
};
|
package/src/context/mockStore.ts
CHANGED
package/src/context/reducer.ts
CHANGED
|
@@ -68,6 +68,9 @@ export const initialState = {
|
|
|
68
68
|
isLockWhenPickColor: false,
|
|
69
69
|
},
|
|
70
70
|
iot: {
|
|
71
|
+
bluetooth: {
|
|
72
|
+
connectedDevices: {},
|
|
73
|
+
},
|
|
71
74
|
homeassistant: {
|
|
72
75
|
connections: {},
|
|
73
76
|
},
|
|
@@ -291,6 +294,20 @@ export const reducer = (currentState: ContextData, action: Action) => {
|
|
|
291
294
|
},
|
|
292
295
|
};
|
|
293
296
|
|
|
297
|
+
case Action.SET_BLUETOOTH_CONNECTED_DEVICE:
|
|
298
|
+
return {
|
|
299
|
+
...currentState,
|
|
300
|
+
iot: {
|
|
301
|
+
...currentState.iot,
|
|
302
|
+
bluetooth: {
|
|
303
|
+
...currentState.iot.bluetooth,
|
|
304
|
+
connectedDevices: {
|
|
305
|
+
...currentState.iot.bluetooth.connectedDevices,
|
|
306
|
+
[payload.name]: payload.device,
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
},
|
|
310
|
+
};
|
|
294
311
|
case Action.SET_HOME_ASSISTANT_CONNECTIONS:
|
|
295
312
|
return {
|
|
296
313
|
...currentState,
|
|
@@ -5,7 +5,6 @@ import useKeyboardShow from './useKeyboardShow';
|
|
|
5
5
|
import usePopover from './usePopover';
|
|
6
6
|
import useTitleHeader from './useTitleHeader';
|
|
7
7
|
import useDevicesStatus from './useDevicesStatus';
|
|
8
|
-
import useHomeAssistantDeviceConnected from './useHomeAssistantDeviceConnected';
|
|
9
8
|
import { useBlockBackAndroid } from './useBlockBackAndroid';
|
|
10
9
|
import { useIsOwnerOfUnit } from './useIsOwnerOfUnit';
|
|
11
10
|
import { useStatusBar } from './useStatusBar';
|
|
@@ -23,5 +22,4 @@ export {
|
|
|
23
22
|
useStatusBar,
|
|
24
23
|
useGetIdUser,
|
|
25
24
|
useDevicesStatus,
|
|
26
|
-
useHomeAssistantDeviceConnected,
|
|
27
25
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { useCallback, useContext } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { useFocusEffect } from '@react-navigation/native';
|
|
1
|
+
import { useCallback, useContext, useEffect } from 'react';
|
|
2
|
+
import { useIsFocused } from '@react-navigation/native';
|
|
4
3
|
import { SCContext, useSCContextSelector } from '../../context';
|
|
5
4
|
import { axiosGet } from '../../utils/Apis/axios';
|
|
6
5
|
import { API } from '../../configs';
|
|
@@ -13,8 +12,13 @@ const useDevicesStatus = (unit, devices) => {
|
|
|
13
12
|
const isNetworkConnected = useSCContextSelector(
|
|
14
13
|
(state) => state.app.isNetworkConnected
|
|
15
14
|
);
|
|
15
|
+
const isFocused = useIsFocused();
|
|
16
16
|
|
|
17
17
|
const getDevicesStatus = useCallback(async (_unit, _devices) => {
|
|
18
|
+
if (timeoutId) {
|
|
19
|
+
clearTimeout(timeoutId);
|
|
20
|
+
timeoutId = 0;
|
|
21
|
+
}
|
|
18
22
|
const params = new URLSearchParams();
|
|
19
23
|
_devices.forEach((device) => {
|
|
20
24
|
params.append('sensors', device.id);
|
|
@@ -30,32 +34,26 @@ const useDevicesStatus = (unit, devices) => {
|
|
|
30
34
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
31
35
|
}, []);
|
|
32
36
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (!isFocused) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (!devices?.length || !isNetworkConnected) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
39
44
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return () => {
|
|
53
|
-
clearTimeout(timeoutId);
|
|
54
|
-
task.cancel();
|
|
55
|
-
};
|
|
56
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
57
|
-
}, [unit, devices, isNetworkConnected])
|
|
58
|
-
);
|
|
45
|
+
const managedDevices = devices.filter(
|
|
46
|
+
(device) => device?.is_managed_by_backend
|
|
47
|
+
);
|
|
48
|
+
if (!managedDevices.length) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
getDevicesStatus(unit, devices);
|
|
52
|
+
return () => {
|
|
53
|
+
clearTimeout(timeoutId);
|
|
54
|
+
timeoutId = 0;
|
|
55
|
+
};
|
|
56
|
+
}, [getDevicesStatus, unit, devices, isNetworkConnected, isFocused]);
|
|
59
57
|
};
|
|
60
58
|
|
|
61
59
|
export default useDevicesStatus;
|
|
@@ -88,6 +88,8 @@ describe('Test useRemoteControl', () => {
|
|
|
88
88
|
});
|
|
89
89
|
|
|
90
90
|
it('test send remote command via bluetooth failed then send via internet', async () => {
|
|
91
|
+
action.command_prefer_over_bluetooth = true;
|
|
92
|
+
action.command_prefer_over_internet = true;
|
|
91
93
|
const { result: sendRemoteCommand } = renderHook(() => useRemoteControl(), {
|
|
92
94
|
wrapper,
|
|
93
95
|
});
|
|
@@ -156,6 +158,7 @@ describe('Test useRemoteControl', () => {
|
|
|
156
158
|
data,
|
|
157
159
|
'internet'
|
|
158
160
|
);
|
|
161
|
+
expect(sendCommandOverInternet).toBeCalledTimes(1);
|
|
159
162
|
expect(sendCommandOverBluetooth).not.toBeCalled();
|
|
160
163
|
expect(sendCommandOverHomeAssistant).not.toBeCalled();
|
|
161
164
|
expect(sendCommandOverLGThinq).not.toBeCalled();
|
package/src/hooks/IoT/index.js
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
|
+
import useBluetoothConnection from './useBluetoothConnection';
|
|
1
2
|
import useHomeAssistantConnection from './useHomeAssistantConnection';
|
|
2
3
|
import useRemoteControl from './useRemoteControl';
|
|
3
4
|
import useValueEvaluations from './useValueEvaluation';
|
|
4
5
|
import useWatchConfigs from './useWatchConfigs';
|
|
5
6
|
import useUnwatchLGDeviceConfigControl from './useUnwatchLGDeviceConfigControl';
|
|
7
|
+
import useHomeAssistantDeviceConnected from './useHomeAssistantDeviceConnected';
|
|
8
|
+
import useBluetoothDeviceConnected from './useBluetoothDeviceConnected';
|
|
9
|
+
import useEoHBackendDeviceConnected from './useEoHBackendDeviceConnected';
|
|
6
10
|
|
|
7
11
|
export {
|
|
12
|
+
useBluetoothConnection,
|
|
8
13
|
useHomeAssistantConnection,
|
|
9
14
|
useRemoteControl,
|
|
10
15
|
useValueEvaluations,
|
|
11
16
|
useWatchConfigs,
|
|
12
17
|
useUnwatchLGDeviceConfigControl,
|
|
18
|
+
useHomeAssistantDeviceConnected,
|
|
19
|
+
useBluetoothDeviceConnected,
|
|
20
|
+
useEoHBackendDeviceConnected,
|
|
13
21
|
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useContext, useCallback } from 'react';
|
|
2
|
+
import { SCContext } from '../../context';
|
|
3
|
+
import { Action } from '../../context/actionType';
|
|
4
|
+
import { scanBluetoothDevices } from '../../iot/RemoteControl/Bluetooth';
|
|
5
|
+
|
|
6
|
+
const useBluetoothConnection = () => {
|
|
7
|
+
const { setAction } = useContext(SCContext);
|
|
8
|
+
|
|
9
|
+
const onDeviceFound = useCallback(async (name, device) => {
|
|
10
|
+
setAction(Action.SET_BLUETOOTH_CONNECTED_DEVICE, { name, device });
|
|
11
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
12
|
+
}, []);
|
|
13
|
+
|
|
14
|
+
const bluetoothScanDevices = useCallback(
|
|
15
|
+
(addresses) => {
|
|
16
|
+
scanBluetoothDevices(addresses, onDeviceFound);
|
|
17
|
+
},
|
|
18
|
+
[onDeviceFound]
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
onDeviceFound,
|
|
23
|
+
bluetoothScanDevices,
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default useBluetoothConnection;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useSCContextSelector } from '../../context';
|
|
2
|
+
|
|
3
|
+
const useBluetoothDeviceConnected = (device) => {
|
|
4
|
+
const connectedDevices = useSCContextSelector(
|
|
5
|
+
(state) => state.iot.bluetooth.connectedDevices
|
|
6
|
+
);
|
|
7
|
+
const isBluetoothEnabled = useSCContextSelector((state) => {
|
|
8
|
+
return state.app.isBluetoothEnabled;
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
const isConnected =
|
|
12
|
+
isBluetoothEnabled &&
|
|
13
|
+
!!connectedDevices[device?.remote_control_options?.bluetooth?.address];
|
|
14
|
+
|
|
15
|
+
return { isConnected };
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default useBluetoothDeviceConnected;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useSCContextSelector } from '../../context';
|
|
2
|
+
|
|
3
|
+
const useEoHBackendDeviceConnected = (device) => {
|
|
4
|
+
const isNetworkConnected = useSCContextSelector(
|
|
5
|
+
(state) => state.app.isNetworkConnected
|
|
6
|
+
);
|
|
7
|
+
const statuses = useSCContextSelector((state) => state.iot.internet.statuses);
|
|
8
|
+
|
|
9
|
+
const isConnected =
|
|
10
|
+
isNetworkConnected &&
|
|
11
|
+
!!device &&
|
|
12
|
+
device.id in statuses &&
|
|
13
|
+
statuses[device.id]?.isConnected;
|
|
14
|
+
|
|
15
|
+
const isFetchingStatus =
|
|
16
|
+
isNetworkConnected && !!device && !(device.id in statuses);
|
|
17
|
+
|
|
18
|
+
return { isConnected, isFetchingStatus };
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default useEoHBackendDeviceConnected;
|
|
File without changes
|
|
@@ -15,7 +15,7 @@ const useRemoteControl = () => {
|
|
|
15
15
|
);
|
|
16
16
|
|
|
17
17
|
const sendRemoteCommand = useCallback(
|
|
18
|
-
async (
|
|
18
|
+
async (device, action, data, userId) => {
|
|
19
19
|
// No action, raise not authorized
|
|
20
20
|
let result = false;
|
|
21
21
|
if (!action) {
|
|
@@ -27,39 +27,28 @@ const useRemoteControl = () => {
|
|
|
27
27
|
|
|
28
28
|
if (action.command_prefer_over_bluetooth) {
|
|
29
29
|
try {
|
|
30
|
-
result = await sendCommandOverBluetooth(
|
|
30
|
+
result = await sendCommandOverBluetooth(device, action, data, userId);
|
|
31
31
|
} catch (err) {
|
|
32
|
-
|
|
33
|
-
if (err === SEND_COMMAND_OVER_BLUETOOTH_FAIL) {
|
|
34
|
-
result = await sendCommandOverInternet(
|
|
35
|
-
sensor,
|
|
36
|
-
action,
|
|
37
|
-
data,
|
|
38
|
-
'bluetooth'
|
|
39
|
-
);
|
|
40
|
-
} else {
|
|
32
|
+
if (err !== SEND_COMMAND_OVER_BLUETOOTH_FAIL) {
|
|
41
33
|
throw err;
|
|
42
34
|
}
|
|
35
|
+
result = false;
|
|
43
36
|
}
|
|
44
37
|
}
|
|
45
38
|
|
|
46
|
-
if (
|
|
47
|
-
(action.command_prefer_over_internet ||
|
|
48
|
-
action.command_prefer_over_bluetooth) &&
|
|
49
|
-
!result
|
|
50
|
-
) {
|
|
39
|
+
if (action.command_prefer_over_internet && !result) {
|
|
51
40
|
result = await sendCommandOverInternet(
|
|
52
|
-
|
|
41
|
+
device,
|
|
53
42
|
action,
|
|
54
43
|
data,
|
|
55
|
-
'internet'
|
|
44
|
+
action.command_prefer_over_bluetooth ? 'bluetooth' : 'internet'
|
|
56
45
|
);
|
|
57
46
|
}
|
|
58
47
|
|
|
59
48
|
if (action.command_prefer_over_googlehome && !result) {
|
|
60
49
|
result = await sendCommandOverHomeAssistant(
|
|
61
50
|
homeAssistantConnections,
|
|
62
|
-
|
|
51
|
+
device,
|
|
63
52
|
action,
|
|
64
53
|
data
|
|
65
54
|
);
|
|
@@ -22,24 +22,17 @@ export const clearFoundDevices = () => {
|
|
|
22
22
|
}
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
if (state === 'PoweredOn') {
|
|
27
|
-
ToastBottomHelper.success(t('text_ble_is_powered_on'));
|
|
28
|
-
realScanBluetoothDevices();
|
|
29
|
-
}
|
|
30
|
-
}, true);
|
|
31
|
-
|
|
32
|
-
export const scanBluetoothDevices = (names) => {
|
|
25
|
+
export const scanBluetoothDevices = (names, onDeviceFound) => {
|
|
33
26
|
names.map((name) => {
|
|
34
27
|
if (bluetoothDevices[name]) {
|
|
35
28
|
return;
|
|
36
29
|
}
|
|
37
30
|
needToScanDevices.push(name);
|
|
38
31
|
});
|
|
39
|
-
realScanBluetoothDevices();
|
|
32
|
+
realScanBluetoothDevices(onDeviceFound);
|
|
40
33
|
};
|
|
41
34
|
|
|
42
|
-
const realScanBluetoothDevices = () => {
|
|
35
|
+
export const realScanBluetoothDevices = (onDeviceFound) => {
|
|
43
36
|
if (!needToScanDevices.length) {
|
|
44
37
|
return;
|
|
45
38
|
}
|
|
@@ -67,9 +60,9 @@ const realScanBluetoothDevices = () => {
|
|
|
67
60
|
const index = needToScanDevices.indexOf(name);
|
|
68
61
|
needToScanDevices.splice(index, 1);
|
|
69
62
|
|
|
70
|
-
ToastBottomHelper.success(t(`Found bluetooth ${name} for remote control`));
|
|
71
|
-
|
|
72
63
|
bluetoothDevices[name] = device;
|
|
64
|
+
onDeviceFound && onDeviceFound(name, device);
|
|
65
|
+
|
|
73
66
|
if (!needToScanDevices.length) {
|
|
74
67
|
try {
|
|
75
68
|
bleManager.stopDeviceScan();
|