@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.
- 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 +22 -5
- 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 +3 -3
- package/src/configs/Constants.js +12 -2
- package/src/configs/SCConfig.js +4 -0
- package/src/context/actionType.ts +5 -3
- package/src/context/mockStore.ts +10 -3
- package/src/context/reducer.ts +26 -12
- 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/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 +24 -0
- 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 +22 -19
- 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/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/Timer.js +3 -0
- package/src/screens/PlayBackCamera/__test__/index.test.js +8 -1
- package/src/screens/PlayBackCamera/index.js +86 -49
- package/src/screens/SubUnit/AddSubUnit.js +2 -1
- package/src/screens/Unit/AddMenu.js +4 -0
- package/src/screens/Unit/Detail.js +16 -10
- package/src/screens/Unit/__test__/CheckSendEmail.test.js +12 -0
- package/src/screens/Unit/__test__/Detail.test.js +2 -3
- package/src/screens/Unit/components/MyUnitDevice/index.js +4 -2
- package/src/screens/Unit/components/__test__/AutomateScript.test.js +116 -0
- package/src/screens/UnitSummary/components/3PPowerConsumption/index.js +4 -2
- package/src/utils/I18n/translations/en.json +5 -1
- package/src/utils/I18n/translations/vi.json +4 -0
- 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
|
|
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;
|
|
@@ -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 () => {
|
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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 ? (
|