@eohjsc/react-native-smart-city 0.4.83 → 0.4.85

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/package.json +1 -1
  2. package/src/commons/Device/PMSensor/PMSensorIndicator.js +15 -8
  3. package/src/commons/Device/WaterQualitySensor/ListQualityIndicator.js +23 -15
  4. package/src/commons/Device/WaterQualitySensor/QualityIndicatorsItem.js +10 -9
  5. package/src/commons/Sharing/WrapHeaderScrollable.js +1 -1
  6. package/src/commons/SubUnit/DeviceTemplate/ConfigValue/ConfigValue.js +2 -8
  7. package/src/commons/SubUnit/DeviceTemplate/EvaluationOverConfig/EvaluationOverConfig.js +2 -10
  8. package/src/commons/SubUnit/ShortDetail.js +14 -4
  9. package/src/commons/UnitSummary/ConfigHistoryChart/index.js +4 -1
  10. package/src/hooks/IoT/useBluetoothDeviceConnected.js +2 -4
  11. package/src/iot/RemoteControl/Bluetooth.js +15 -9
  12. package/src/screens/Device/__test__/mqttDetail.test.js +20 -20
  13. package/src/screens/Device/components/SensorConnectStatusViewHeader.js +3 -3
  14. package/src/screens/Device/components/VisualChart.js +1 -1
  15. package/src/screens/Device/detail.js +13 -6
  16. package/src/screens/UnitSummary/__test__/index.test.js +2 -1
  17. package/src/screens/UnitSummary/components/3PPowerConsumption/__test__/3PPowerConsumption.test.js +37 -30
  18. package/src/screens/UnitSummary/components/3PPowerConsumption/index.js +105 -166
  19. package/src/screens/UnitSummary/components/AirQuality/SegmentedRoundChart.js +32 -0
  20. package/src/{commons/UnitSummary → screens/UnitSummary/components}/AirQuality/__test__/index.test.js +25 -15
  21. package/src/{commons/UnitSummary → screens/UnitSummary/components}/AirQuality/index.js +55 -71
  22. package/src/{commons/UnitSummary → screens/UnitSummary/components}/AirQuality/styles.js +1 -2
  23. package/src/screens/UnitSummary/components/PowerConsumption/__test__/PowerConsumption.test.js +26 -20
  24. package/src/screens/UnitSummary/components/PowerConsumption/index.js +59 -87
  25. package/src/screens/UnitSummary/components/RunningDevices/index.js +27 -23
  26. package/src/screens/UnitSummary/components/Temperature/ItemTemperature/index.js +33 -20
  27. package/src/screens/UnitSummary/components/Temperature/index.js +52 -79
  28. package/src/screens/UnitSummary/components/UvIndex/SegmentedRoundChart.js +36 -0
  29. package/src/screens/UnitSummary/components/UvIndex/__test__/index.test.js +8 -0
  30. package/src/screens/UnitSummary/components/UvIndex/index.js +16 -72
  31. package/src/screens/UnitSummary/components/UvIndex/styles.js +48 -0
  32. package/src/screens/UnitSummary/components/WaterQuality/Item/index.js +6 -4
  33. package/src/screens/UnitSummary/components/WaterQuality/__test__/index.test.js +26 -12
  34. package/src/screens/UnitSummary/components/WaterQuality/index.js +93 -3
  35. package/src/screens/UnitSummary/index.js +1 -9
  36. package/src/utils/I18n/translations/en.js +2 -0
  37. package/src/utils/I18n/translations/vi.js +2 -0
  38. package/src/screens/UnitSummary/components/PowerConsumption/ItemPower/index.js +0 -53
  39. package/src/screens/UnitSummary/components/PowerConsumption/__test__/ItemPower.test.js +0 -20
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.4.83",
4
+ "version": "0.4.85",
5
5
  "description": "TODO",
6
6
  "main": "index.js",
7
7
  "files": [
@@ -4,25 +4,32 @@ import { FlatList } from 'react-native';
4
4
  import QualityIndicatorItem from '../WaterQualitySensor/QualityIndicatorsItem';
5
5
  import styles from './PMSensorIndicatorStyles';
6
6
  import { keyExtractor, roundNumber } from '../../../utils/Utils';
7
+ import { useConfigGlobalState } from '../../../iot/states';
7
8
 
8
9
  const PMSensorIndicator = memo(({ data = [], style, isWidgetOrder }) => {
10
+ const [configValues] = useConfigGlobalState('configValues');
11
+
9
12
  const renderItem = useCallback(
10
13
  ({ item }) => {
11
- const getValue = ['', null, undefined, NaN].includes(item?.value)
12
- ? '--'
13
- : roundNumber(item?.value);
14
+ const { id, color, title, standard, evaluate, unit } = item || {};
15
+ const getValue =
16
+ configValues?.[id]?.value === undefined
17
+ ? '--'
18
+ : `${roundNumber(configValues[id].value)}`;
19
+
14
20
  return (
15
21
  <QualityIndicatorItem
16
- color={item.color}
17
- standard={item.standard}
22
+ key={id?.toString()}
23
+ color={color}
24
+ standard={title || standard}
18
25
  value={getValue}
19
- evaluate={item.evaluate}
20
- measure={item.unit}
26
+ evaluate={evaluate}
27
+ measure={unit}
21
28
  style={style}
22
29
  />
23
30
  );
24
31
  },
25
- [style]
32
+ [configValues, style]
26
33
  );
27
34
 
28
35
  const isScrollMode = data.length > 3;
@@ -2,25 +2,33 @@ import React, { useCallback } from 'react';
2
2
  import { View, StyleSheet, FlatList } from 'react-native';
3
3
 
4
4
  import QualityIndicatorItem from './QualityIndicatorsItem';
5
+ import { useConfigGlobalState } from '../../../iot/states';
5
6
 
6
7
  //using for Water quality sensor , power meter SENSOR, INdoor air sensor
7
8
  const ListQualityIndicator = ({ data, style }) => {
8
- const renderItem = useCallback(({ item }) => {
9
- const getValue = ['', null, undefined, NaN].includes(item?.value)
10
- ? '--'
11
- : item?.value;
9
+ const [configValues] = useConfigGlobalState('configValues');
10
+ const renderItem = useCallback(
11
+ ({ item }) => {
12
+ const { id, measure, color, title, standard, evaluate, unit } =
13
+ item || {};
14
+ const getValue =
15
+ configValues?.[id]?.value === undefined
16
+ ? '--'
17
+ : `${configValues[id].value} ${measure}`;
12
18
 
13
- return (
14
- <QualityIndicatorItem
15
- key={item.id.toString()}
16
- color={item.color}
17
- standard={item.standard}
18
- value={getValue}
19
- evaluate={item.evaluate}
20
- measure={item.unit}
21
- />
22
- );
23
- }, []);
19
+ return (
20
+ <QualityIndicatorItem
21
+ key={id?.toString()}
22
+ color={color}
23
+ standard={title || standard}
24
+ value={getValue}
25
+ evaluate={evaluate}
26
+ measure={unit}
27
+ />
28
+ );
29
+ },
30
+ [configValues]
31
+ );
24
32
  return (
25
33
  <View style={styles.standard}>
26
34
  <FlatList
@@ -22,14 +22,14 @@ const QualityIndicatorItem = memo(
22
22
  backgroundColor: color,
23
23
  };
24
24
  const navigation = useNavigation();
25
+ const measureText =
26
+ measure && measure.length ? `${value} ${measure}` : `${value}`;
25
27
 
26
28
  return (
27
29
  <View style={[styles.container, style, color && styles.containerPadding]}>
28
30
  <View style={[styles.line, styleColor]} />
29
31
  <View style={styles.rowFlex}>
30
- <Text size={14} color={Colors.Gray8} style={styles.txtMeasure}>
31
- {standard}
32
- </Text>
32
+ <Text style={styles.txtMeasure}>{standard}</Text>
33
33
  {type === 'machine_status' && (
34
34
  <TouchableOpacity
35
35
  onPress={() => navigation.navigate(descriptionScreen)}
@@ -43,13 +43,9 @@ const QualityIndicatorItem = memo(
43
43
  </TouchableOpacity>
44
44
  )}
45
45
  </View>
46
- <Text size={24} color={Colors.Gray9} style={styles.txtValue}>
47
- {measure && measure.length ? `${value} ${measure}` : `${value}`}
48
- </Text>
46
+ <Text style={styles.txtValue}>{measureText}</Text>
49
47
  {!!evaluate?.color && (
50
- <Text size={12} color={evaluate.color} style={styles.txtEvaluate}>
51
- {evaluate.text}
52
- </Text>
48
+ <Text style={styles.txtEvaluate}>{evaluate.text}</Text>
53
49
  )}
54
50
  </View>
55
51
  );
@@ -82,14 +78,19 @@ const styles = StyleSheet.create({
82
78
  txtMeasure: {
83
79
  lineHeight: 22,
84
80
  marginTop: 8,
81
+ fontSize: 14,
82
+ color: Colors.Gray8,
85
83
  },
86
84
  txtValue: {
87
85
  lineHeight: 32,
88
86
  marginTop: 16,
87
+ fontSize: 24,
88
+ color: Colors.Gray9,
89
89
  },
90
90
  txtEvaluate: {
91
91
  lineHeight: 20,
92
92
  marginTop: 8,
93
+ fontSize: 12,
93
94
  },
94
95
  iconInfo: {
95
96
  width: 40,
@@ -116,7 +116,7 @@ const styles = StyleSheet.create({
116
116
  scrollView: {
117
117
  flex: 1,
118
118
  paddingTop: Platform.select({
119
- ios: 0,
119
+ ios: 15,
120
120
  android: heightHeader + 16,
121
121
  }),
122
122
  },
@@ -1,22 +1,16 @@
1
- import React, { memo, useMemo } from 'react';
1
+ import React, { memo } from 'react';
2
2
  import styles from '../styles/ConfigValueStyles';
3
3
  import { Platform, View } from 'react-native';
4
4
  import Text from '../../../Text';
5
5
  import { useConfigGlobalState } from '../../../../iot/states';
6
- import { useWatchConfigs } from '../../../../hooks/IoT';
7
6
  import LastUpdatedText from '../../../Device/LastUpdatedText';
8
7
  import IconComponent from '../../../IconComponent';
9
8
  import { IconOutline } from '@ant-design/icons-react-native';
10
9
 
11
10
  const ConfigValue = ({ device, stationItem }) => {
12
- // eslint-disable-next-line no-unused-vars
13
- const [configValues, _] = useConfigGlobalState('configValues');
11
+ const [configValues] = useConfigGlobalState('configValues');
14
12
  const configValue = configValues[stationItem.configuration?.config];
15
- const configIds = useMemo(() => {
16
- return [stationItem.configuration?.config];
17
- }, [stationItem.configuration?.config]);
18
13
  const { icon_kit, icon } = device || {};
19
- useWatchConfigs(configIds);
20
14
 
21
15
  return (
22
16
  <>
@@ -1,4 +1,4 @@
1
- import React, { memo, useMemo } from 'react';
1
+ import React, { memo } from 'react';
2
2
  import styles from '../styles/ConfigValueStyles';
3
3
  import { Platform, View } from 'react-native';
4
4
  import Text from '../../../Text';
@@ -7,22 +7,14 @@ import {
7
7
  useEvaluateValue,
8
8
  useValueEvaluation,
9
9
  } from '../../../../screens/Device/hooks/useEvaluateValue';
10
- import { useWatchConfigs } from '../../../../hooks/IoT';
11
10
  import LastUpdatedText from '../../../Device/LastUpdatedText';
12
11
  import IconComponent from '../../../IconComponent';
13
12
  import { IconOutline } from '@ant-design/icons-react-native';
14
13
 
15
14
  export const EvaluationConfigWrapper = memo(
16
15
  ({ device, stationItem, Child }) => {
17
- // eslint-disable-next-line no-unused-vars
18
- const [configValues, _] = useConfigGlobalState('configValues');
16
+ const [configValues] = useConfigGlobalState('configValues');
19
17
  const configValue = configValues[stationItem.configuration?.config];
20
- const configIds = useMemo(() => {
21
- return [stationItem.configuration?.config];
22
- }, [stationItem.configuration?.config]);
23
-
24
- useWatchConfigs(configIds);
25
-
26
18
  const valueEvaluationObject = useValueEvaluation(
27
19
  stationItem.configuration?.config,
28
20
  device.unit_id,
@@ -29,12 +29,22 @@ const ShortDetailSubUnit = ({ unit, station, isOwner }) => {
29
29
  useDevicesStatus(unit, station?.devices);
30
30
 
31
31
  const configsNeedWatching = useMemo(() => {
32
- const configIds = [];
33
- (station?.devices || []).forEach((device) => {
34
- if (device?.quick_action?.config_id && device?.is_managed_by_backend) {
35
- configIds.push(device.quick_action.config_id);
32
+ const configIds = (station?.devices || []).flatMap((device) => {
33
+ const ids = [];
34
+
35
+ if (device?.quick_action?.config_id && device.is_managed_by_backend) {
36
+ ids.push(device.quick_action.config_id);
37
+ }
38
+
39
+ if (device?.station_items?.length) {
40
+ ids.push(
41
+ ...device.station_items.map((item) => item.configuration.config)
42
+ );
36
43
  }
44
+
45
+ return ids;
37
46
  });
47
+
38
48
  return configIds;
39
49
  }, [station]);
40
50
 
@@ -36,7 +36,10 @@ export const useFetchConfigHistory = (configs, setChartData) => {
36
36
  'date_from',
37
37
  startDate.subtract(7, 'hours').format('YYYY-MM-DDTHH:mm:ss')
38
38
  );
39
- params.append('date_to', endDate.format('YYYY-MM-DDTHH:mm:ss'));
39
+ params.append(
40
+ 'date_to',
41
+ endDate.subtract(7, 'hours').format('YYYY-MM-DDTHH:mm:ss')
42
+ );
40
43
 
41
44
  const { success, data } = await axiosGet(
42
45
  API.CONFIG.DISPLAY_HISTORY_V3(),
@@ -7,10 +7,8 @@ const useBluetoothDeviceConnected = (device) => {
7
7
  const isBluetoothEnabled = useSCContextSelector((state) => {
8
8
  return state.bluetooth.isEnabled;
9
9
  });
10
-
11
- const isConnected =
12
- isBluetoothEnabled &&
13
- !!connectedDevices[device?.remote_control_options?.bluetooth?.address];
10
+ const address = device?.remote_control_options?.bluetooth?.address;
11
+ const isConnected = isBluetoothEnabled && !!connectedDevices[address];
14
12
 
15
13
  return { isConnected };
16
14
  };
@@ -30,7 +30,7 @@ export const clearFoundDevices = () => {
30
30
 
31
31
  export const scanBluetoothDevices = async (names, onDeviceFound) => {
32
32
  names.map((name) => {
33
- if (bluetoothDevices[name]) {
33
+ if (needToScanDevices.includes(name)) {
34
34
  return;
35
35
  }
36
36
  needToScanDevices.push(name);
@@ -163,20 +163,26 @@ export const sendDataOverBluetooth = async (
163
163
  let fullDataDevice = null;
164
164
  let result = true;
165
165
  let hasResponse = false;
166
-
167
166
  try {
168
- connectedDevice = await device.connect();
167
+ connectedDevice = await device.connect({ timeout: 5000 });
169
168
  } catch (e) {
170
169
  const BLE_ERROR = {
171
170
  DEVICE_IS_NOT_ALREADY_CONNECTED: 201,
172
171
  DEVICE_WAS_DISCONNECTED: 203,
172
+ DEVICE_CONNECTION_TIMEOUT: 3,
173
+ PHONE_HAS_BLUETOOTH_TURNED_OFF: 102,
173
174
  };
174
- if (
175
- e?.errorCode === BLE_ERROR.DEVICE_IS_NOT_ALREADY_CONNECTED ||
176
- BLE_ERROR.DEVICE_WAS_DISCONNECTED
177
- ) {
178
- await bleManager.cancelDeviceConnection(device.id);
179
- return BLUETOOOH_DEVICE_UNSTABLE;
175
+ switch (e?.errorCode) {
176
+ case BLE_ERROR.DEVICE_IS_NOT_ALREADY_CONNECTED:
177
+ case BLE_ERROR.DEVICE_WAS_DISCONNECTED:
178
+ await bleManager.cancelDeviceConnection(device.id);
179
+ return BLUETOOOH_DEVICE_UNSTABLE;
180
+ case BLE_ERROR.DEVICE_CONNECTION_TIMEOUT:
181
+ case BLE_ERROR.PHONE_HAS_BLUETOOTH_TURNED_OFF:
182
+ delete bluetoothDevices[device.address];
183
+ return SEND_COMMAND_OVER_BLUETOOTH_FAIL;
184
+ default:
185
+ return SEND_COMMAND_OVER_BLUETOOTH_FAIL;
180
186
  }
181
187
  }
182
188
  try {
@@ -318,8 +318,8 @@ describe('test DeviceDetail', () => {
318
318
  data: '00012',
319
319
  }
320
320
  );
321
- expect(valueBoxs[0].props.value).toEqual(0.1);
322
- expect(valueBoxs[1].props.value).toEqual(0.2);
321
+ expect(valueBoxs[0].props.value).toEqual('0.1');
322
+ expect(valueBoxs[1].props.value).toEqual('0.2');
323
323
  });
324
324
 
325
325
  it('should render device detail, modbus call updateGlobalValue, int_all exceed 32767', async () => {
@@ -330,8 +330,8 @@ describe('test DeviceDetail', () => {
330
330
  data: '0001F000',
331
331
  }
332
332
  );
333
- expect(valueBoxs[0].props.value).toEqual(0.1);
334
- expect(valueBoxs[1].props.value).toEqual(-409.6);
333
+ expect(valueBoxs[0].props.value).toEqual('0.1');
334
+ expect(valueBoxs[1].props.value).toEqual('-409.6');
335
335
  });
336
336
 
337
337
  it('should render device detail, modbus call updateGlobalValue, uint_32', async () => {
@@ -346,8 +346,8 @@ describe('test DeviceDetail', () => {
346
346
  data: '0001CCDDBBAA',
347
347
  }
348
348
  );
349
- expect(valueBoxs[0].props.value).toEqual(0.1);
350
- expect(valueBoxs[1].props.value).toEqual(343708356.1);
349
+ expect(valueBoxs[0].props.value).toEqual('0.1');
350
+ expect(valueBoxs[1].props.value).toEqual('343708356.1');
351
351
  });
352
352
 
353
353
  it('should render device detail, modbus call updateGlobalValue, float_cdba', async () => {
@@ -363,8 +363,8 @@ describe('test DeviceDetail', () => {
363
363
  }
364
364
  );
365
365
 
366
- expect(valueBoxs[0].props.value).toEqual(0.1);
367
- expect(valueBoxs[1].props.value).toEqual(369.6);
366
+ expect(valueBoxs[0].props.value).toEqual('0.1');
367
+ expect(valueBoxs[1].props.value).toEqual('369.6');
368
368
  });
369
369
 
370
370
  it('should render device detail, modbus call updateGlobalValue, float_cdba, data not hex format', async () => {
@@ -380,7 +380,7 @@ describe('test DeviceDetail', () => {
380
380
  }
381
381
  );
382
382
 
383
- expect(valueBoxs[0].props.value).toEqual(0.1);
383
+ expect(valueBoxs[0].props.value).toEqual('0.1');
384
384
  expect(valueBoxs[1].props.value).toEqual('--');
385
385
  });
386
386
 
@@ -396,7 +396,7 @@ describe('test DeviceDetail', () => {
396
396
  data: '0001P5670123', // reverse for simple
397
397
  }
398
398
  );
399
- expect(valueBoxs[0].props.value).toEqual(0.1);
399
+ expect(valueBoxs[0].props.value).toEqual('0.1');
400
400
  expect(valueBoxs[1].props.value).toEqual('--');
401
401
  });
402
402
 
@@ -412,8 +412,8 @@ describe('test DeviceDetail', () => {
412
412
  data: '0001CCDDBBAA',
413
413
  }
414
414
  );
415
- expect(valueBoxs[0].props.value).toEqual(0.1);
416
- expect(valueBoxs[1].props.value).toEqual(5244.5);
415
+ expect(valueBoxs[0].props.value).toEqual('0.1');
416
+ expect(valueBoxs[1].props.value).toEqual('5244.5');
417
417
  });
418
418
 
419
419
  test('should render device detail, modbus call updateGlobalValue, int_last4', async () => {
@@ -429,8 +429,8 @@ describe('test DeviceDetail', () => {
429
429
  }
430
430
  );
431
431
 
432
- expect(valueBoxs[0].props.value).toEqual(0.1);
433
- expect(valueBoxs[1].props.value).toEqual(4804.2);
432
+ expect(valueBoxs[0].props.value).toEqual('0.1');
433
+ expect(valueBoxs[1].props.value).toEqual('4804.2');
434
434
  });
435
435
 
436
436
  it('should render device detail, modbus call updateGlobalValue, convert_ai', async () => {
@@ -448,8 +448,8 @@ describe('test DeviceDetail', () => {
448
448
  }
449
449
  );
450
450
 
451
- expect(valueBoxs[0].props.value).toEqual(0.1);
452
- expect(valueBoxs[1].props.value).toEqual(10);
451
+ expect(valueBoxs[0].props.value).toEqual('0.1');
452
+ expect(valueBoxs[1].props.value).toEqual('10');
453
453
  });
454
454
 
455
455
  it('should render device detail, modbus call updateGlobalValue, convert_ai min_raw same max_raw', async () => {
@@ -467,7 +467,7 @@ describe('test DeviceDetail', () => {
467
467
  }
468
468
  );
469
469
 
470
- expect(valueBoxs[0].props.value).toEqual(0.1);
470
+ expect(valueBoxs[0].props.value).toEqual('0.1');
471
471
  expect(valueBoxs[1].props.value).toEqual('--');
472
472
  });
473
473
 
@@ -482,7 +482,7 @@ describe('test DeviceDetail', () => {
482
482
  }
483
483
  );
484
484
 
485
- expect(valueBoxs[0].props.value).toEqual(0.1);
485
+ expect(valueBoxs[0].props.value).toEqual('0.1');
486
486
  expect(valueBoxs[1].props.value).toEqual('--');
487
487
  });
488
488
 
@@ -496,7 +496,7 @@ describe('test DeviceDetail', () => {
496
496
  }
497
497
  );
498
498
 
499
- expect(valueBoxs[0].props.value).toEqual(10);
499
+ expect(valueBoxs[0].props.value).toEqual('10');
500
500
  expect(valueBoxs[1].props.value).toEqual('--');
501
501
  });
502
502
 
@@ -538,7 +538,7 @@ describe('test DeviceDetail', () => {
538
538
  }
539
539
  );
540
540
 
541
- expect(valueBoxs[0].props.value).toEqual(36);
541
+ expect(valueBoxs[0].props.value).toEqual('36');
542
542
  expect(valueBoxs[1].props.value).toEqual('--');
543
543
  });
544
544
 
@@ -39,22 +39,22 @@ export const SensorConnectStatusViewHeader = ({
39
39
  </>
40
40
  );
41
41
  }
42
- if (connectedViaNetwork) {
42
+ if (connectedViaBle) {
43
43
  return (
44
44
  <>
45
45
  <ConnectedViewHeader
46
46
  lastUpdated={lastUpdated}
47
+ type={'Bluetooth'}
47
48
  isDisplayTime={isDisplayTime}
48
49
  showWindDirection={showWindDirection}
49
50
  />
50
51
  </>
51
52
  );
52
- } else if (connectedViaBle) {
53
+ } else if (connectedViaNetwork) {
53
54
  return (
54
55
  <>
55
56
  <ConnectedViewHeader
56
57
  lastUpdated={lastUpdated}
57
- type={'Bluetooth'}
58
58
  isDisplayTime={isDisplayTime}
59
59
  showWindDirection={showWindDirection}
60
60
  />
@@ -292,7 +292,7 @@ const VisualChart = ({ item, isDemo = false, isWidgetOrder }) => {
292
292
  return (
293
293
  <View style={styles.container}>
294
294
  <View style={styles.titleHistory}>
295
- <Text size={20} semibold color={Colors.Gray9}>
295
+ <Text type="H3" semibold color={Colors.Gray9}>
296
296
  {item.label}
297
297
  </Text>
298
298
  </View>
@@ -190,6 +190,13 @@ const DeviceDetail = ({ route }) => {
190
190
  }
191
191
  }, [unitId]);
192
192
 
193
+ const checkScanDevicesBLE = useCallback(async () => {
194
+ const bluetooth = controlOptions?.bluetooth;
195
+ if (isBluetoothEnabled && bluetooth) {
196
+ bluetoothScanDevices([bluetooth.address]);
197
+ }
198
+ }, [bluetoothScanDevices, controlOptions?.bluetooth, isBluetoothEnabled]);
199
+
193
200
  useEffect(() => {
194
201
  if (unitId && !unitData) {
195
202
  fetchUnitDetail();
@@ -222,10 +229,7 @@ const DeviceDetail = ({ route }) => {
222
229
  }, [unit, isNetworkConnected]);
223
230
 
224
231
  useEffect(() => {
225
- if (isBluetoothEnabled && controlOptions?.bluetooth) {
226
- const bluetooth = controlOptions.bluetooth;
227
- bluetoothScanDevices([bluetooth.address]);
228
- }
232
+ checkScanDevicesBLE();
229
233
  // eslint-disable-next-line react-hooks/exhaustive-deps
230
234
  }, [isBluetoothEnabled, bluetoothPermGranted, controlOptions, unit]);
231
235
 
@@ -296,7 +300,9 @@ const DeviceDetail = ({ route }) => {
296
300
 
297
301
  success &&
298
302
  data.items.length &&
299
- data.items.some((item) => (item?.template || item?.type) === 'action') &&
303
+ data.items.some(
304
+ (item) => item.template.toLowerCase().search('action') !== -1
305
+ ) &&
300
306
  (await fetchRemoteControlOptions());
301
307
  }, [token, sensor, setDeviceId, fetchRemoteControlOptions]);
302
308
 
@@ -489,6 +495,7 @@ const DeviceDetail = ({ route }) => {
489
495
  await connectHomeAssistant(unit.remote_control_options.googlehome);
490
496
  })();
491
497
  }
498
+ checkScanDevicesBLE();
492
499
  // eslint-disable-next-line react-hooks/exhaustive-deps
493
500
  }, [sensor, unit, isNetworkConnected, fetchDataDeviceDetail]);
494
501
 
@@ -762,7 +769,7 @@ const DeviceDetail = ({ route }) => {
762
769
  accessibilityLabel={
763
770
  AccessibilityLabel.SENSOR_DISPLAY_ITEM
764
771
  }
765
- key={(item?.id || index).toString()}
772
+ key={`display${item?.id || index}`}
766
773
  item={item}
767
774
  evaluate={evaluate}
768
775
  emergency={onEmergencyButtonPress}
@@ -8,7 +8,6 @@ import UnitSummary from '..';
8
8
  import { API } from '../../../configs';
9
9
  import { AccessibilityLabel } from '../../../configs/Constants';
10
10
  import { TouchableOpacity } from 'react-native';
11
- import AirQuality from '../../../commons/UnitSummary/AirQuality';
12
11
  import PowerConsumption from '../components/PowerConsumption';
13
12
  import ThreePhasePowerConsumption from '../components/3PPowerConsumption';
14
13
  import RunningDevices from '../components/RunningDevices';
@@ -20,6 +19,7 @@ import { SCProvider } from '../../../context';
20
19
  import { mockSCStore } from '../../../context/mockStore';
21
20
  import api from '../../../utils/Apis/axios';
22
21
  import { WrapHeaderScrollable } from '../../../commons';
22
+ import AirQuality from '../components/AirQuality';
23
23
 
24
24
  const mock = new MockAdapter(api.axiosInstance);
25
25
 
@@ -32,6 +32,7 @@ jest.mock('@react-navigation/native', () => {
32
32
  navigate: mockedNavigate,
33
33
  }),
34
34
  useIsFocused: () => true,
35
+ useFocusEffect: (func) => func(),
35
36
  };
36
37
  });
37
38
 
@@ -1,7 +1,7 @@
1
1
  import React, { useState } from 'react';
2
2
  import renderer, { act } from 'react-test-renderer';
3
3
  import { AccessibilityLabel } from '../../../../../configs/Constants';
4
- import { API, Colors } from '../../../../../configs';
4
+ import { API } from '../../../../../configs';
5
5
  import PowerConsumption from '../index';
6
6
  import { SCProvider } from '../../../../../context';
7
7
  import { mockSCStore } from '../../../../../context/mockStore';
@@ -17,6 +17,19 @@ jest.mock('react', () => {
17
17
  useState: jest.fn(),
18
18
  };
19
19
  });
20
+
21
+ const mockedNavigate = jest.fn();
22
+
23
+ jest.mock('@react-navigation/native', () => {
24
+ return {
25
+ ...jest.requireActual('@react-navigation/native'),
26
+ useNavigation: () => ({
27
+ navigate: mockedNavigate,
28
+ }),
29
+ useFocusEffect: (func) => func(),
30
+ };
31
+ });
32
+
20
33
  useState.mockImplementation((init) => [init, mockSetState]);
21
34
 
22
35
  const wrapComponent = (summaryDetail) => (
@@ -35,7 +48,19 @@ describe('Test 3PPowerConsumption', () => {
35
48
  activePowerValue: 10,
36
49
  powerFactor1Value: 30,
37
50
  totalPowerValue: 20,
38
- listConfigs: [1, 2, 3],
51
+ listConfigs: {
52
+ volt_1: 1,
53
+ volt_2: 2,
54
+ volt_3: 3,
55
+ current_1: 4,
56
+ current_2: 5,
57
+ current_3: 6,
58
+ active_power: 7,
59
+ power_factor_1: 8,
60
+ power_factor_2: 9,
61
+ power_factor_3: 10,
62
+ total_power: 11,
63
+ },
39
64
  };
40
65
  await act(async () => {
41
66
  tree = await renderer.create(wrapComponent(summaryDetail));
@@ -48,34 +73,16 @@ describe('Test 3PPowerConsumption', () => {
48
73
  );
49
74
  expect(listIndicator).not.toBeUndefined();
50
75
  const resultList = [
51
- {
52
- color: Colors.Red6,
53
- standard: 'Voltage 1',
54
- value: summaryDetail.volt1Value,
55
- measure: '',
56
- id: 1,
57
- },
58
- {
59
- color: Colors.Blue10,
60
- standard: 'Current 1',
61
- value: summaryDetail.current1Value,
62
- measure: '',
63
- id: 4,
64
- },
65
- {
66
- color: Colors.Orange,
67
- standard: 'Active Power',
68
- value: summaryDetail.activePowerValue,
69
- measure: '',
70
- id: 7,
71
- },
72
- {
73
- color: Colors.Green6,
74
- standard: 'Power Factor 1',
75
- value: summaryDetail.powerFactor1Value,
76
- measure: '',
77
- id: 8,
78
- },
76
+ { id: 1, color: '#F5222D', title: 'Voltage 1', measure: 'V' },
77
+ { id: 2, color: '#F5222D', title: 'Voltage 2', measure: 'V' },
78
+ { id: 3, color: '#F5222D', title: 'Voltage 3', measure: 'V' },
79
+ { id: 4, color: '#1890FF', title: 'Current 1', measure: 'A' },
80
+ { id: 5, color: '#1890FF', title: 'Current 2', measure: 'A' },
81
+ { id: 6, color: '#1890FF', title: 'Current 3', measure: 'A' },
82
+ { id: 7, color: '#F08229', title: 'Active Power', measure: 'kW' },
83
+ { id: 8, color: '#52C41A', title: 'Power Factor 1', measure: '' },
84
+ { id: 9, color: '#52C41A', title: 'Power Factor 2', measure: '' },
85
+ { id: 10, color: '#52C41A', title: 'Power Factor 3', measure: '' },
79
86
  ];
80
87
  expect(listIndicator.props.data).toEqual(resultList);
81
88
  });