@eohjsc/react-native-smart-city 0.4.99 → 0.5.0

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 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.99",
4
+ "version": "0.5.00",
5
5
  "description": "TODO",
6
6
  "main": "index.js",
7
7
  "files": [
@@ -50,19 +50,9 @@ const OnOffTemplate = memo(({ item = {}, doAction, sensor = {} }) => {
50
50
  }, [config, configValues, is_on_value]);
51
51
 
52
52
  const [isOn, setIsOn] = useState(false);
53
- const [tempIsOn, setTempIsOn] = useState(getIsOnValue());
54
- const [timeoutId, setTimeoutId] = useState();
55
- const [needUpdateTempIsOn, setNeedUpdateTempIsOn] = useState(false);
56
-
57
- const refreshTempIsOn = useCallback(() => {
58
- const timeout = setTimeout(() => {
59
- setNeedUpdateTempIsOn(true);
60
- }, 7000);
61
- setTimeoutId(timeout);
62
- }, []);
63
53
 
64
54
  const triggerAction = useCallback(async () => {
65
- const action_data = tempIsOn ? action_off_data : action_on_data;
55
+ const action_data = isOn ? action_off_data : action_on_data;
66
56
  if (!action_data) {
67
57
  return;
68
58
  }
@@ -77,11 +67,7 @@ const OnOffTemplate = memo(({ item = {}, doAction, sensor = {} }) => {
77
67
  config_value: isOn ? 0 : 1,
78
68
  };
79
69
  }
80
- clearTimeout(timeoutId);
81
70
  await doAction(action_data, data);
82
- setTempIsOn((prev) => !prev);
83
- setNeedUpdateTempIsOn(false);
84
- refreshTempIsOn();
85
71
  if (
86
72
  is_managed_by_backend &&
87
73
  config &&
@@ -90,17 +76,14 @@ const OnOffTemplate = memo(({ item = {}, doAction, sensor = {} }) => {
90
76
  watchMultiConfigs([config]);
91
77
  }
92
78
  }, [
93
- tempIsOn,
79
+ isOn,
94
80
  action_off_data,
95
81
  action_on_data,
96
82
  allow_config_store_value,
97
83
  config,
98
84
  device_type,
99
- timeoutId,
100
85
  doAction,
101
- refreshTempIsOn,
102
86
  is_managed_by_backend,
103
- isOn,
104
87
  ]);
105
88
 
106
89
  useUnwatchLGDeviceConfigControl(sensor, [config]);
@@ -109,16 +92,6 @@ const OnOffTemplate = memo(({ item = {}, doAction, sensor = {} }) => {
109
92
  setIsOn(getIsOnValue());
110
93
  }, [getIsOnValue]);
111
94
 
112
- useEffect(() => {
113
- needUpdateTempIsOn && setTempIsOn(getIsOnValue());
114
- }, [getIsOnValue, needUpdateTempIsOn]);
115
-
116
- useEffect(() => {
117
- if (device_type !== DEVICE_TYPE.LG_THINQ) {
118
- setTempIsOn(getIsOnValue());
119
- }
120
- }, [getIsOnValue, device_type]);
121
-
122
95
  const Component = useMemo(() => {
123
96
  return getComponent(item.template);
124
97
  }, [item.template]);
@@ -126,7 +99,7 @@ const OnOffTemplate = memo(({ item = {}, doAction, sensor = {} }) => {
126
99
  return (
127
100
  <View style={styles.wrap}>
128
101
  <Component
129
- isOn={tempIsOn}
102
+ isOn={isOn}
130
103
  triggerAction={triggerAction}
131
104
  actionGroup={configuration}
132
105
  disabled={!action_on_data && !action_off_data}
@@ -20,7 +20,7 @@ import _TextInput from '../Form/TextInput';
20
20
  const SliderRangeTemplate = memo(
21
21
  ({ item = {}, doAction, sensor, isWidgetOrder }) => {
22
22
  const t = useTranslations();
23
- const { configuration = {} } = item;
23
+ const { configuration = {}, title, label } = item;
24
24
  const [configValues] = useConfigGlobalState('configValues');
25
25
  const {
26
26
  config = undefined,
@@ -91,7 +91,7 @@ const SliderRangeTemplate = memo(
91
91
  <View
92
92
  style={(isWidgetOrder && styles.wrapOrderItem) || styles.viewBrightness}
93
93
  >
94
- <Text type="H4">{item?.title || item?.label || t('brightness')}</Text>
94
+ <Text type="H4">{title || label || t('brightness')}</Text>
95
95
  <View style={styles.wrap}>
96
96
  <Slider
97
97
  step={1}
@@ -68,14 +68,14 @@ const TerminalBoxTemplate = ({ item, doAction, isWidgetOrder }) => {
68
68
  setValue(e);
69
69
  };
70
70
 
71
- const fromValue = useMemo(() => {
72
- return configValues[from_config?.id];
73
- }, [configValues, from_config]);
74
-
75
71
  const toValue = useMemo(() => {
76
72
  return configValues[to_config?.id];
77
73
  }, [configValues, to_config]);
78
74
 
75
+ const fromValue = useMemo(() => {
76
+ return configValues[from_config?.id];
77
+ }, [configValues, from_config]);
78
+
79
79
  const configs = useMemo(() => {
80
80
  if (!from_config || !to_config) {
81
81
  return [];
@@ -172,7 +172,7 @@ const TerminalBoxTemplate = ({ item, doAction, isWidgetOrder }) => {
172
172
  accessibilityLabel={AccessibilityLabel.TERMINAL_BOX_BUTTON_SEND}
173
173
  disabled={!value}
174
174
  >
175
- <IconOutline name="send" size={20} />
175
+ <IconOutline name="send" size={25} />
176
176
  </TouchableOpacity>
177
177
  </View>
178
178
  </View>
@@ -24,7 +24,10 @@ export default StyleSheet.create({
24
24
  width: '100%',
25
25
  },
26
26
  iconAndTextOption: {
27
+ justifyContent: 'center',
27
28
  marginTop: 25,
29
+ width: 40,
30
+ height: 40,
28
31
  },
29
32
  wrapInputStyle: {
30
33
  marginRight: 14,
@@ -40,33 +40,35 @@ const TextBoxTemplate = ({ item, doAction, isWidgetOrder }) => {
40
40
  </View>
41
41
 
42
42
  <View style={styles.iconAndText}>
43
- <Text type="H4">{valueText}</Text>
43
+ <Text style={styles.textValue} type="H4">
44
+ {valueText}
45
+ </Text>
44
46
  <TouchableOpacity
45
47
  style={styles.iconAndTextOption}
46
48
  onPress={onShowAlert}
47
49
  accessibilityLabel={AccessibilityLabel.TEXT_BOX_BUTTON_EDIT}
48
50
  >
49
- <IconOutline name="edit" size={20} />
51
+ <IconOutline name="edit" size={25} />
50
52
  </TouchableOpacity>
51
- <AlertAction
52
- visible={stateAlert.visible}
53
- hideModal={hideAlertAction}
54
- title={t('enter_parameters')}
55
- message={stateAlert.message}
56
- leftButtonTitle={stateAlert.leftButton}
57
- leftButtonClick={hideAlertAction}
58
- rightButtonTitle={stateAlert.rightButton}
59
- rightButtonClick={onDone}
60
- rightDisabled={!value}
61
- transY={transY}
62
- >
63
- <_TextInput
64
- wrapStyle={styles.wrapInputStyle}
65
- value={value}
66
- onChange={onInputChange}
67
- />
68
- </AlertAction>
69
53
  </View>
54
+ <AlertAction
55
+ visible={stateAlert.visible}
56
+ hideModal={hideAlertAction}
57
+ title={t('enter_parameters')}
58
+ message={stateAlert.message}
59
+ leftButtonTitle={stateAlert.leftButton}
60
+ leftButtonClick={hideAlertAction}
61
+ rightButtonTitle={stateAlert.rightButton}
62
+ rightButtonClick={onDone}
63
+ rightDisabled={!value}
64
+ transY={transY}
65
+ >
66
+ <_TextInput
67
+ wrapStyle={styles.wrapInputStyle}
68
+ value={value}
69
+ onChange={onInputChange}
70
+ />
71
+ </AlertAction>
70
72
  </View>
71
73
  );
72
74
  };
@@ -24,6 +24,9 @@ export default StyleSheet.create({
24
24
  flexDirection: 'row',
25
25
  alignItems: 'center',
26
26
  },
27
+ textValue: {
28
+ width: '80%',
29
+ },
27
30
  iconAndTextOption: {
28
31
  flex: 1,
29
32
  flexDirection: 'row',
@@ -3,7 +3,7 @@ import { View } from 'react-native';
3
3
  import { FlatList } from 'react-native';
4
4
  import QualityIndicatorItem from '../WaterQualitySensor/QualityIndicatorsItem';
5
5
  import styles from './PMSensorIndicatorStyles';
6
- import { keyExtractor, roundNumber } from '../../../utils/Utils';
6
+ import { keyExtractor } from '../../../utils/Utils';
7
7
  import { useConfigGlobalState } from '../../../iot/states';
8
8
 
9
9
  const PMSensorIndicator = memo(({ data = [], style, isWidgetOrder }) => {
@@ -12,10 +12,8 @@ const PMSensorIndicator = memo(({ data = [], style, isWidgetOrder }) => {
12
12
  const renderItem = useCallback(
13
13
  ({ item }) => {
14
14
  const { id, color, title, standard, evaluate, unit } = item || {};
15
- const getValue =
16
- configValues?.[id]?.value === undefined
17
- ? '--'
18
- : `${roundNumber(configValues[id].value)}`;
15
+ const value = configValues[id]?.value;
16
+ const getValue = value === undefined ? '--' : value;
19
17
 
20
18
  return (
21
19
  <QualityIndicatorItem
@@ -9,7 +9,7 @@ import { Colors, Constants } from '../../configs';
9
9
  import { AccessibilityLabel } from '../../configs/Constants';
10
10
 
11
11
  const screenHeight = Constants.height;
12
- const default_height = 44;
12
+ const default_height = 45;
13
13
  const paddingIos = getStatusBarHeight() + 10;
14
14
  export const title_height = 44;
15
15
  export const heightHeader = default_height + title_height + paddingIos;
@@ -45,6 +45,7 @@ jest.mock('../../../iot/states', () => ({
45
45
  describe('test ShortDetail Subunit', () => {
46
46
  let tree, props;
47
47
  beforeEach(() => {
48
+ jest.useFakeTimers();
48
49
  props = {
49
50
  unit: {
50
51
  address: null,
@@ -187,6 +188,7 @@ describe('test ShortDetail Subunit', () => {
187
188
  await act(async () => {
188
189
  tree = await create(wrapComponent(props));
189
190
  });
191
+ jest.runOnlyPendingTimers();
190
192
  expect(watchMultiConfigs).toBeCalledWith([1]);
191
193
  });
192
194
 
@@ -40,6 +40,7 @@ describe('Test useWatchConfigs', () => {
40
40
  renderHook(() => useWatchConfigs([1]), {
41
41
  wrapper,
42
42
  });
43
+ jest.runAllTimers();
43
44
  expect(watchMultiConfigs).toBeCalledWith([1]);
44
45
  expect(unwatchMultiConfigs).toBeCalledWith([1]);
45
46
  });
@@ -17,11 +17,13 @@ const useWatchConfigs = (configIds) => {
17
17
  return;
18
18
  }
19
19
 
20
- watchMultiConfigs(configIds);
21
20
  clearInterval(intervalId);
22
21
  intervalId = setInterval(() => {
23
22
  watchMultiConfigs(configIds);
24
23
  }, SCConfig.intervalWatchConfigTime);
24
+ setTimeout(() => {
25
+ watchMultiConfigs(configIds);
26
+ }, 500); // Delay 500ms to ensure unwatchMultiConfigs will execute before watchMultiConfigs
25
27
 
26
28
  return () => {
27
29
  unwatchMultiConfigs(configIds);
package/src/iot/mqtt.js CHANGED
@@ -1,3 +1,4 @@
1
+ import moment from 'moment';
1
2
  import { updateGlobalValue } from './Monitor';
2
3
  import { Buffer } from 'buffer';
3
4
 
@@ -134,12 +135,16 @@ const get_sensor_data = (sensor, data) => {
134
135
  };
135
136
 
136
137
  const get_scale_value = (value, config) => {
137
- value = value && value * (config?.scale || 1);
138
- value =
139
- config?.decimal_behind || config?.decimal_behind === 0
140
- ? value.toFixed(config?.decimal_behind)
141
- : value;
142
- return value;
138
+ if (!value || typeof value === 'string') {
139
+ return value;
140
+ }
141
+ const { decimal_behind, scale } = config;
142
+ let scaledValue = value * (scale || 1);
143
+
144
+ if (decimal_behind || decimal_behind === 0) {
145
+ scaledValue = scaledValue.toFixed(decimal_behind);
146
+ }
147
+ return Number(scaledValue);
143
148
  };
144
149
 
145
150
  const updateGlobalValueMqtt = (config, value) => {
@@ -151,7 +156,12 @@ const updateGlobalValueMqtt = (config, value) => {
151
156
  }
152
157
 
153
158
  value = get_scale_value(value, config);
154
- updateGlobalValue(config.id, { value: Number(value) });
159
+ updateGlobalValue(config.id, { value: value });
160
+ };
161
+
162
+ const arduinoUpdateGlobalValueMqtt = (config, value, last_updated) => {
163
+ value = get_scale_value(value, config);
164
+ updateGlobalValue(config.id, { value: value, last_updated: last_updated });
155
165
  };
156
166
 
157
167
  export const handleModbusData = (chip, configById, data) => {
@@ -178,7 +188,11 @@ export const handleModbusData = (chip, configById, data) => {
178
188
  };
179
189
 
180
190
  export const handleChipData = (configById, configId, data) => {
181
- updateGlobalValueMqtt(configById[configId], Number(data?.v));
191
+ arduinoUpdateGlobalValueMqtt(
192
+ configById[configId],
193
+ data?.v,
194
+ moment().format('YYYY-MM-DDTHH:mm:ss.SSSSSS')
195
+ );
182
196
  };
183
197
 
184
198
  export const handleZigbeeData = (chip, configById, ieee_address, data) => {
@@ -221,7 +235,7 @@ export const handleMqttMessage = (
221
235
  if (matchArduinoConfigValue) {
222
236
  // Arduino
223
237
  // topic: eoh/chip/{code}/config/127363/value
224
- // payload: {v: 2130}
238
+ // payload: {v: 2130} or {v: 'on'}
225
239
  handleChipData(configById, matchArduinoConfigValue[1], payloadData);
226
240
  }
227
241
 
@@ -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,20 @@ 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
+ expect(valueBoxs[1].props.value).toEqual('--');
501
+ });
502
+
503
+ it('arduino pin submit data type string updateGlobalValue', async () => {
504
+ const valueBoxs = await _receiveDataOnDeviceDetail(
505
+ [{ id: 128282 }, { id: 128324 }],
506
+ 'config/128282/value/',
507
+ {
508
+ v: 'on',
509
+ }
510
+ );
511
+
512
+ expect(valueBoxs[0].props.value).toEqual('on');
500
513
  expect(valueBoxs[1].props.value).toEqual('--');
501
514
  });
502
515
 
@@ -538,7 +551,7 @@ describe('test DeviceDetail', () => {
538
551
  }
539
552
  );
540
553
 
541
- expect(valueBoxs[0].props.value).toEqual('36');
554
+ expect(valueBoxs[0].props.value).toEqual(36);
542
555
  expect(valueBoxs[1].props.value).toEqual('--');
543
556
  });
544
557
 
@@ -615,7 +615,7 @@ const DeviceDetail = ({ route }) => {
615
615
  }, [display.items, isNetworkConnected, sensor, mqttConfigs])
616
616
  );
617
617
 
618
- useWatchConfigs(configIdsTemp.current);
618
+ useWatchConfigs(chipFiltered.length ? [] : configIdsTemp.current);
619
619
 
620
620
  const isShowEmergencyResolve =
621
621
  display.items.filter(
@@ -751,6 +751,7 @@ const DeviceDetail = ({ route }) => {
751
751
  }
752
752
  showWindDirection={showWindDirection}
753
753
  isDeviceHasBle={isDeviceHasBle}
754
+ key={`sensor${sensor.id}`}
754
755
  >
755
756
  {display.items.map((item, index) => {
756
757
  return (
@@ -8,12 +8,11 @@ export const useDeviceWatchConfigControl = (
8
8
  display,
9
9
  mqttConfigs = {}
10
10
  ) => {
11
+ const { is_managed_by_backend, device_type } = device;
11
12
  const configsNeedWatching = useMemo(() => {
12
13
  if (
13
- !device?.is_managed_by_backend ||
14
- [DEVICE_TYPE.GOOGLE_HOME, DEVICE_TYPE.LG_THINQ].includes(
15
- device?.device_type
16
- )
14
+ !is_managed_by_backend ||
15
+ [DEVICE_TYPE.GOOGLE_HOME, DEVICE_TYPE.LG_THINQ].includes(device_type)
17
16
  ) {
18
17
  return [];
19
18
  }
@@ -24,11 +23,6 @@ export const useDeviceWatchConfigControl = (
24
23
  );
25
24
  }
26
25
  return configsControl;
27
- }, [
28
- mqttConfigs,
29
- device?.device_type,
30
- device?.is_managed_by_backend,
31
- display,
32
- ]);
26
+ }, [is_managed_by_backend, device_type, display, mqttConfigs]);
33
27
  useWatchConfigs(configsNeedWatching);
34
28
  };