@eohjsc/react-native-smart-city 0.3.10 → 0.3.13

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 (39) hide show
  1. package/index.js +2 -0
  2. package/package.json +1 -1
  3. package/src/commons/Action/ItemQuickAction.js +1 -1
  4. package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +2 -0
  5. package/src/commons/ActionGroup/__test__/NumberUpDownTemplate.test.js +1 -1
  6. package/src/commons/ActionGroup/__test__/index.test.js +1 -1
  7. package/src/commons/Device/HistoryChart.js +2 -2
  8. package/src/commons/Device/ItemDevice.js +2 -2
  9. package/src/commons/OneTapTemplate/NumberUpDownActionTemplate.js +5 -1
  10. package/src/commons/SubUnit/Favorites/index.js +6 -2
  11. package/src/configs/API.js +4 -0
  12. package/src/configs/SCConfig.js +1 -1
  13. package/src/context/actionType.ts +5 -2
  14. package/src/context/mockStore.ts +17 -3
  15. package/src/context/reducer.ts +38 -4
  16. package/src/hooks/IoT/__test__/useValueEvaluation.test.js +58 -0
  17. package/src/hooks/IoT/index.js +2 -1
  18. package/src/hooks/IoT/useValueEvaluation.js +45 -0
  19. package/src/hooks/useReceiveNotifications.js +12 -18
  20. package/src/navigations/UnitStack.js +8 -0
  21. package/src/screens/AddNewAction/SelectAction.js +3 -2
  22. package/src/screens/AddNewAction/SetupSensor.js +3 -2
  23. package/src/screens/Device/detail.js +18 -27
  24. package/src/screens/Device/hooks/useEvaluateValue.js +97 -0
  25. package/src/screens/Device/hooks/useFavoriteDevice.js +2 -2
  26. package/src/screens/ScriptDetail/index.js +13 -3
  27. package/src/screens/Unit/Detail.js +10 -5
  28. package/src/screens/Unit/SelectAddress.js +1 -3
  29. package/src/screens/Unit/SelectDevices.js +158 -0
  30. package/src/screens/Unit/SelectDevicesStyles.js +40 -0
  31. package/src/screens/Unit/Summaries.js +1 -1
  32. package/src/screens/Unit/__test__/SelectAddress.test.js +90 -1
  33. package/src/screens/Unit/__test__/SelectDevices.test.js +110 -0
  34. package/src/screens/UnitSummary/components/RunningDevices/index.js +3 -1
  35. package/src/utils/Apis/axios.js +6 -0
  36. package/src/utils/I18n/translations/en.json +2 -0
  37. package/src/utils/I18n/translations/vi.json +2 -0
  38. package/src/utils/Route/index.js +1 -0
  39. package/src/utils/Validation.js +3 -0
package/index.js CHANGED
@@ -17,6 +17,7 @@ import NotificationStack from './src/navigations/NotificationStack';
17
17
  import MyPinnedSharedUnit from './src/commons/Dashboard/MyPinnedSharedUnit';
18
18
  import MyUnit from './src/commons/Dashboard/MyUnit';
19
19
  import SharedUnit from './src/commons/Unit/SharedUnit';
20
+ import { Action } from './src/context/actionType';
20
21
 
21
22
  export {
22
23
  AddSubUnitStack,
@@ -40,4 +41,5 @@ export {
40
41
  SharedUnit,
41
42
  MyUnit,
42
43
  SCWrapper,
44
+ Action,
43
45
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@eohjsc/react-native-smart-city",
3
3
  "title": "React Native Smart Home",
4
- "version": "0.3.10",
4
+ "version": "0.3.13",
5
5
  "description": "TODO",
6
6
  "main": "index.js",
7
7
  "files": [
@@ -7,7 +7,7 @@ import { useRemoteControl } from '../../hooks/IoT';
7
7
  import { useConfigGlobalState } from '../../iot/states';
8
8
  import IconComponent from '../IconComponent';
9
9
 
10
- const ItemQuickAction = memo(({ sensor, wrapperStyle, setStatus, unit }) => {
10
+ const ItemQuickAction = memo(({ sensor, wrapperStyle, setStatus }) => {
11
11
  const [isSendingCommand, setIsSendingCommand] = useState(false);
12
12
  const [action, setAction] = useState(sensor.action);
13
13
  // eslint-disable-next-line no-unused-vars
@@ -47,6 +47,8 @@ const NumberUpDownActionTemplate = ({ actionGroup, doAction, sensor }) => {
47
47
  const configValue = configValues[config];
48
48
  if (configValue !== null && configValue !== undefined) {
49
49
  setValue(configValue);
50
+ } else {
51
+ setValue(valueDefault);
50
52
  }
51
53
  // eslint-disable-next-line react-hooks/exhaustive-deps
52
54
  }, [JSON.stringify(configValues)]);
@@ -326,7 +326,7 @@ describe('Test NumberUpDownActionTemplate', () => {
326
326
  });
327
327
  const instance = wrapper.root;
328
328
  const text = instance.findAllByType(ActivityIndicator);
329
- expect(text).toHaveLength(1);
329
+ expect(text).toHaveLength(0);
330
330
  });
331
331
  test('action up sensor device type is GOOGLE_HOME', async () => {
332
332
  const mockDoAction = jest.fn();
@@ -363,7 +363,7 @@ describe('Test ActionGroup', () => {
363
363
  });
364
364
  const instance = wrapper.root;
365
365
  const activity = instance.findAllByType(ActivityIndicator);
366
- expect(activity.length).toEqual(1);
366
+ expect(activity.length).toEqual(0);
367
367
  });
368
368
 
369
369
  test('render ActionGroup StatesGridActionTemplate', async () => {
@@ -234,7 +234,7 @@ const HistoryChart = memo(
234
234
  )}
235
235
  <DateTimePickerModal
236
236
  isVisible={eventPicker.showModalStart}
237
- date={eventPicker.startTime.valueOf()}
237
+ date={eventPicker.startTime?._d}
238
238
  mode={formatType || 'datetime'}
239
239
  onConfirm={onConfirmStart}
240
240
  onCancel={onCancel}
@@ -244,7 +244,7 @@ const HistoryChart = memo(
244
244
  />
245
245
  <DateTimePickerModal
246
246
  isVisible={eventPicker.showModalEnd}
247
- date={eventPicker.endTime.valueOf()}
247
+ date={eventPicker.endTime?._d}
248
248
  mode={formatType || 'datetime'}
249
249
  onConfirm={onConfirmEnd}
250
250
  onCancel={onCancel}
@@ -82,7 +82,7 @@ const ItemDevice = memo(
82
82
  const textConnected = isConnected
83
83
  ? t('connected')
84
84
  : isConnecting
85
- ? ''
85
+ ? t('connecting')
86
86
  : t('disconnected');
87
87
 
88
88
  return (
@@ -98,7 +98,7 @@ const ItemDevice = memo(
98
98
  <TouchableOpacity onPress={goToSensorDisplay}>
99
99
  <IconComponent icon={sensor.icon} iconKit={sensor.icon_kit} />
100
100
  </TouchableOpacity>
101
- <ItemQuickAction sensor={sensor} unit={unit} />
101
+ {!isConnecting && <ItemQuickAction sensor={sensor} unit={unit} />}
102
102
  </View>
103
103
  <TouchableOpacity onPress={goToSensorDisplay}>
104
104
  <Text
@@ -19,16 +19,20 @@ const NumberUpDownActionTemplate = memo(({ data, onSelectAction }) => {
19
19
  const { configuration, template, title } = data;
20
20
  const { config, text_format, min_value, max_value, action } = configuration;
21
21
  const [configValues] = useConfigGlobalState('configValues');
22
- const [value, setValue] = useState((config && configValues[config]) || 28);
22
+ const [value, setValue] = useState();
23
23
  const [actionName, setActionName] = useState(null);
24
+ const valueDefault = 28;
24
25
 
25
26
  useEffect(() => {
26
27
  if (!config) {
28
+ setValue(valueDefault);
27
29
  return;
28
30
  }
29
31
  const configValue = configValues[config];
30
32
  if (configValue !== null && configValue !== undefined) {
31
33
  setValue(configValue);
34
+ } else {
35
+ setValue(valueDefault);
32
36
  }
33
37
  }, [configValues, config]);
34
38
 
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { View } from 'react-native';
3
+ import { useNavigation } from '@react-navigation/native';
3
4
  import { useTranslations } from '../../../hooks/Common/useTranslations';
4
5
  import { useSensorsStatus } from '../../../hooks/Common';
5
6
 
@@ -8,7 +9,7 @@ import ItemDevice from '../../Device/ItemDevice';
8
9
  import ItemOneTap from '../OneTap/ItemOneTap';
9
10
  import ItemAddNew from '../../Device/ItemAddNew';
10
11
  import styles from './styles';
11
- import { notImplemented } from '../../../utils/Utils';
12
+ import Routes from '../../../utils/Route';
12
13
 
13
14
  const SubUnitFavorites = ({
14
15
  isOwner,
@@ -18,11 +19,14 @@ const SubUnitFavorites = ({
18
19
  wrapItemStyle,
19
20
  }) => {
20
21
  const t = useTranslations();
22
+ const { navigate } = useNavigation();
21
23
 
22
24
  const { getStatus, serverDown } = useSensorsStatus(unit, favoriteDevices);
23
25
 
24
26
  const handleOnAddNew = () => {
25
- notImplemented(t);
27
+ navigate(Routes.SelectDevices, {
28
+ unitId: unit.id,
29
+ });
26
30
  };
27
31
 
28
32
  return (
@@ -29,6 +29,9 @@ const API = {
29
29
  CHANGE_OWNER: (id) => `/property_manager/units/${id}/change_owner/`,
30
30
  FAVOURITE_DEVICES: (id) =>
31
31
  `/property_manager/units/${id}/favourite_devices/`,
32
+ DEVICES: (id) => `/property_manager/units/${id}/devices/`,
33
+ ADD_DEVICES_TO_FAVORITES: (id) =>
34
+ `/property_manager/units/${id}/add_devices_to_favourites/`,
32
35
  },
33
36
  SUB_UNIT: {
34
37
  REMOVE_SUB_UNIT: (unitId, id) =>
@@ -173,6 +176,7 @@ const API = {
173
176
  `/notifications/eoh/?page=${page}&type=${type}`,
174
177
  SET_READ: (id) => `/notifications/eoh/${id}/set_read/`,
175
178
  },
179
+ VALUE_EVALUATIONS: () => '/property_manager/config_value_evaluations/',
176
180
  EXTERNAL: {
177
181
  GOOGLE_MAP: {
178
182
  AUTO_COMPLETE:
@@ -112,7 +112,7 @@ export class SCConfig {
112
112
 
113
113
  export const initSCConfig = (config) => {
114
114
  api.setBaseURL(config.apiRoot ?? SCDefaultConfig.apiRoot);
115
- LocaleConfig.defaultLocale = config.language;
115
+ LocaleConfig.defaultLocale = config.language ?? SCConfig.language;
116
116
  SCConfig.language = config.language ?? SCConfig.language;
117
117
  SCConfig.apiRoot = config.apiRoot ?? SCDefaultConfig.apiRoot;
118
118
  SCConfig.GOOGLE_MAP_API_KEY =
@@ -12,14 +12,16 @@ export const Action = {
12
12
  CAMERA_STATUS_CHANGE: 'CAMERA_STATUS_CHANGE',
13
13
  CLOSE_ALL_CAMERA: 'CLOSE_ALL_CAMERA',
14
14
  SET_FAVORITE_DEVICES: 'SET_FAVORITE_DEVICES',
15
- ADD_DEVICE_TO_FAVORITES: 'ADD_DEVICE_TO_FAVORITES',
16
- REMOVE_DEVICE_FROM_FAVORITES: 'REMOVE_DEVICE_FROM_FAVORITES',
15
+ ADD_DEVICES_TO_FAVORITES: 'ADD_DEVICE_TO_FAVORITES',
16
+ REMOVE_DEVICES_FROM_FAVORITES: 'REMOVE_DEVICE_FROM_FAVORITES',
17
17
  SET_STARRED_SCRIPTS: 'SET_STARRED_SCRIPTS',
18
18
  STAR_SCRIPT: 'STAR_SCRIPT',
19
19
  UNSTAR_SCRIPT: 'UNSTAR_SCRIPT',
20
20
  CONNECTING_GOOGLE_HOME: 'CONNECTING_GOOGLE_HOME',
21
21
  SET_GOOGLE_HOME_CONNECTIONS: 'SET_GOOGLE_HOME_CONNECTIONS',
22
22
  CHANGE_GOOGLE_HOME_CONN_STATE: 'CHANGE_GOOGLE_HOME_CONN_STATE',
23
+ UPDATE_VALUE_EVALUATIONS: 'UPDATE_VALUE_EVALUATIONS',
24
+ ON_RECEIVE_NOTIFICATION: 'ON_RECEIVE_NOTIFICATION',
23
25
  };
24
26
 
25
27
  export type AuthData = {
@@ -76,6 +78,7 @@ export type AppType = {
76
78
  isBluetoothEnabled: boolean;
77
79
  isNetworkConnected: boolean;
78
80
  camera_opened: any[];
81
+ notificationData: any;
79
82
  };
80
83
 
81
84
  export type IoTType = {
@@ -31,11 +31,23 @@ export const mockDataStore: ContextData = {
31
31
  automate: {
32
32
  starredScriptIds: [],
33
33
  },
34
+ app: {
35
+ isFirstOpenCamera: true,
36
+ isLavidaSource: false,
37
+ isConnectWifiGateway: false,
38
+ isBluetoothEnabled: true,
39
+ isNetworkConnected: true,
40
+ camera_opened: [],
41
+ },
34
42
  iot: {
35
- isFirstTimeConnect: true,
36
- isConnecting: false,
37
- googlehome: {},
43
+ googlehome: {
44
+ isFirstTimeConnect: true,
45
+ isConnecting: false,
46
+ connections: {},
47
+ },
38
48
  },
49
+ valueEvaluations: {},
50
+ fetchedValueEvaluationUnits: [],
39
51
  };
40
52
 
41
53
  export const mockSCStore = (data: ContextData): ContextData => {
@@ -83,5 +95,7 @@ export const mockSCStore = (data: ContextData): ContextData => {
83
95
  connections: {},
84
96
  },
85
97
  },
98
+ valueEvaluations: {},
99
+ fetchedValueEvaluationUnits: [],
86
100
  };
87
101
  };
@@ -12,7 +12,7 @@ import {
12
12
  AppType,
13
13
  IoTType,
14
14
  } from './actionType';
15
- import { uniq } from 'lodash';
15
+ import { uniq, reduce } from 'lodash';
16
16
 
17
17
  export type ContextData = {
18
18
  auth: AuthData;
@@ -24,6 +24,8 @@ export type ContextData = {
24
24
  automate: AutomateType;
25
25
  app: AppType;
26
26
  iot: IoTType;
27
+ valueEvaluations: {};
28
+ fetchedValueEvaluationUnits: Array<number>;
27
29
  };
28
30
 
29
31
  export type Action = {
@@ -57,6 +59,7 @@ export const initialState = {
57
59
  isBluetoothEnabled: false,
58
60
  isNetworkConnected: false,
59
61
  camera_opened: [],
62
+ notificationData: null,
60
63
  },
61
64
  iot: {
62
65
  googlehome: {
@@ -65,6 +68,8 @@ export const initialState = {
65
68
  connections: {},
66
69
  },
67
70
  },
71
+ valueEvaluations: {},
72
+ fetchedValueEvaluationUnits: [],
68
73
  };
69
74
 
70
75
  export const reducer = (currentState: ContextData, action: Action) => {
@@ -201,7 +206,7 @@ export const reducer = (currentState: ContextData, action: Action) => {
201
206
  favoriteDeviceIds: payload,
202
207
  },
203
208
  };
204
- case Action.ADD_DEVICE_TO_FAVORITES:
209
+ case Action.ADD_DEVICES_TO_FAVORITES:
205
210
  return {
206
211
  ...currentState,
207
212
  unit: {
@@ -211,13 +216,13 @@ export const reducer = (currentState: ContextData, action: Action) => {
211
216
  ),
212
217
  },
213
218
  };
214
- case Action.REMOVE_DEVICE_FROM_FAVORITES:
219
+ case Action.REMOVE_DEVICES_FROM_FAVORITES:
215
220
  return {
216
221
  ...currentState,
217
222
  unit: {
218
223
  ...currentState.unit,
219
224
  favoriteDeviceIds: currentState.unit.favoriteDeviceIds.filter(
220
- (deviceId) => deviceId !== payload
225
+ (deviceId) => !payload.includes(deviceId)
221
226
  ),
222
227
  },
223
228
  };
@@ -294,6 +299,35 @@ export const reducer = (currentState: ContextData, action: Action) => {
294
299
  },
295
300
  };
296
301
 
302
+ case Action.UPDATE_VALUE_EVALUATIONS:
303
+ // eslint-disable-next-line no-case-declarations
304
+ const { data, unitId } = payload;
305
+ return {
306
+ ...currentState,
307
+ fetchedValueEvaluationUnits:
308
+ currentState.fetchedValueEvaluationUnits.indexOf(unitId) !== -1
309
+ ? currentState.fetchedValueEvaluationUnits
310
+ : [...currentState.fetchedValueEvaluationUnits, unitId],
311
+ valueEvaluations: reduce(
312
+ data,
313
+ (dict, item) => {
314
+ // eslint-disable-next-line no-param-reassign
315
+ dict[item.config] = item;
316
+ return dict;
317
+ },
318
+ currentState.valueEvaluations
319
+ ),
320
+ };
321
+
322
+ case Action.ON_RECEIVE_NOTIFICATION:
323
+ return {
324
+ ...currentState,
325
+ app: {
326
+ ...currentState.app,
327
+ notificationData: payload,
328
+ },
329
+ };
330
+
297
331
  default:
298
332
  return currentState;
299
333
  }
@@ -0,0 +1,58 @@
1
+ import React from 'react';
2
+ import { renderHook } from '@testing-library/react-hooks';
3
+ import MockAdapter from 'axios-mock-adapter';
4
+ import { SCProvider } from '../../../context';
5
+ import { mockSCStore } from '../../../context/mockStore';
6
+ import { useValueEvaluations } from '../index';
7
+ import api from '../../../utils/Apis/axios';
8
+ import { API } from '../../../configs';
9
+
10
+ const mock = new MockAdapter(api.axiosInstance);
11
+
12
+ const mockedSetAction = jest.fn();
13
+
14
+ const wrapper = ({ children }) => <SCProvider>{children}</SCProvider>;
15
+
16
+ const mockUseContext = jest.fn().mockImplementation(() => ({
17
+ stateData: mockSCStore({}),
18
+ setAction: mockedSetAction,
19
+ }));
20
+
21
+ React.useContext = mockUseContext;
22
+
23
+ describe('Test useValueEvaluation', () => {
24
+ beforeEach(() => {
25
+ mock.resetHistory();
26
+ });
27
+
28
+ it('test unitId null', async () => {
29
+ renderHook(() => useValueEvaluations(null), {
30
+ wrapper,
31
+ });
32
+ expect(mock.history.get.length).toBe(0);
33
+ });
34
+
35
+ it('test unitId not null request success', async () => {
36
+ mock.onGet(API.VALUE_EVALUATIONS()).replyOnce(200, {
37
+ results: [],
38
+ next: 'link',
39
+ });
40
+ mock.onGet(API.VALUE_EVALUATIONS()).replyOnce(200, {
41
+ results: [],
42
+ });
43
+ renderHook(() => useValueEvaluations(1), {
44
+ wrapper,
45
+ });
46
+ expect(mock.history.get.length).toBe(1);
47
+ });
48
+
49
+ it('test request failed', async () => {
50
+ mock.onGet(API.VALUE_EVALUATIONS()).replyOnce(400, {
51
+ results: [],
52
+ });
53
+ renderHook(() => useValueEvaluations(1), {
54
+ wrapper,
55
+ });
56
+ expect(mock.history.get.length).toBe(1);
57
+ });
58
+ });
@@ -1,4 +1,5 @@
1
1
  import useGGHomeConnection from './useGGHomeConnection';
2
2
  import useRemoteControl from './useRemoteControl';
3
+ import useValueEvaluations from './useValueEvaluation';
3
4
 
4
- export { useGGHomeConnection, useRemoteControl };
5
+ export { useGGHomeConnection, useRemoteControl, useValueEvaluations };
@@ -0,0 +1,45 @@
1
+ import { useCallback, useContext, useEffect } from 'react';
2
+ import { API } from '../../configs';
3
+ import { SCContext, useSCContextSelector } from '../../context';
4
+ import { Action } from '../../context/actionType';
5
+ import { axiosGet } from '../../utils/Apis/axios';
6
+
7
+ const useValueEvaluations = (unitId) => {
8
+ const { setAction } = useContext(SCContext);
9
+
10
+ const fetchConfigValueEvaluations = useCallback(
11
+ async (page = 1) => {
12
+ if (!unitId) {
13
+ return;
14
+ }
15
+ const params = new URLSearchParams();
16
+ params.append('config__end_device__station__unit', unitId);
17
+ params.append('page', page);
18
+ const { success, data } = await axiosGet(API.VALUE_EVALUATIONS(), {
19
+ params,
20
+ });
21
+ if (success) {
22
+ setAction(Action.UPDATE_VALUE_EVALUATIONS, {
23
+ unitId,
24
+ data: data.results,
25
+ });
26
+ if (data.next) {
27
+ await fetchConfigValueEvaluations(page + 1);
28
+ }
29
+ }
30
+ },
31
+ [unitId, setAction]
32
+ );
33
+
34
+ const fetchedValueEvaluationUnits = useSCContextSelector((state) => {
35
+ return state.fetchedValueEvaluationUnits || [];
36
+ });
37
+
38
+ useEffect(() => {
39
+ if (!(fetchedValueEvaluationUnits.indexOf(unitId) !== -1)) {
40
+ fetchConfigValueEvaluations();
41
+ }
42
+ }, [unitId, fetchConfigValueEvaluations, fetchedValueEvaluationUnits]);
43
+ };
44
+
45
+ export default useValueEvaluations;
@@ -1,26 +1,20 @@
1
- import { useEffect, useState, useCallback } from 'react';
2
- import OneSignal from 'react-native-onesignal';
1
+ import { useEffect, useState } from 'react';
2
+ import { useSCContextSelector } from '../context';
3
3
 
4
4
  const useReceiveNotifications = (callBack) => {
5
- const [dataNofitication, setDataNofitication] = useState(null);
6
-
7
- const onReceived = useCallback((data) => {
8
- const { additionalData } = data;
9
- setDataNofitication(additionalData);
10
- }, []);
5
+ const [dataNotification, setDataNotification] = useState(null);
6
+ const notificationData = useSCContextSelector(
7
+ (state) => state.app.notificationData
8
+ );
11
9
 
12
10
  useEffect(() => {
13
- OneSignal.setNotificationWillShowInForegroundHandler(
14
- (notifReceivedEvent) => {
15
- let notif = notifReceivedEvent.getNotification();
16
- setTimeout(() => notifReceivedEvent.complete(notif), 0);
17
- onReceived(notif);
18
- callBack && callBack();
19
- }
20
- );
21
- }, [callBack, onReceived]);
11
+ if (notificationData) {
12
+ setDataNotification(notificationData);
13
+ callBack && callBack();
14
+ }
15
+ }, [callBack, notificationData]);
22
16
 
23
- return { dataNofitication };
17
+ return { dataNotification };
24
18
  };
25
19
 
26
20
  export default useReceiveNotifications;
@@ -51,6 +51,7 @@ import EmergencySetting from '../screens/EmergencySetting';
51
51
  import ConfirmUnitDeletion from '../screens/ConfirmUnitDeletion';
52
52
  import InfoMemberUnit from '../screens/Sharing/InfoMemberUnit';
53
53
  import EnterPassword from '../screens/EnterPassword';
54
+ import SelectDevices from '../screens/Unit/SelectDevices';
54
55
  import { HanetCameraStack } from './HanetCameraStack';
55
56
  import { axiosGet } from '../utils/Apis/axios';
56
57
  import { API } from '../configs';
@@ -400,6 +401,13 @@ export const UnitStack = memo((props) => {
400
401
  headerShown: false,
401
402
  }}
402
403
  />
404
+ <Stack.Screen
405
+ name={Route.SelectDevices}
406
+ component={SelectDevices}
407
+ options={{
408
+ headerShown: false,
409
+ }}
410
+ />
403
411
  </Stack.Navigator>
404
412
  );
405
413
  });
@@ -134,6 +134,7 @@ const SelectAction = memo(({ route }) => {
134
134
  value: itemTemp?.value,
135
135
  config_id: itemTemp?.id,
136
136
  config_name: itemTemp?.name,
137
+ sensor_type: itemTemp?.sensor_type,
137
138
  },
138
139
  scriptName,
139
140
  });
@@ -300,9 +301,9 @@ const SelectAction = memo(({ route }) => {
300
301
  if (isNumberValue) {
301
302
  return `${item?.name} ${
302
303
  item?.title ? item.title : t('is_below') + ' (<)'
303
- }{' '}${item?.value} ${item?.unit}`;
304
+ } ${item?.value} ${item?.unit}`;
304
305
  }
305
- return t(stateConditionData?.stateValue[item?.value === 1 ? 1 : 0]);
306
+ return t(stateConditionData?.stateValue[item?.value]);
306
307
  },
307
308
  [t]
308
309
  );
@@ -56,7 +56,7 @@ const SetUpSensor = () => {
56
56
  modalNumberConditionData[0]
57
57
  );
58
58
  const [itemActiveStateModal, setItemActiveStateModal] = useState(
59
- modalStateConditionData?.stateValue[0]
59
+ modalStateConditionData?.stateValue[1]
60
60
  );
61
61
  const [value, setValue] = useState(parseFloat(item?.value || 0));
62
62
  const [minimum] = useState(isHasLimit ? parseInt(item?.range_min, 10) : 0);
@@ -226,7 +226,8 @@ const SetUpSensor = () => {
226
226
  <View style={styles.modalContent}>
227
227
  {(isNumberValue
228
228
  ? modalNumberConditionData
229
- : modalStateConditionData?.stateValue
229
+ : /* Disable picking not_active/not_dectect option -> temporaly remove not_acitve option */
230
+ modalStateConditionData?.stateValue.slice(1)
230
231
  ).map((i, index) => (
231
232
  <>
232
233
  <TouchableOpacity
@@ -44,12 +44,13 @@ import {
44
44
  useBoolean,
45
45
  useGGHomeDeviceConnected,
46
46
  } from '../../hooks/Common';
47
- import { useGGHomeConnection } from '../../hooks/IoT';
47
+ import { useGGHomeConnection, useValueEvaluations } from '../../hooks/IoT';
48
48
  import { SensorDisplayItem } from './components/SensorDisplayItem';
49
49
  import { useSCContextSelector } from '../../context';
50
50
  import { EmergencyCountdown } from './components/EmergencyCountdown';
51
51
  import { SensorConnectStatusViewHeader } from './components/SensorConnectStatusViewHeader';
52
52
  import { useDisconnectedDevice } from './hooks/useDisconnectedDevice';
53
+ import { useEvaluateValue } from './hooks/useEvaluateValue';
53
54
  import { Card } from '../../commons/CardShadow';
54
55
  import PreventAccess from '../../commons/PreventAccess';
55
56
  import { notImplemented } from '../../utils/Utils';
@@ -117,6 +118,8 @@ const DeviceDetail = ({ route }) => {
117
118
  });
118
119
  }, [display]);
119
120
 
121
+ useValueEvaluations(unitId || unitData?.id);
122
+
120
123
  useDisconnectedDevice(sensorName, isDeviceHasBle, serverDown);
121
124
 
122
125
  const isShowSetupEmergencyContact = useMemo(
@@ -438,21 +441,32 @@ const DeviceDetail = ({ route }) => {
438
441
  // eslint-disable-next-line react-hooks/exhaustive-deps
439
442
  }, [sensor, unit, isNetworkConnected, fetchDataDeviceDetail]);
440
443
 
444
+ const evaluateValue = useEvaluateValue();
445
+
441
446
  const getData = useCallback(
442
447
  (item) => {
443
448
  if (!item.configuration) {
444
449
  return;
445
450
  }
446
451
  const data = item.configuration.configs.map((config) => {
447
- const value = displayValues.find((k) => k.id === config.id);
448
- if (!value) {
452
+ const configValue = configValues[config.id];
453
+ const displayValue = displayValues.find((k) => k.id === config.id);
454
+ if (!configValue && !displayValue) {
449
455
  return;
450
456
  }
457
+ const value = configValue
458
+ ? {
459
+ id: config.id,
460
+ value: configValue,
461
+ evaluate: evaluateValue(config.id, configValue),
462
+ }
463
+ : displayValue;
464
+
451
465
  return { ...config, ...value };
452
466
  });
453
467
  return data.filter((value) => value);
454
468
  },
455
- [displayValues]
469
+ [configValues, displayValues, evaluateValue]
456
470
  );
457
471
 
458
472
  useEffect(() => {
@@ -509,29 +523,6 @@ const DeviceDetail = ({ route }) => {
509
523
  }
510
524
  }, [sensor, display]);
511
525
 
512
- useEffect(() => {
513
- setDisplayValues((currentDisplayValues) => {
514
- for (const [configId, value] of Object.entries(configValues)) {
515
- const intId = parseInt(configId, 10);
516
- const index = currentDisplayValues.findIndex(
517
- (element) => element.id === intId
518
- );
519
-
520
- const item = currentDisplayValues[index];
521
- if (index !== -1) {
522
- currentDisplayValues[index].value = value;
523
- currentDisplayValues[index].evaluate = item.evaluate;
524
- } else {
525
- currentDisplayValues.push({
526
- id: intId,
527
- value: value,
528
- });
529
- }
530
- }
531
- return currentDisplayValues;
532
- });
533
- }, [configValues, setDisplayValues]);
534
-
535
526
  const isShowEmergencyResolve =
536
527
  display.items.filter(
537
528
  (item) =>