@eohjsc/react-native-smart-city 0.7.41 → 0.7.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/commons/Dashboard/MyDashboardDevice/index.js +14 -12
- package/src/commons/Dashboard/MyUnit/index.js +4 -3
- package/src/commons/DateTimeRangeChange/index.js +5 -5
- package/src/commons/Device/HorizontalBarChart.js +11 -24
- package/src/commons/Device/PowerConsumptionChart.js +195 -103
- package/src/commons/Form/CurrencyInput.js +9 -18
- package/src/commons/SubUnit/Favorites/index.js +35 -10
- package/src/commons/SubUnit/ShortDetail.js +17 -4
- package/src/commons/SubUnit/__test__/Favorites.test.js +90 -0
- package/src/commons/SubUnit/__test__/ShortDetail.test.js +45 -2
- package/src/hooks/IoT/__test__/useValueEvaluation.test.js +12 -12
- package/src/iot/UpdateStates.js +37 -16
- package/src/iot/mqtt.js +23 -0
- package/src/screens/Device/__test__/DeviceDetail-3rdparty.test.js +16 -5
- package/src/screens/Device/__test__/DeviceDetail-arduino.test.js +10 -0
- package/src/screens/Device/__test__/DeviceDetail-modbus.test.js +37 -8
- package/src/screens/Device/__test__/DeviceDetail-zigbee.test.js +16 -5
- package/src/screens/Device/__test__/DeviceDetail.test.js +17 -6
- package/src/screens/Device/__test__/sensorDisplayItem.test.js +47 -11
- package/src/screens/Device/components/SensorDisplayItem.js +23 -5
- package/src/screens/Device/styles.js +4 -0
- package/src/screens/UnitSummary/components/3PPowerConsumption/index.js +8 -49
- package/src/screens/UnitSummary/components/PowerConsumption/__test__/PowerConsumption.test.js +121 -6
- package/src/screens/UnitSummary/components/PowerConsumption/index.js +6 -47
- package/src/utils/I18n/translations/en.js +1 -0
- package/src/utils/I18n/translations/vi.js +1 -0
- package/src/utils/chartHelper/index.js +53 -0
- package/src/utils/chartHelper/getMaxValueIndex.js +0 -11
|
@@ -32,14 +32,17 @@ const ShortDetailSubUnit = ({ unit, station, isOwner }) => {
|
|
|
32
32
|
|
|
33
33
|
useDevicesStatus(unit, station?.devices);
|
|
34
34
|
|
|
35
|
+
const stationChipIdsSet = useMemo(() => {
|
|
36
|
+
return new Set(station?.devices?.map((device) => device.chip_id));
|
|
37
|
+
}, [station?.devices]);
|
|
38
|
+
|
|
35
39
|
const { chips, isFetching } = useChipJsonConfiguration({
|
|
36
40
|
dashboardId: unit?.id,
|
|
37
41
|
});
|
|
38
42
|
|
|
39
43
|
const listChipsMqtt = useMemo(() => {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}, [chips, station?.devices]);
|
|
44
|
+
return chips.filter((chip) => stationChipIdsSet.has(chip.id));
|
|
45
|
+
}, [chips, stationChipIdsSet]);
|
|
43
46
|
|
|
44
47
|
const { mqttConfigs } = useConnectChipMqtt(listChipsMqtt);
|
|
45
48
|
|
|
@@ -64,7 +67,17 @@ const ShortDetailSubUnit = ({ unit, station, isOwner }) => {
|
|
|
64
67
|
}, [station, mqttConfigs]);
|
|
65
68
|
|
|
66
69
|
useWatchConfigs(isFetching ? [] : configsNeedWatching);
|
|
67
|
-
|
|
70
|
+
|
|
71
|
+
const listSharedChipIds = useMemo(() => {
|
|
72
|
+
const chipMqttIdsSet = new Set(listChipsMqtt.map((chip) => chip.id));
|
|
73
|
+
return [...stationChipIdsSet].filter((id) => !chipMqttIdsSet.has(id));
|
|
74
|
+
}, [listChipsMqtt, stationChipIdsSet]);
|
|
75
|
+
|
|
76
|
+
useWatchSharedChips({
|
|
77
|
+
dashboardId: unit?.id,
|
|
78
|
+
filterChipIds: listSharedChipIds,
|
|
79
|
+
ready: !!listSharedChipIds.length,
|
|
80
|
+
});
|
|
68
81
|
|
|
69
82
|
const goToPlayBack = useCallback(() => {
|
|
70
83
|
navigate(Routes.PlaybackCamera, {
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import MockAdapter from 'axios-mock-adapter';
|
|
2
3
|
import { act, create } from 'react-test-renderer';
|
|
4
|
+
import { API } from '../../../configs';
|
|
3
5
|
import { SCProvider } from '../../../context';
|
|
4
6
|
import { mockSCStore } from '../../../context/mockStore';
|
|
7
|
+
import { watchMultiDataChips, watchMultiConfigs } from '../../../iot/Monitor';
|
|
8
|
+
import api from '../../../utils/Apis/axios';
|
|
9
|
+
import { gatewayDataFactory } from '../../../utils/FactoryGateway';
|
|
5
10
|
import ItemAddNew from '../../Device/ItemAddNew';
|
|
6
11
|
import ItemDevice from '../../Device/ItemDevice';
|
|
7
12
|
import SubUnitFavorites from '../Favorites';
|
|
8
13
|
import ItemOneTap from '../OneTap/ItemOneTap';
|
|
9
14
|
|
|
15
|
+
const mockAxios = new MockAdapter(api.axiosInstance);
|
|
16
|
+
|
|
17
|
+
jest.mock('../../../iot/Monitor');
|
|
18
|
+
|
|
10
19
|
const wrapComponent = (props) => (
|
|
11
20
|
<SCProvider initState={mockSCStore({})}>
|
|
12
21
|
<SubUnitFavorites {...props} />
|
|
@@ -18,6 +27,7 @@ describe('test ShortDetail Subunit', () => {
|
|
|
18
27
|
let props;
|
|
19
28
|
|
|
20
29
|
beforeEach(() => {
|
|
30
|
+
jest.useFakeTimers();
|
|
21
31
|
props = {
|
|
22
32
|
unit: {
|
|
23
33
|
address: null,
|
|
@@ -78,6 +88,8 @@ describe('test ShortDetail Subunit', () => {
|
|
|
78
88
|
],
|
|
79
89
|
isGGHomeConnected: true,
|
|
80
90
|
};
|
|
91
|
+
watchMultiConfigs.mockClear();
|
|
92
|
+
watchMultiDataChips.mockClear();
|
|
81
93
|
});
|
|
82
94
|
|
|
83
95
|
it('render SubUnitFavorites', async () => {
|
|
@@ -96,4 +108,82 @@ describe('test ShortDetail Subunit', () => {
|
|
|
96
108
|
await itemAddNew[0].props.onAddNew();
|
|
97
109
|
});
|
|
98
110
|
});
|
|
111
|
+
|
|
112
|
+
it('render using mqtt call watch config and data chips', async () => {
|
|
113
|
+
mockAxios
|
|
114
|
+
.onGet(API.CHIP.JSON_CONFIGURATION)
|
|
115
|
+
.reply(200, [gatewayDataFactory]);
|
|
116
|
+
mockAxios
|
|
117
|
+
.onGet(API.CHIP.SHARED_CONFIGURATION)
|
|
118
|
+
.reply(200, [gatewayDataFactory, { ...gatewayDataFactory, id: 7690 }]);
|
|
119
|
+
props.favoriteDevices = [
|
|
120
|
+
{
|
|
121
|
+
action: {
|
|
122
|
+
color: '#00979D',
|
|
123
|
+
icon: 'caretup',
|
|
124
|
+
id: 1,
|
|
125
|
+
key: '',
|
|
126
|
+
},
|
|
127
|
+
action2: null,
|
|
128
|
+
chip_id: 7690,
|
|
129
|
+
description: null,
|
|
130
|
+
icon: '',
|
|
131
|
+
id: 1,
|
|
132
|
+
name: 'People Counting',
|
|
133
|
+
quick_action: { config_id: 128283 },
|
|
134
|
+
remote_control_options: {},
|
|
135
|
+
station: {},
|
|
136
|
+
status: null,
|
|
137
|
+
status2: null,
|
|
138
|
+
is_managed_by_backend: true,
|
|
139
|
+
},
|
|
140
|
+
];
|
|
141
|
+
|
|
142
|
+
await act(async () => {
|
|
143
|
+
tree = await create(wrapComponent(props));
|
|
144
|
+
});
|
|
145
|
+
await act(async () => {
|
|
146
|
+
jest.runOnlyPendingTimers();
|
|
147
|
+
});
|
|
148
|
+
expect(watchMultiConfigs).toHaveBeenCalledWith([128283]);
|
|
149
|
+
expect(watchMultiDataChips).toHaveBeenCalledWith([7690]);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it('render using mqtt not call watch config and data chips', async () => {
|
|
153
|
+
mockAxios
|
|
154
|
+
.onGet(API.CHIP.JSON_CONFIGURATION)
|
|
155
|
+
.reply(200, [gatewayDataFactory]);
|
|
156
|
+
mockAxios.onGet(API.CHIP.SHARED_CONFIGURATION).reply(200, []);
|
|
157
|
+
props.favoriteDevices = [
|
|
158
|
+
{
|
|
159
|
+
action: {
|
|
160
|
+
color: '#00979D',
|
|
161
|
+
icon: 'caretup',
|
|
162
|
+
id: 1,
|
|
163
|
+
key: '',
|
|
164
|
+
},
|
|
165
|
+
action2: null,
|
|
166
|
+
chip_id: 7689,
|
|
167
|
+
description: null,
|
|
168
|
+
icon: '',
|
|
169
|
+
id: 1,
|
|
170
|
+
name: 'People Counting',
|
|
171
|
+
quick_action: { config_id: 128282 },
|
|
172
|
+
remote_control_options: {},
|
|
173
|
+
station: {},
|
|
174
|
+
status: null,
|
|
175
|
+
status2: null,
|
|
176
|
+
is_managed_by_backend: true,
|
|
177
|
+
},
|
|
178
|
+
];
|
|
179
|
+
|
|
180
|
+
await act(async () => {
|
|
181
|
+
tree = await create(wrapComponent(props));
|
|
182
|
+
});
|
|
183
|
+
await act(async () => {
|
|
184
|
+
jest.runOnlyPendingTimers();
|
|
185
|
+
});
|
|
186
|
+
expect(watchMultiConfigs).not.toHaveBeenCalled();
|
|
187
|
+
expect(watchMultiDataChips).not.toHaveBeenCalled();
|
|
188
|
+
});
|
|
99
189
|
});
|
|
@@ -7,7 +7,7 @@ import { API } from '../../../configs';
|
|
|
7
7
|
import { AccessibilityLabel } from '../../../configs/Constants';
|
|
8
8
|
import { SCProvider } from '../../../context';
|
|
9
9
|
import { mockSCStore } from '../../../context/mockStore';
|
|
10
|
-
import { watchMultiConfigs } from '../../../iot/Monitor';
|
|
10
|
+
import { watchMultiDataChips, watchMultiConfigs } from '../../../iot/Monitor';
|
|
11
11
|
import { keyPermission } from '../../../utils/Permission/common';
|
|
12
12
|
import api from '../../../utils/Apis/axios';
|
|
13
13
|
import Routes from '../../../utils/Route';
|
|
@@ -78,6 +78,7 @@ describe('test ShortDetail Subunit', () => {
|
|
|
78
78
|
isGGHomeConnected: true,
|
|
79
79
|
};
|
|
80
80
|
watchMultiConfigs.mockClear();
|
|
81
|
+
watchMultiDataChips.mockClear();
|
|
81
82
|
});
|
|
82
83
|
|
|
83
84
|
it('render ShortDetail', async () => {
|
|
@@ -191,10 +192,51 @@ describe('test ShortDetail Subunit', () => {
|
|
|
191
192
|
expect(watchMultiConfigs).toHaveBeenCalledWith([1]);
|
|
192
193
|
});
|
|
193
194
|
|
|
194
|
-
it('render using mqtt
|
|
195
|
+
it('render using mqtt call watch config and data chips', async () => {
|
|
195
196
|
mockAxios
|
|
196
197
|
.onGet(API.CHIP.JSON_CONFIGURATION)
|
|
197
198
|
.reply(200, [gatewayDataFactory]);
|
|
199
|
+
mockAxios
|
|
200
|
+
.onGet(API.CHIP.SHARED_CONFIGURATION)
|
|
201
|
+
.reply(200, [gatewayDataFactory, { ...gatewayDataFactory, id: 7690 }]);
|
|
202
|
+
props.station.devices = [
|
|
203
|
+
{
|
|
204
|
+
action: {
|
|
205
|
+
color: '#00979D',
|
|
206
|
+
icon: 'caretup',
|
|
207
|
+
id: 1,
|
|
208
|
+
key: '',
|
|
209
|
+
},
|
|
210
|
+
action2: null,
|
|
211
|
+
chip_id: 7690,
|
|
212
|
+
description: null,
|
|
213
|
+
icon: '',
|
|
214
|
+
id: 1,
|
|
215
|
+
name: 'People Counting',
|
|
216
|
+
quick_action: { config_id: 128283 },
|
|
217
|
+
remote_control_options: {},
|
|
218
|
+
station: {},
|
|
219
|
+
status: null,
|
|
220
|
+
status2: null,
|
|
221
|
+
is_managed_by_backend: true,
|
|
222
|
+
},
|
|
223
|
+
];
|
|
224
|
+
|
|
225
|
+
await act(async () => {
|
|
226
|
+
tree = await create(wrapComponent(props));
|
|
227
|
+
});
|
|
228
|
+
await act(async () => {
|
|
229
|
+
jest.runOnlyPendingTimers();
|
|
230
|
+
});
|
|
231
|
+
expect(watchMultiConfigs).toHaveBeenCalledWith([128283]);
|
|
232
|
+
expect(watchMultiDataChips).toHaveBeenCalledWith([7690]);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it('render using mqtt not call watch config and data chips', async () => {
|
|
236
|
+
mockAxios
|
|
237
|
+
.onGet(API.CHIP.JSON_CONFIGURATION)
|
|
238
|
+
.reply(200, [gatewayDataFactory]);
|
|
239
|
+
mockAxios.onGet(API.CHIP.SHARED_CONFIGURATION).reply(200, []);
|
|
198
240
|
props.station.devices = [
|
|
199
241
|
{
|
|
200
242
|
action: {
|
|
@@ -225,6 +267,7 @@ describe('test ShortDetail Subunit', () => {
|
|
|
225
267
|
jest.runOnlyPendingTimers();
|
|
226
268
|
});
|
|
227
269
|
expect(watchMultiConfigs).not.toHaveBeenCalled();
|
|
270
|
+
expect(watchMultiDataChips).not.toHaveBeenCalled();
|
|
228
271
|
});
|
|
229
272
|
|
|
230
273
|
['ConfigAndEvaluation', 'ConfigValue', 'EvaluationOverConfig'].forEach(
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { renderHook } from '@testing-library/react-hooks';
|
|
1
|
+
import { act, renderHook } from '@testing-library/react-hooks';
|
|
3
2
|
import MockAdapter from 'axios-mock-adapter';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { API } from '../../../configs';
|
|
4
5
|
import { SCProvider } from '../../../context';
|
|
5
6
|
import { mockSCStore } from '../../../context/mockStore';
|
|
6
|
-
import { useValueEvaluations } from '../index';
|
|
7
7
|
import api from '../../../utils/Apis/axios';
|
|
8
|
-
import {
|
|
8
|
+
import { useValueEvaluations } from '../index';
|
|
9
9
|
|
|
10
10
|
const mock = new MockAdapter(api.axiosInstance);
|
|
11
11
|
|
|
@@ -35,13 +35,11 @@ describe('Test useValueEvaluation', () => {
|
|
|
35
35
|
it('test unitId not null request success', async () => {
|
|
36
36
|
mock.onGet(API.VALUE_EVALUATIONS()).replyOnce(200, {
|
|
37
37
|
results: [],
|
|
38
|
-
next: 'link',
|
|
39
38
|
});
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
wrapper,
|
|
39
|
+
await act(async () => {
|
|
40
|
+
renderHook(() => useValueEvaluations(1), {
|
|
41
|
+
wrapper,
|
|
42
|
+
});
|
|
45
43
|
});
|
|
46
44
|
expect(mock.history.get.length).toBe(1);
|
|
47
45
|
});
|
|
@@ -50,8 +48,10 @@ describe('Test useValueEvaluation', () => {
|
|
|
50
48
|
mock.onGet(API.VALUE_EVALUATIONS()).replyOnce(400, {
|
|
51
49
|
results: [],
|
|
52
50
|
});
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
await act(async () => {
|
|
52
|
+
renderHook(() => useValueEvaluations(1), {
|
|
53
|
+
wrapper,
|
|
54
|
+
});
|
|
55
55
|
});
|
|
56
56
|
expect(mock.history.get.length).toBe(1);
|
|
57
57
|
});
|
package/src/iot/UpdateStates.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import moment from 'moment';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { setConfigGlobalState } from './states';
|
|
4
4
|
|
|
5
5
|
const isNewer = (valueTime, valueMicro, currentTime, currentMicro) => {
|
|
6
6
|
if (valueTime?.isAfter(currentTime)) {
|
|
@@ -40,21 +40,42 @@ export const updateGlobalValues = (data) => {
|
|
|
40
40
|
});
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
+
let pending = {};
|
|
44
|
+
let scheduled = false;
|
|
45
|
+
|
|
43
46
|
export const updateGlobalValue = (configId, value) => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
47
|
+
pending[configId] = value;
|
|
48
|
+
|
|
49
|
+
if (!scheduled) {
|
|
50
|
+
scheduled = true;
|
|
51
|
+
|
|
52
|
+
requestAnimationFrame(() => {
|
|
53
|
+
setConfigGlobalState('configValues', (prev) => {
|
|
54
|
+
let changed = false;
|
|
55
|
+
const next = { ...prev };
|
|
56
|
+
|
|
57
|
+
Object.keys(pending).forEach((id) => {
|
|
58
|
+
const val = pending[id];
|
|
59
|
+
const cur = prev[id];
|
|
60
|
+
|
|
61
|
+
if (
|
|
62
|
+
isNewer(
|
|
63
|
+
val.last_updated,
|
|
64
|
+
val.last_updated_micro,
|
|
65
|
+
cur?.last_updated || moment(0),
|
|
66
|
+
cur?.last_updated_micro || 0
|
|
67
|
+
)
|
|
68
|
+
) {
|
|
69
|
+
next[id] = val;
|
|
70
|
+
changed = true;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
pending = {};
|
|
75
|
+
scheduled = false;
|
|
76
|
+
|
|
77
|
+
return changed ? next : prev;
|
|
78
|
+
});
|
|
79
|
+
});
|
|
55
80
|
}
|
|
56
|
-
setConfigGlobalState('configValues', {
|
|
57
|
-
...configValues,
|
|
58
|
-
[configId]: value,
|
|
59
|
-
});
|
|
60
81
|
};
|
package/src/iot/mqtt.js
CHANGED
|
@@ -193,6 +193,19 @@ const convert_ai = (bytes_str, config_data = null) => {
|
|
|
193
193
|
);
|
|
194
194
|
};
|
|
195
195
|
|
|
196
|
+
const power_factor_4q_fp_pf = (value) => {
|
|
197
|
+
let pfVal;
|
|
198
|
+
if (value > 1) {
|
|
199
|
+
pfVal = 2 - value;
|
|
200
|
+
} else if (value < -1) {
|
|
201
|
+
pfVal = -2 - value;
|
|
202
|
+
} else {
|
|
203
|
+
pfVal = value;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return pfVal;
|
|
207
|
+
};
|
|
208
|
+
|
|
196
209
|
const mappingTransformer = {
|
|
197
210
|
int_all: int_all,
|
|
198
211
|
float_abcd: float_abcd,
|
|
@@ -224,6 +237,10 @@ const mappingTransformer = {
|
|
|
224
237
|
int_64_cdab: int_64_cdab,
|
|
225
238
|
};
|
|
226
239
|
|
|
240
|
+
const mappingValueConverter = {
|
|
241
|
+
power_factor_4q_fp_pf: power_factor_4q_fp_pf,
|
|
242
|
+
};
|
|
243
|
+
|
|
227
244
|
const extract_config_value = (register, value_bytes) => {
|
|
228
245
|
const transformer = mappingTransformer[register?.transformer];
|
|
229
246
|
if (!transformer) {
|
|
@@ -303,6 +320,11 @@ const get_offset_sample_value = async (value, config) => {
|
|
|
303
320
|
return value;
|
|
304
321
|
};
|
|
305
322
|
|
|
323
|
+
const getValueConverter = (value, config) => {
|
|
324
|
+
const converter = mappingValueConverter[config?.value_converter];
|
|
325
|
+
return converter ? converter(value) : value;
|
|
326
|
+
};
|
|
327
|
+
|
|
306
328
|
const check_filter = (value, config) => {
|
|
307
329
|
if (!config?.active_filter) {
|
|
308
330
|
return false;
|
|
@@ -333,6 +355,7 @@ const updateGlobalValueMqtt = async (config, value, time) => {
|
|
|
333
355
|
|
|
334
356
|
value = get_scale_value(value, config);
|
|
335
357
|
value = await get_offset_sample_value(value, config);
|
|
358
|
+
value = getValueConverter(value, config);
|
|
336
359
|
|
|
337
360
|
if (check_filter(value, config)) {
|
|
338
361
|
return;
|
|
@@ -120,6 +120,12 @@ describe('test DeviceDetail', () => {
|
|
|
120
120
|
mock.onGet(API.CHIP.SHARED_CONFIGURATION).reply(200, []);
|
|
121
121
|
});
|
|
122
122
|
|
|
123
|
+
afterEach(() => {
|
|
124
|
+
act(() => {
|
|
125
|
+
jest.runOnlyPendingTimers();
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
123
129
|
const _receiveDataOnDeviceDetail = async (widgetConfigs, topic, message) => {
|
|
124
130
|
mock.onGet(API.CHIP.JSON_CONFIGURATION).reply(200, [gatewayData]);
|
|
125
131
|
|
|
@@ -168,6 +174,10 @@ describe('test DeviceDetail', () => {
|
|
|
168
174
|
await client.trigger('message', topic, JSON.stringify(message), 'packet');
|
|
169
175
|
});
|
|
170
176
|
|
|
177
|
+
await act(async () => {
|
|
178
|
+
jest.runOnlyPendingTimers();
|
|
179
|
+
});
|
|
180
|
+
|
|
171
181
|
const valueBox = instance.findAllByType(QualityIndicatorItem);
|
|
172
182
|
return valueBox;
|
|
173
183
|
};
|
|
@@ -370,11 +380,6 @@ describe('test DeviceDetail', () => {
|
|
|
370
380
|
);
|
|
371
381
|
});
|
|
372
382
|
|
|
373
|
-
const instance = tree.root;
|
|
374
|
-
const valueBoxs = instance.findAllByType(QualityIndicatorItem);
|
|
375
|
-
expect(valueBoxs[0].props.value).toEqual(expect1);
|
|
376
|
-
expect(valueBoxs[1].props.value).toEqual(expect2);
|
|
377
|
-
|
|
378
383
|
expect(
|
|
379
384
|
mock.history.post.filter(
|
|
380
385
|
(req) => req.url === API.IOT.CHIP_MANAGER.WATCH_DATA_CHIPS()
|
|
@@ -384,6 +389,7 @@ describe('test DeviceDetail', () => {
|
|
|
384
389
|
await act(async () => {
|
|
385
390
|
jest.runOnlyPendingTimers();
|
|
386
391
|
});
|
|
392
|
+
|
|
387
393
|
expect(
|
|
388
394
|
mock.history.post.filter(
|
|
389
395
|
(req) => req.url === API.IOT.CHIP_MANAGER.WATCH_DATA_CHIPS()
|
|
@@ -391,6 +397,11 @@ describe('test DeviceDetail', () => {
|
|
|
391
397
|
).toHaveLength(2);
|
|
392
398
|
expect(unwatchMultiDataChips).not.toHaveBeenCalled();
|
|
393
399
|
|
|
400
|
+
const instance = tree.root;
|
|
401
|
+
const valueBoxs = instance.findAllByType(QualityIndicatorItem);
|
|
402
|
+
expect(valueBoxs[0].props.value).toEqual(expect1);
|
|
403
|
+
expect(valueBoxs[1].props.value).toEqual(expect2);
|
|
404
|
+
|
|
394
405
|
await act(async () => {
|
|
395
406
|
await tree.unmount();
|
|
396
407
|
});
|
|
@@ -120,6 +120,12 @@ describe('test DeviceDetail', () => {
|
|
|
120
120
|
mock.onGet(API.CHIP.SHARED_CONFIGURATION).reply(200, []);
|
|
121
121
|
});
|
|
122
122
|
|
|
123
|
+
afterEach(() => {
|
|
124
|
+
act(() => {
|
|
125
|
+
jest.runOnlyPendingTimers();
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
123
129
|
const _receiveDataOnDeviceDetail = async (widgetConfigs, topic, message) => {
|
|
124
130
|
mock.onGet(API.CHIP.JSON_CONFIGURATION).reply(200, [gatewayData]);
|
|
125
131
|
|
|
@@ -168,6 +174,10 @@ describe('test DeviceDetail', () => {
|
|
|
168
174
|
await client.trigger('message', topic, JSON.stringify(message), 'packet');
|
|
169
175
|
});
|
|
170
176
|
|
|
177
|
+
await act(async () => {
|
|
178
|
+
jest.runOnlyPendingTimers();
|
|
179
|
+
});
|
|
180
|
+
|
|
171
181
|
const valueBox = instance.findAllByType(QualityIndicatorItem);
|
|
172
182
|
return valueBox;
|
|
173
183
|
};
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { NavigationContext } from '@react-navigation/native';
|
|
2
1
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
2
|
+
import { NavigationContext } from '@react-navigation/native';
|
|
3
3
|
import MockAdapter from 'axios-mock-adapter';
|
|
4
4
|
import moment from 'moment';
|
|
5
5
|
import mqtt from 'precompiled-mqtt/dist/mqtt.browser';
|
|
6
|
-
import React from 'react';
|
|
7
6
|
import { Alert } from 'react-native';
|
|
8
7
|
import { act, create } from 'react-test-renderer';
|
|
9
8
|
|
|
@@ -120,6 +119,12 @@ describe('test DeviceDetail', () => {
|
|
|
120
119
|
mock.onGet(API.CHIP.SHARED_CONFIGURATION).reply(200, []);
|
|
121
120
|
});
|
|
122
121
|
|
|
122
|
+
afterEach(() => {
|
|
123
|
+
act(() => {
|
|
124
|
+
jest.runOnlyPendingTimers();
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
123
128
|
const _receiveDataOnDeviceDetail = async (widgetConfigs, topic, message) => {
|
|
124
129
|
mock.onGet(API.CHIP.JSON_CONFIGURATION).reply(200, [gatewayData]);
|
|
125
130
|
|
|
@@ -168,6 +173,10 @@ describe('test DeviceDetail', () => {
|
|
|
168
173
|
await client.trigger('message', topic, JSON.stringify(message), 'packet');
|
|
169
174
|
});
|
|
170
175
|
|
|
176
|
+
await act(async () => {
|
|
177
|
+
jest.runOnlyPendingTimers();
|
|
178
|
+
});
|
|
179
|
+
|
|
171
180
|
const valueBox = instance.findAllByType(QualityIndicatorItem);
|
|
172
181
|
return valueBox;
|
|
173
182
|
};
|
|
@@ -500,6 +509,25 @@ describe('test DeviceDetail', () => {
|
|
|
500
509
|
await testModbus('00012', 0.1, '--');
|
|
501
510
|
});
|
|
502
511
|
|
|
512
|
+
it('should render device detail, modbus call updateGlobalValue, power_factor_4q_fp_pf > 1', async () => {
|
|
513
|
+
gatewayData.sensors[1].configs[1].scale = 0.1;
|
|
514
|
+
gatewayData.sensors[1].configs[1].decimal_behind = 1;
|
|
515
|
+
gatewayData.sensors[1].configs[1].value_converter = 'power_factor_4q_fp_pf';
|
|
516
|
+
await testModbus('0001000F', 0.1, 0.5);
|
|
517
|
+
});
|
|
518
|
+
it('should render device detail, modbus call updateGlobalValue, power_factor_4q_fp_pf < -1', async () => {
|
|
519
|
+
gatewayData.sensors[1].configs[1].scale = 0.1;
|
|
520
|
+
gatewayData.sensors[1].configs[1].decimal_behind = 1;
|
|
521
|
+
gatewayData.sensors[1].configs[1].value_converter = 'power_factor_4q_fp_pf';
|
|
522
|
+
await testModbus('0001FFF1', 0.1, -0.5);
|
|
523
|
+
});
|
|
524
|
+
it('should render device detail, modbus call updateGlobalValue, power_factor_4q_fp_pf in range [-1, 1]', async () => {
|
|
525
|
+
gatewayData.sensors[1].configs[1].scale = 0.1;
|
|
526
|
+
gatewayData.sensors[1].configs[1].decimal_behind = 1;
|
|
527
|
+
gatewayData.sensors[1].configs[1].value_converter = 'power_factor_4q_fp_pf';
|
|
528
|
+
await testModbus('00010005', 0.1, 0.5);
|
|
529
|
+
});
|
|
530
|
+
|
|
503
531
|
const dataConverterWrongData64 = async (transformer) => {
|
|
504
532
|
gatewayData.mqtt_server.is_wss = false;
|
|
505
533
|
gatewayData.modbus_gateway.sensors[0].configs[1].transformer = transformer;
|
|
@@ -688,11 +716,6 @@ describe('test DeviceDetail', () => {
|
|
|
688
716
|
);
|
|
689
717
|
});
|
|
690
718
|
|
|
691
|
-
const instance = tree.root;
|
|
692
|
-
const valueBoxs = instance.findAllByType(QualityIndicatorItem);
|
|
693
|
-
expect(valueBoxs[0].props.value).toEqual(expect1);
|
|
694
|
-
expect(valueBoxs[1].props.value).toEqual(expect2);
|
|
695
|
-
|
|
696
719
|
expect(
|
|
697
720
|
mock.history.post.filter(
|
|
698
721
|
(req) => req.url === API.IOT.CHIP_MANAGER.WATCH_DATA_CHIPS()
|
|
@@ -702,6 +725,7 @@ describe('test DeviceDetail', () => {
|
|
|
702
725
|
await act(async () => {
|
|
703
726
|
jest.runOnlyPendingTimers();
|
|
704
727
|
});
|
|
728
|
+
|
|
705
729
|
expect(
|
|
706
730
|
mock.history.post.filter(
|
|
707
731
|
(req) => req.url === API.IOT.CHIP_MANAGER.WATCH_DATA_CHIPS()
|
|
@@ -709,6 +733,11 @@ describe('test DeviceDetail', () => {
|
|
|
709
733
|
).toHaveLength(2);
|
|
710
734
|
expect(unwatchMultiDataChips).not.toHaveBeenCalled();
|
|
711
735
|
|
|
736
|
+
const instance = tree.root;
|
|
737
|
+
const valueBoxs = instance.findAllByType(QualityIndicatorItem);
|
|
738
|
+
expect(valueBoxs[0].props.value).toEqual(expect1);
|
|
739
|
+
expect(valueBoxs[1].props.value).toEqual(expect2);
|
|
740
|
+
|
|
712
741
|
await act(async () => {
|
|
713
742
|
await tree.unmount();
|
|
714
743
|
});
|
|
@@ -783,5 +812,5 @@ describe('test DeviceDetail', () => {
|
|
|
783
812
|
0.2,
|
|
784
813
|
'2025-09-09T12:00:00.123456Z'
|
|
785
814
|
);
|
|
786
|
-
});
|
|
815
|
+
}, 10000);
|
|
787
816
|
});
|
|
@@ -120,6 +120,12 @@ describe('test DeviceDetail', () => {
|
|
|
120
120
|
mock.onGet(API.CHIP.SHARED_CONFIGURATION).reply(200, []);
|
|
121
121
|
});
|
|
122
122
|
|
|
123
|
+
afterEach(() => {
|
|
124
|
+
act(() => {
|
|
125
|
+
jest.runOnlyPendingTimers();
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
123
129
|
const _receiveDataOnDeviceDetail = async (widgetConfigs, topic, message) => {
|
|
124
130
|
mock.onGet(API.CHIP.JSON_CONFIGURATION).reply(200, [gatewayData]);
|
|
125
131
|
|
|
@@ -168,6 +174,10 @@ describe('test DeviceDetail', () => {
|
|
|
168
174
|
await client.trigger('message', topic, JSON.stringify(message), 'packet');
|
|
169
175
|
});
|
|
170
176
|
|
|
177
|
+
await act(async () => {
|
|
178
|
+
jest.runOnlyPendingTimers();
|
|
179
|
+
});
|
|
180
|
+
|
|
171
181
|
const valueBox = instance.findAllByType(QualityIndicatorItem);
|
|
172
182
|
return valueBox;
|
|
173
183
|
};
|
|
@@ -374,11 +384,6 @@ describe('test DeviceDetail', () => {
|
|
|
374
384
|
);
|
|
375
385
|
});
|
|
376
386
|
|
|
377
|
-
const instance = tree.root;
|
|
378
|
-
const valueBoxs = instance.findAllByType(QualityIndicatorItem);
|
|
379
|
-
expect(valueBoxs[0].props.value).toEqual(expect1);
|
|
380
|
-
expect(valueBoxs[1].props.value).toEqual(expect2);
|
|
381
|
-
|
|
382
387
|
expect(
|
|
383
388
|
mock.history.post.filter(
|
|
384
389
|
(req) => req.url === API.IOT.CHIP_MANAGER.WATCH_DATA_CHIPS()
|
|
@@ -388,6 +393,7 @@ describe('test DeviceDetail', () => {
|
|
|
388
393
|
await act(async () => {
|
|
389
394
|
jest.runOnlyPendingTimers();
|
|
390
395
|
});
|
|
396
|
+
|
|
391
397
|
expect(
|
|
392
398
|
mock.history.post.filter(
|
|
393
399
|
(req) => req.url === API.IOT.CHIP_MANAGER.WATCH_DATA_CHIPS()
|
|
@@ -395,6 +401,11 @@ describe('test DeviceDetail', () => {
|
|
|
395
401
|
).toHaveLength(2);
|
|
396
402
|
expect(unwatchMultiDataChips).not.toHaveBeenCalled();
|
|
397
403
|
|
|
404
|
+
const instance = tree.root;
|
|
405
|
+
const valueBoxs = instance.findAllByType(QualityIndicatorItem);
|
|
406
|
+
expect(valueBoxs[0].props.value).toEqual(expect1);
|
|
407
|
+
expect(valueBoxs[1].props.value).toEqual(expect2);
|
|
408
|
+
|
|
398
409
|
await act(async () => {
|
|
399
410
|
await tree.unmount();
|
|
400
411
|
});
|
|
@@ -117,6 +117,12 @@ describe('test DeviceDetail', () => {
|
|
|
117
117
|
mock.onGet(API.CHIP.SHARED_CONFIGURATION).reply(200, []);
|
|
118
118
|
});
|
|
119
119
|
|
|
120
|
+
afterEach(() => {
|
|
121
|
+
act(() => {
|
|
122
|
+
jest.runOnlyPendingTimers();
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
120
126
|
it('should render device detail, connect will call subscribe', async () => {
|
|
121
127
|
mock.onGet(API.CHIP.JSON_CONFIGURATION).reply(200, [gatewayData]);
|
|
122
128
|
const client = mqtt.connect();
|
|
@@ -328,6 +334,10 @@ describe('test DeviceDetail', () => {
|
|
|
328
334
|
await client.trigger('message', topic, JSON.stringify(message), 'packet');
|
|
329
335
|
});
|
|
330
336
|
|
|
337
|
+
await act(async () => {
|
|
338
|
+
jest.runOnlyPendingTimers();
|
|
339
|
+
});
|
|
340
|
+
|
|
331
341
|
const valueBox = instance.findAllByType(QualityIndicatorItem);
|
|
332
342
|
expect(valueBox.length).toBe(widgetConfigs.length);
|
|
333
343
|
return valueBox;
|
|
@@ -442,12 +452,6 @@ describe('test DeviceDetail', () => {
|
|
|
442
452
|
);
|
|
443
453
|
});
|
|
444
454
|
|
|
445
|
-
const instance = tree.root;
|
|
446
|
-
const valueBoxs = instance.findAllByType(QualityIndicatorItem);
|
|
447
|
-
for (let i = 0; i < widgetConfigs.length; i++) {
|
|
448
|
-
expect(valueBoxs[i].props.value).toEqual(expects[i]);
|
|
449
|
-
}
|
|
450
|
-
|
|
451
455
|
expect(
|
|
452
456
|
mock.history.post.filter(
|
|
453
457
|
(req) => req.url === API.IOT.CHIP_MANAGER.WATCH_DATA_CHIPS()
|
|
@@ -457,6 +461,7 @@ describe('test DeviceDetail', () => {
|
|
|
457
461
|
await act(async () => {
|
|
458
462
|
jest.runOnlyPendingTimers();
|
|
459
463
|
});
|
|
464
|
+
|
|
460
465
|
expect(
|
|
461
466
|
mock.history.post.filter(
|
|
462
467
|
(req) => req.url === API.IOT.CHIP_MANAGER.WATCH_DATA_CHIPS()
|
|
@@ -464,6 +469,12 @@ describe('test DeviceDetail', () => {
|
|
|
464
469
|
).toHaveLength(2);
|
|
465
470
|
expect(unwatchMultiDataChips).not.toHaveBeenCalled();
|
|
466
471
|
|
|
472
|
+
const instance = tree.root;
|
|
473
|
+
const valueBoxs = instance.findAllByType(QualityIndicatorItem);
|
|
474
|
+
for (let i = 0; i < widgetConfigs.length; i++) {
|
|
475
|
+
expect(valueBoxs[i].props.value).toEqual(expects[i]);
|
|
476
|
+
}
|
|
477
|
+
|
|
467
478
|
await act(async () => {
|
|
468
479
|
await tree.unmount();
|
|
469
480
|
});
|