@eohjsc/react-native-smart-city 0.3.91 → 0.3.93

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 (237) hide show
  1. package/package.json +5 -1
  2. package/src/Images/Common/reorder.svg +3 -0
  3. package/src/commons/ActionGroup/OnOffSmartLock/AutoLock/AutoLockStyles.js +1 -1
  4. package/src/commons/ActionGroup/OnOffSmartLock/AutoLock/__test__/index.test.js +3 -1
  5. package/src/commons/ActionGroup/OnOffSmartLock/AutoLock/index.js +3 -3
  6. package/src/commons/ActionGroup/OnOffSmartLock/PasscodeList/__test__/index.test.js +3 -10
  7. package/src/commons/ActionGroup/OnOffSmartLock/PasscodeList/index.js +1 -0
  8. package/src/commons/ActionGroup/OnOffSmartLock/SetupGeneratePasscode/SetupGeneratePasscodeStyles.js +1 -1
  9. package/src/commons/ActionGroup/OnOffTemplate/SwitchButtonTemplate.js +13 -5
  10. package/src/commons/ActionGroup/SliderRangeTemplate.js +100 -69
  11. package/src/commons/ActionGroup/SliderRangeTemplateStyles.js +27 -27
  12. package/src/commons/ActionGroup/StatesGridActionTemplate.js +4 -1
  13. package/src/commons/ActionGroup/__test__/OnOffTemplate.test.js +4 -1
  14. package/src/commons/ActionGroup/__test__/SliderRangeTemplate.test.js +56 -0
  15. package/src/commons/ActionGroup/__test__/StatesGridActionTemplate.test.js +2 -2
  16. package/src/commons/ActionGroup/__test__/SwitchButtonTemplate.test.js +45 -8
  17. package/src/commons/ActionGroup/__test__/index.test.js +0 -19
  18. package/src/commons/ActionGroup/index.js +0 -3
  19. package/src/commons/ActionTemplate/CurtainAction.js +3 -3
  20. package/src/commons/ActionTemplate/CurtainActionStyles.js +1 -1
  21. package/src/commons/ActionTemplate/OnOffButtonAction.js +2 -2
  22. package/src/commons/ActionTemplate/OnOffButtonActionStyles.js +1 -1
  23. package/src/commons/ActionTemplate/OnOffSimpleAction.js +2 -2
  24. package/src/commons/ActionTemplate/OnOffSimpleActionStyles.js +1 -1
  25. package/src/commons/ActionTemplate/OnOffSmartLockAction.js +2 -2
  26. package/src/commons/ActionTemplate/OnOffSmartLockActionStyles.js +1 -1
  27. package/src/commons/ActionTemplate/OneButtonAction.js +1 -1
  28. package/src/commons/ActionTemplate/OneButtonActionStyles.js +1 -1
  29. package/src/commons/ActionTemplate/ThreeButtonAction.js +3 -3
  30. package/src/commons/ActionTemplate/ThreeButtonActionStyles.js +1 -1
  31. package/src/commons/AlertAction/index.js +5 -0
  32. package/src/commons/Auth/AccountList.js +1 -1
  33. package/src/commons/Auth/__test__/OtpInputList.test.js +13 -17
  34. package/src/commons/Automate/ItemAutomate.js +10 -4
  35. package/src/commons/Automate/__test__/ItemAutomate.test.js +11 -11
  36. package/src/commons/BottomButtonView/index.js +22 -4
  37. package/src/commons/Button/index.js +5 -0
  38. package/src/commons/Device/ConnectedViewHeader.js +0 -1
  39. package/src/commons/Device/DeviceAlertStatus.js +2 -1
  40. package/src/commons/Device/Emergency/EmergencyDetail.js +4 -2
  41. package/src/commons/Device/Emergency/__test__/EmergencyDetail.test.js +4 -2
  42. package/src/commons/Device/ProgressBar/index.js +7 -11
  43. package/src/commons/Device/ProgressBar/styles.js +9 -4
  44. package/src/commons/Device/WindSpeed/Anemometer/index.js +3 -1
  45. package/src/commons/Device/WindSpeed/LinearChart/__test__/LinearChart.test.js +14 -1
  46. package/src/commons/Device/WindSpeed/LinearChart/index.js +4 -2
  47. package/src/commons/FlatListDnD/__test__/index.test.js +49 -0
  48. package/src/commons/FlatListDnD/index.js +37 -0
  49. package/src/commons/FlatListDnD/styles.js +12 -0
  50. package/src/commons/Form/__test__/TextInput.test.js +1 -1
  51. package/src/commons/Header/HeaderCustom.js +10 -19
  52. package/src/commons/HorizontalPicker/index.js +65 -38
  53. package/src/commons/IconComponent/index.js +3 -2
  54. package/src/commons/MediaPlayer/__test__/index.test.js +8 -3
  55. package/src/commons/MediaPlayer/index.js +11 -7
  56. package/src/commons/MenuActionMore/index.js +6 -4
  57. package/src/commons/Modal/ModalBottom.js +2 -3
  58. package/src/commons/Modal/ModalCustom.js +2 -3
  59. package/src/commons/NavBar/index.js +48 -50
  60. package/src/commons/OneTapTemplate/NumberUpDownActionTemplate.js +1 -1
  61. package/src/commons/OneTapTemplate/NumberUpDownActionTemplateStyles.js +1 -1
  62. package/src/commons/OneTapTemplate/OptionsDropdownActionTemplate.js +1 -1
  63. package/src/commons/OneTapTemplate/OptionsDropdownActionTemplateStyles.js +1 -1
  64. package/src/commons/OneTapTemplate/StatesGridActionTemplate.js +1 -1
  65. package/src/commons/OneTapTemplate/StatesGridActionTemplateStyles.js +1 -1
  66. package/src/commons/PreventAccess/index.js +1 -1
  67. package/src/commons/Sharing/StationDevicePermissions.js +4 -4
  68. package/src/commons/Sharing/WrapHeaderScrollable.js +5 -5
  69. package/src/commons/Sharing/__test__/DevicePermissionsCheckbox.test.js +2 -2
  70. package/src/commons/SubUnit/OneTap/ItemOneTap.js +12 -59
  71. package/src/commons/SubUnit/OneTap/__test__/SubUnitAutomate.test.js +16 -20
  72. package/src/commons/SubUnit/OneTap/index.js +20 -7
  73. package/src/commons/UnitSummary/AirQuality/__test__/index.test.js +4 -0
  74. package/src/commons/UnitSummary/ConfigHistoryChart/__test__/ConfigHistoryChart.test.js +1 -1
  75. package/src/commons/ViewButtonBottom/index.js +32 -4
  76. package/src/configs/API.js +9 -0
  77. package/src/configs/AccessibilityLabel.js +2 -0
  78. package/src/configs/BLE.js +1 -0
  79. package/src/configs/Colors.js +1 -1
  80. package/src/configs/Constants.js +12 -18
  81. package/src/context/actionType.ts +2 -1
  82. package/src/context/mockStore.ts +1 -0
  83. package/src/context/reducer.ts +12 -1
  84. package/src/hooks/Common/__test__/useStatusbar.test.js +5 -5
  85. package/src/hooks/Common/index.js +0 -2
  86. package/src/hooks/Common/useKeyboardShow.js +4 -4
  87. package/src/hooks/Common/useStatusBar.js +2 -2
  88. package/src/hooks/Common/useTitleHeader.js +5 -7
  89. package/src/hooks/Explore/useKeyboardAnimated.js +10 -4
  90. package/src/hooks/IoT/__test__/useRemoteControl.test.js +11 -0
  91. package/src/hooks/IoT/useBluetoothConnection.js +20 -29
  92. package/src/hooks/index.js +1 -2
  93. package/src/hooks/useMqtt.js +95 -0
  94. package/src/iot/Monitor.js +2 -1
  95. package/src/iot/RemoteControl/Bluetooth.js +56 -19
  96. package/src/iot/RemoteControl/__test__/Bluetooth.test.js +140 -0
  97. package/src/iot/mqtt.js +233 -0
  98. package/src/navigations/UnitStack.js +44 -12
  99. package/src/screens/AddLocationMaps/index.js +18 -16
  100. package/src/screens/AddLocationMaps/indexStyle.js +3 -0
  101. package/src/screens/AddNewGateway/SelectDeviceSubUnit.js +1 -2
  102. package/src/screens/AddNewGateway/__test__/AddNewGateway.test.js +5 -17
  103. package/src/screens/AddNewGateway/__test__/SelectDeviceSubUnit.test.js +5 -13
  104. package/src/screens/AddNewGateway/__test__/SelectDeviceUnit.test.js +9 -11
  105. package/src/screens/AddNewGateway/__test__/SelectModbusGateway.test.js +6 -14
  106. package/src/screens/AddNewGateway/__test__/SelectZigbeeGateway.test.js +6 -14
  107. package/src/screens/AddNewGateway/hooks/__Tests__/useWifiManage.test.js +3 -2
  108. package/src/screens/AddNewGateway/index.js +1 -1
  109. package/src/screens/AllCamera/index.js +2 -3
  110. package/src/screens/AllGateway/DetailConfigActionZigbee/__test__/index.test.js +0 -18
  111. package/src/screens/AllGateway/DetailConfigActionZigbee/index.js +1 -1
  112. package/src/screens/AllGateway/DeviceModbusDetail/__test__/index.test.js +5 -2
  113. package/src/screens/AllGateway/hooks/__test__/index.test.js +1 -1
  114. package/src/screens/{AddNewAction → Automate/AddNewAction}/ChooseAction.js +78 -119
  115. package/src/screens/{AddNewAction → Automate/AddNewAction}/ChooseConfig.js +45 -73
  116. package/src/screens/{AddNewAction → Automate/AddNewAction}/Components/LoadingSelectAction.js +1 -1
  117. package/src/screens/{AddNewAction → Automate/AddNewAction}/Components/SelectDevices.js +3 -3
  118. package/src/screens/{AddNewAction → Automate/AddNewAction}/Device/DeviceStyles.js +5 -1
  119. package/src/screens/{AddNewAction → Automate/AddNewAction}/Device/__test__/index.test.js +3 -3
  120. package/src/screens/{AddNewAction → Automate/AddNewAction}/Device/index.js +5 -4
  121. package/src/screens/{AddNewAction → Automate/AddNewAction}/NewActionWrapper.js +5 -7
  122. package/src/screens/{AddNewAction → Automate/AddNewAction}/SelectControlDevices.js +11 -49
  123. package/src/screens/{AddNewAction → Automate/AddNewAction}/SelectMonitorDevices.js +10 -42
  124. package/src/screens/{AddNewAction → Automate/AddNewAction}/SetupConfigCondition.js +52 -101
  125. package/src/screens/{AddNewAction → Automate/AddNewAction}/Styles/SelectActionStyles.js +1 -1
  126. package/src/screens/{AddNewAction → Automate/AddNewAction}/Styles/SelectSensorDevicesStyles.js +1 -1
  127. package/src/screens/{AddNewAction → Automate/AddNewAction}/Styles/SetupSensorStyles.js +4 -2
  128. package/src/screens/{AddNewAction → Automate/AddNewAction}/__test__/ChooseAction.test.js +10 -11
  129. package/src/screens/{AddNewAction → Automate/AddNewAction}/__test__/ChooseConfig.test.js +26 -27
  130. package/src/screens/{AddNewAction → Automate/AddNewAction}/__test__/SelectControlDevices.test.js +9 -9
  131. package/src/screens/{AddNewAction → Automate/AddNewAction}/__test__/SelectMonitorDevices.test.js +5 -5
  132. package/src/screens/{AddNewAction → Automate/AddNewAction}/__test__/SetupSensor.test.js +52 -16
  133. package/src/screens/Automate/AddNewAutoSmart/AddAutomationTypeSmart.js +25 -0
  134. package/src/screens/Automate/AddNewAutoSmart/AddTypeSmart.js +78 -0
  135. package/src/screens/Automate/AddNewAutoSmart/AddUnknownTypeSmart.js +29 -0
  136. package/src/screens/{AddNewAutoSmart → Automate/AddNewAutoSmart}/__test__/AddNewAutoSmart.test.js +18 -41
  137. package/src/screens/{AddNewAutoSmart → Automate/AddNewAutoSmart}/styles/AddNewAutoSmartStyles.js +1 -1
  138. package/src/screens/Automate/Components/InputName.js +64 -0
  139. package/src/screens/{AddNewOneTap/AddNewOneTapStyles.js → Automate/Components/InputNameStyles.js} +3 -3
  140. package/src/screens/{EditActionsList → Automate/EditActionsList}/Styles/indexStyles.js +5 -1
  141. package/src/screens/{EditActionsList → Automate/EditActionsList}/__tests__/index.test.js +17 -31
  142. package/src/screens/{EditActionsList → Automate/EditActionsList}/index.js +49 -51
  143. package/src/screens/Automate/MultiUnits.js +69 -67
  144. package/src/screens/Automate/OneTap/__test__/AddNewOneTap.test.js +134 -0
  145. package/src/screens/Automate/OneTap/index.js +16 -0
  146. package/src/screens/Automate/Scenario/ScenarioName.js +15 -0
  147. package/src/screens/{AddNewOneTap → Automate/Scenario}/__test__/AddNewOneTap.test.js +27 -45
  148. package/src/screens/Automate/ScriptDetail/Components/DeleteScript.js +45 -0
  149. package/src/screens/Automate/ScriptDetail/Components/RenameScript.js +58 -0
  150. package/src/screens/{ScriptDetail → Automate/ScriptDetail}/Styles/indexStyles.js +1 -1
  151. package/src/screens/{ScriptDetail → Automate/ScriptDetail}/__test__/index.test.js +110 -74
  152. package/src/screens/{ScriptDetail → Automate/ScriptDetail}/__test__/useStarredScript.test.js +7 -6
  153. package/src/screens/{ScriptDetail → Automate/ScriptDetail}/hooks/useStarredScript.js +4 -4
  154. package/src/screens/Automate/ScriptDetail/index.js +360 -0
  155. package/src/screens/{ScriptDetail → Automate/ScriptDetail}/utils.js +32 -31
  156. package/src/screens/{SetSchedule → Automate/SetSchedule}/__test__/SelectWeekday.test.js +2 -2
  157. package/src/screens/{SetSchedule → Automate/SetSchedule}/__test__/index.test.js +21 -46
  158. package/src/screens/{SetSchedule → Automate/SetSchedule}/components/RepeatOptionsPopup.js +4 -4
  159. package/src/screens/{SetSchedule → Automate/SetSchedule}/components/RowItem.js +2 -2
  160. package/src/screens/{SetSchedule → Automate/SetSchedule}/components/SelectWeekday.js +3 -3
  161. package/src/screens/Automate/SetSchedule/index.js +140 -0
  162. package/src/screens/{SetSchedule → Automate/SetSchedule}/styles/RepeatOptionsPopupStyles.js +1 -1
  163. package/src/screens/{SetSchedule → Automate/SetSchedule}/styles/RowItemStyles.js +1 -1
  164. package/src/screens/{SetSchedule → Automate/SetSchedule}/styles/SelectWeekdayStyles.js +1 -1
  165. package/src/screens/{SetSchedule → Automate/SetSchedule}/styles/indexStyles.js +1 -1
  166. package/src/screens/Automate/ValueChange/ValueChangeName.js +16 -0
  167. package/src/screens/Automate/__test__/MultiUnits.test.js +77 -121
  168. package/src/screens/Automate/__test__/index.test.js +3 -10
  169. package/src/screens/Automate/constants.js +0 -0
  170. package/src/screens/Automate/index.js +12 -23
  171. package/src/screens/ChangePosition/__test__/index.test.js +75 -0
  172. package/src/screens/ChangePosition/index.js +112 -0
  173. package/src/screens/ChangePosition/styles.js +87 -0
  174. package/src/screens/Device/__test__/detail.test.js +203 -258
  175. package/src/screens/Device/__test__/mqttDetail.test.js +599 -0
  176. package/src/screens/Device/__test__/sensorDisplayItem.test.js +4 -0
  177. package/src/screens/Device/components/SensorDisplayItem.js +3 -8
  178. package/src/screens/Device/components/VisualChart.js +55 -8
  179. package/src/screens/Device/detail.js +78 -30
  180. package/src/screens/Device/hooks/__test__/useEmergencyButton.test.js +35 -13
  181. package/src/screens/Device/hooks/useDeviceWatchConfigControl.js +13 -3
  182. package/src/screens/Device/hooks/useEvaluateValue.js +20 -2
  183. package/src/screens/Device/styles.js +7 -0
  184. package/src/screens/GuestInfo/components/__test__/AccessScheduleSheet.test.js +52 -0
  185. package/src/screens/MoveToAnotherSubUnit/__test__/index.test.js +18 -13
  186. package/src/screens/Notification/__test__/Notification.test.js +1 -1
  187. package/src/screens/PlayBackCamera/index.js +2 -3
  188. package/src/screens/SelectUnit/__test__/index.test.js +8 -13
  189. package/src/screens/SharedUnit/index.js +5 -4
  190. package/src/screens/Sharing/SelectUser.js +2 -2
  191. package/src/screens/Sharing/__test__/MemberList.test.js +9 -15
  192. package/src/screens/Sharing/__test__/MemberList2.test.js +10 -16
  193. package/src/screens/Sharing/__test__/SelectUser.test.js +8 -4
  194. package/src/screens/SideMenuDetail/SideMenuDetailStyles.js +1 -1
  195. package/src/screens/SmartAccount/__test__/SmartAccount.test.js +8 -4
  196. package/src/screens/SmartAccount/index.js +9 -9
  197. package/src/screens/SmartAccount/style.js +8 -7
  198. package/src/screens/SubUnit/ManageSubUnit.js +4 -4
  199. package/src/screens/SubUnit/__test__/ManageSubUnit.test.js +9 -28
  200. package/src/screens/TDSGuide/index.js +1 -1
  201. package/src/screens/Template/GatewayList.js +4 -1
  202. package/src/screens/Template/__test__/detail.test.js +14 -20
  203. package/src/screens/Template/detail.js +1 -0
  204. package/src/screens/UVIndexGuide/index.js +2 -2
  205. package/src/screens/Unit/Detail.js +10 -24
  206. package/src/screens/Unit/SelectAddToFavorites.js +1 -1
  207. package/src/screens/Unit/Summaries.js +6 -17
  208. package/src/screens/Unit/__test__/ChooseLocation.test.js +8 -13
  209. package/src/screens/Unit/__test__/Detail.test.js +3 -1
  210. package/src/screens/Unit/__test__/SelectAddToFavorites.test.js +1 -1
  211. package/src/screens/Unit/__test__/SmartAccount.test.js +8 -14
  212. package/src/screens/Unit/__test__/Summaries.test.js +2 -2
  213. package/src/screens/UnitSummary/components/UvIndex/__test__/index.test.js +4 -0
  214. package/src/screens/UnitSummary/components/WaterQuality/__test__/index.test.js +6 -11
  215. package/src/screens/WaterQualityGuide/index.js +10 -5
  216. package/src/utils/FactoryGateway.js +525 -0
  217. package/src/utils/I18n/translations/en.json +28 -19
  218. package/src/utils/I18n/translations/vi.json +26 -20
  219. package/src/utils/Route/index.js +5 -1
  220. package/src/utils/Utils.js +40 -0
  221. package/src/utils/__test__/Utils.test.js +6 -0
  222. package/src/commons/ActionGroup/CurtainButtonTemplate.js +0 -130
  223. package/src/commons/ActionGroup/__test__/CurtainButtonTemplate.test.js +0 -109
  224. package/src/commons/Auth/SocialButton.js +0 -54
  225. package/src/commons/Auth/__test__/SocialButton.test.js +0 -46
  226. package/src/commons/Device/SensorConnectedStatus.js +0 -56
  227. package/src/commons/Device/__test__/SensorConnectedStatus.test.js +0 -29
  228. package/src/commons/Sharing/__test__/StationDevicePermission.test.js +0 -85
  229. package/src/hooks/__test__/useInitDeepLink.test.js +0 -28
  230. package/src/hooks/useInitDeepLink.js +0 -25
  231. package/src/screens/AddNewAutoSmart/index.js +0 -149
  232. package/src/screens/AddNewOneTap/index.js +0 -156
  233. package/src/screens/ScriptDetail/hooks/index.js +0 -136
  234. package/src/screens/ScriptDetail/index.js +0 -446
  235. package/src/screens/SetSchedule/index.js +0 -200
  236. /package/src/screens/{AddNewAction → Automate/AddNewAction}/Components/index.js +0 -0
  237. /package/src/screens/{AddNewAction → Automate/AddNewAction}/__test__/LoadingSelectAction.test.js +0 -0
@@ -1,4 +1,6 @@
1
1
  import { BleManager } from 'react-native-ble-plx';
2
+ import { getTranslate } from '../../../utils/I18n';
3
+ import { ToastBottomHelper } from '../../../utils/Utils';
2
4
  import '../Bluetooth';
3
5
  import {
4
6
  scanBluetoothDevices,
@@ -7,10 +9,18 @@ import {
7
9
  clearFoundDevices,
8
10
  } from '../Bluetooth';
9
11
 
12
+ jest.mock('react-native-crypto-aes-cbc', () => ({
13
+ ...jest.requireActual('react-native-crypto-aes-cbc'),
14
+ encryptInBase64: jest.fn().mockReturnValue('af9534b8'),
15
+ }));
16
+
10
17
  const bleManager = new BleManager();
11
18
 
12
19
  const mockOnDeviceFound = jest.fn();
13
20
 
21
+ const spyToastSuccess = jest.spyOn(ToastBottomHelper, 'success');
22
+ const spyToastError = jest.spyOn(ToastBottomHelper, 'error');
23
+
14
24
  describe('Test IOT Bluetooth', () => {
15
25
  beforeEach(() => {
16
26
  mockOnDeviceFound.mockClear();
@@ -23,11 +33,14 @@ describe('Test IOT Bluetooth', () => {
23
33
  afterEach(() => {
24
34
  clearFoundDevices();
25
35
  clearNeedToScanDevices();
36
+ spyToastSuccess.mockClear();
37
+ spyToastError.mockClear();
26
38
  });
27
39
 
28
40
  it('Send command over bluetooth via device success', async () => {
29
41
  const device = {
30
42
  name: '1234567',
43
+ password: 'aWZux%Z7EN9J-}ah',
31
44
  cancelConnection: jest.fn(),
32
45
  connect: async () => ({
33
46
  discoverAllServicesAndCharacteristics: async () => ({
@@ -43,16 +56,143 @@ describe('Test IOT Bluetooth', () => {
43
56
  );
44
57
  await scanBluetoothDevices([device.name], mockOnDeviceFound);
45
58
 
59
+ const result = await sendCommandOverBluetooth(
60
+ {
61
+ remote_control_options: {
62
+ bluetooth: {
63
+ address: device.name,
64
+ },
65
+ },
66
+ },
67
+ {}
68
+ );
69
+ expect(result).toBeTruthy();
70
+ });
71
+
72
+ it('Send command over bluetooth via device with secret key successfully', async () => {
73
+ const device = {
74
+ name: '1234567',
75
+ cancelConnection: jest.fn(),
76
+ connect: async () => ({
77
+ discoverAllServicesAndCharacteristics: async () => ({
78
+ writeCharacteristicWithResponseForService: async () => ({}),
79
+ monitorCharacteristicForService: async (_, __, fn) => {
80
+ fn(null, { value: 'T0s=' }); // T0s= is OK
81
+ },
82
+ }),
83
+ }),
84
+ readCharacteristicForService: jest
85
+ .fn()
86
+ .mockResolvedValue({ value: 'KaLAVw==' }),
87
+ };
88
+ bleManager.startDeviceScan.mockImplementation(
89
+ (uuids, options, listener) => {
90
+ listener(null, device);
91
+ }
92
+ );
93
+ await scanBluetoothDevices([device.name], mockOnDeviceFound);
94
+
46
95
  await sendCommandOverBluetooth(
47
96
  {
48
97
  remote_control_options: {
49
98
  bluetooth: {
50
99
  address: device.name,
100
+ password: 'aWZux%Z7EN9J-}ah',
101
+ user: 1,
102
+ is_use_secret_key: true,
51
103
  },
52
104
  },
53
105
  },
54
106
  {}
55
107
  );
108
+ expect(spyToastSuccess).toBeCalledWith(
109
+ getTranslate('en', 'control_device_via_bluetooth_successfully')
110
+ );
111
+ });
112
+
113
+ it('Send command over bluetooth via device with secret key failure', async () => {
114
+ const device = {
115
+ name: '1234567',
116
+ cancelConnection: jest.fn(),
117
+ connect: async () => ({
118
+ discoverAllServicesAndCharacteristics: async () => ({
119
+ writeCharacteristicWithResponseForService: async () => ({}),
120
+ monitorCharacteristicForService: async (_, __, fn) => {
121
+ fn({ message: 'FAILED' });
122
+ },
123
+ }),
124
+ cancelConnection: jest.fn(),
125
+ }),
126
+ readCharacteristicForService: jest
127
+ .fn()
128
+ .mockResolvedValue({ value: 'KaLAVw==' }),
129
+ };
130
+ bleManager.startDeviceScan.mockImplementation(
131
+ (uuids, options, listener) => {
132
+ listener(null, device);
133
+ }
134
+ );
135
+ await scanBluetoothDevices([device.name], mockOnDeviceFound);
136
+
137
+ await sendCommandOverBluetooth(
138
+ {
139
+ remote_control_options: {
140
+ bluetooth: {
141
+ address: device.name,
142
+ password: null,
143
+ user: 1,
144
+ is_use_secret_key: true,
145
+ },
146
+ },
147
+ },
148
+ {}
149
+ );
150
+ expect(spyToastError).toBeCalledWith(
151
+ getTranslate('en', 'command_is_fail_to_send_via_bluetooth')
152
+ );
153
+ });
154
+
155
+ it('Send command over bluetooth via device with secret key failure because chip does not response', async () => {
156
+ jest.useFakeTimers();
157
+ const device = {
158
+ name: '1234567',
159
+ cancelConnection: jest.fn(),
160
+ connect: async () => ({
161
+ discoverAllServicesAndCharacteristics: async () => ({
162
+ writeCharacteristicWithResponseForService: async () => ({}),
163
+ monitorCharacteristicForService: async (_, __, fn) => {},
164
+ }),
165
+ cancelConnection: jest.fn(),
166
+ }),
167
+ readCharacteristicForService: jest
168
+ .fn()
169
+ .mockResolvedValue({ value: 'KaLAVw==' }),
170
+ };
171
+
172
+ bleManager.startDeviceScan.mockImplementation(
173
+ (uuids, options, listener) => {
174
+ listener(null, device);
175
+ }
176
+ );
177
+ await scanBluetoothDevices([device.name], mockOnDeviceFound);
178
+
179
+ await sendCommandOverBluetooth(
180
+ {
181
+ remote_control_options: {
182
+ bluetooth: {
183
+ address: device.name,
184
+ password: 'aWZux%Z7EN9J-}ah',
185
+ user: 1,
186
+ is_use_secret_key: true,
187
+ },
188
+ },
189
+ },
190
+ {}
191
+ );
192
+ jest.runAllTimers();
193
+ expect(spyToastError).toBeCalledWith(
194
+ getTranslate('en', 'command_is_fail_to_send_via_bluetooth')
195
+ );
56
196
  });
57
197
 
58
198
  test('Scan bluetooth device will init hardware scan', async () => {
@@ -0,0 +1,233 @@
1
+ import { updateGlobalValue } from './Monitor';
2
+ import { Buffer } from 'buffer';
3
+
4
+ const int_all = (bytes_str, config_data = null) => {
5
+ let val;
6
+ val = Number.parseInt(bytes_str, 16);
7
+
8
+ if (val > 32767) {
9
+ val = val - 65536;
10
+ }
11
+
12
+ return val;
13
+ };
14
+
15
+ const int_first4 = (bytes_str, config_data = null) => {
16
+ return Number.parseInt(bytes_str.slice(0, 4), 16);
17
+ };
18
+
19
+ const int_last4 = (bytes_str, config_data = null) => {
20
+ return Number.parseInt(bytes_str.slice(4), 16);
21
+ };
22
+
23
+ const uint_32 = (bytes_str, config_data = null) => {
24
+ let bits = 32;
25
+ let value = Number.parseInt(bytes_str, 16);
26
+
27
+ if (value & (1 << (bits - 1))) {
28
+ value -= 1 << bits;
29
+ }
30
+
31
+ return value;
32
+ };
33
+
34
+ const float_convert = (bytes_str) => {
35
+ const struct = require('python-struct');
36
+ let value = null;
37
+ try {
38
+ value = struct.unpack('>f', Buffer.from(bytes_str, 'hex'))[0];
39
+ // eslint-disable-next-line no-empty
40
+ } catch {}
41
+ return value;
42
+ };
43
+
44
+ const float_cdba = (bytes_str, config_data = null) => {
45
+ const bytes_cdba = bytes_str?.slice(4) + bytes_str?.slice(0, 4);
46
+ return float_convert(bytes_cdba);
47
+ };
48
+
49
+ const float_abcd = (bytes_str, config_data = null) => {
50
+ return float_convert(bytes_str);
51
+ };
52
+
53
+ const range_value_converting = (
54
+ raw_value,
55
+ raw_min,
56
+ raw_max,
57
+ value_min,
58
+ value_max
59
+ ) => {
60
+ const rawValue = parseInt(raw_value, 16);
61
+ const meaning_range = value_max - value_min;
62
+ const value_range = raw_max - raw_min;
63
+ if (!value_range) {
64
+ return null;
65
+ }
66
+
67
+ const value = rawValue - raw_min;
68
+ const meaning_value = (value * meaning_range) / value_range;
69
+ return meaning_value + value_min;
70
+ };
71
+
72
+ const convert_ai = (bytes_str, config_data = null) => {
73
+ return range_value_converting(
74
+ bytes_str,
75
+ config_data?.ai_trans_min_raw_in,
76
+ config_data?.ai_trans_max_raw_in,
77
+ config_data?.ai_trans_min_value,
78
+ config_data?.ai_trans_max_value
79
+ );
80
+ };
81
+
82
+ const mappingTransformer = {
83
+ int_all: int_all,
84
+ int_first4: int_first4,
85
+ int_last4: int_last4,
86
+ uint_32: uint_32,
87
+ float_cdba: float_cdba,
88
+ float_abcd: float_abcd,
89
+ convert_ai: convert_ai,
90
+ };
91
+
92
+ const extract_config_value = (register, value_bytes) => {
93
+ const transformer = mappingTransformer[register?.transformer];
94
+ if (!transformer) {
95
+ return null;
96
+ }
97
+
98
+ return transformer(value_bytes, register);
99
+ };
100
+
101
+ const get_modbus_length = (config) => {
102
+ const len = config?.len;
103
+ if ([1, 2].includes(config?.func)) {
104
+ return len * 2;
105
+ }
106
+ return len * 4;
107
+ };
108
+
109
+ const get_config_value = (register, data) => {
110
+ const size = get_modbus_length(register);
111
+ const value_bytes = data?.slice(0, size);
112
+
113
+ const value = extract_config_value(register, value_bytes);
114
+ if (value === undefined || value === null) {
115
+ return { value: null, data: null };
116
+ }
117
+
118
+ return { value, data: data.slice(size) };
119
+ };
120
+
121
+ const get_sensor_size = (sensor) => {
122
+ let size = 0;
123
+ (sensor?.configs || []).forEach((config) => {
124
+ size += get_modbus_length(config);
125
+ });
126
+ return size;
127
+ };
128
+
129
+ const get_sensor_data = (sensor, data) => {
130
+ const size = get_sensor_size(sensor);
131
+ return { sensor_data: data.slice(0, size), data: data.slice(size) };
132
+ };
133
+
134
+ const get_scale_value = (value, config) => {
135
+ value = value && value * (config?.scale || 1);
136
+ value =
137
+ config?.decimal_behind || config?.decimal_behind === 0
138
+ ? value.toFixed(config?.decimal_behind)
139
+ : value;
140
+ return value;
141
+ };
142
+
143
+ const updateGlobalValueMqtt = (config, value) => {
144
+ if (!config?.id) {
145
+ return;
146
+ }
147
+ if (value === undefined || value === null) {
148
+ return;
149
+ }
150
+
151
+ value = get_scale_value(value, config);
152
+ updateGlobalValue(config.id, { value: Number(value) });
153
+ };
154
+
155
+ export const handleModbusData = (chip, configById, data) => {
156
+ const modbus_gateway = chip?.modbus_gateway;
157
+ if (!modbus_gateway) {
158
+ return;
159
+ }
160
+
161
+ (modbus_gateway?.sensors || []).forEach((device) => {
162
+ let { sensor_data, data: new_data } = get_sensor_data(device, data);
163
+ data = new_data;
164
+
165
+ (device?.configs || []).forEach((register) => {
166
+ let { value, data: new_sensor_data } = get_config_value(
167
+ register,
168
+ sensor_data
169
+ );
170
+ sensor_data = new_sensor_data;
171
+
172
+ const configId = register?.config;
173
+ updateGlobalValueMqtt(configById[configId], value);
174
+ });
175
+ });
176
+ };
177
+
178
+ export const handleChipData = (configById, configId, data) => {
179
+ updateGlobalValueMqtt(configById[configId], Number(data?.v));
180
+ };
181
+
182
+ export const handleZigbeeData = (chip, configById, ieee_address, data) => {
183
+ const zigbee_gateway = chip?.zigbee_gateway;
184
+ if (!zigbee_gateway) {
185
+ return;
186
+ }
187
+
188
+ const zigbee_device_by_ieee = {};
189
+
190
+ (zigbee_gateway?.sensors || []).forEach((device) => {
191
+ zigbee_device_by_ieee[device.ieee_address] = device;
192
+ });
193
+
194
+ const device = zigbee_device_by_ieee[ieee_address];
195
+ if (device) {
196
+ (device.configs || []).forEach((config_map) => {
197
+ let value = data?.data[config_map?.key];
198
+ const configId = config_map?.config;
199
+ updateGlobalValueMqtt(configById[configId], value);
200
+ });
201
+ }
202
+ };
203
+
204
+ export const handleMqttMessage = (
205
+ topic,
206
+ payloadData,
207
+ code,
208
+ chip,
209
+ configById
210
+ ) => {
211
+ if (topic === `eoh/chip/${code}/data`) {
212
+ // Modbus
213
+ // topic: eoh/chip/${code}/data
214
+ // payload: {data: '01aa010a', 'ack':'1', 'chip_temperature':5333, 'rssi':-61}
215
+ handleModbusData(chip, configById, payloadData.data);
216
+ }
217
+
218
+ const matchArduinoConfigValue = topic.match(/config\/(\d+)\/value/);
219
+ if (matchArduinoConfigValue) {
220
+ // Arduino
221
+ // topic: eoh/chip/{code}/config/127363/value
222
+ // payload: {v: 2130}
223
+ handleChipData(configById, matchArduinoConfigValue[1], payloadData);
224
+ }
225
+
226
+ const matchZigbeeConfigValue = topic.match(/zigbee\/(.+)\/data/);
227
+ if (matchZigbeeConfigValue) {
228
+ // Zigbee
229
+ // topic: eoh/chip/code-123/zigbee/IEEE-123/data
230
+ // payload: {zigbee_data: 'aaa', 'data': {state: 1, state_0: 0}}
231
+ handleZigbeeData(chip, configById, matchZigbeeConfigValue[1], payloadData);
232
+ }
233
+ };
@@ -18,6 +18,7 @@ import { Action } from '../context/actionType';
18
18
 
19
19
  import AQIGuide from '../screens/AQIGuide';
20
20
  import DeviceDetail from '../screens/Device/detail';
21
+ import ChangePosition from '../screens/ChangePosition';
21
22
  import SharingMemberList from '../screens/Sharing/MemberList';
22
23
  import ManageSubUnit from '../screens/SubUnit/ManageSubUnit';
23
24
  import SelectAddress from '../screens/Unit/SelectAddress';
@@ -31,20 +32,20 @@ import UVIndexGuide from '../screens/UVIndexGuide';
31
32
  import TDSGuide from '../screens/TDSGuide';
32
33
  import WaterQualityGuide from '../screens/WaterQualityGuide';
33
34
  import DeviceInfo from '../screens/DeviceInfo';
34
- import AddNewOneTap from '../screens/AddNewOneTap';
35
- import AddNewAutoSmart from '../screens/AddNewAutoSmart';
35
+ import AddNewOneTap from '../screens/Automate/OneTap';
36
+ import AddUnknownTypeSmart from '../screens/Automate/AddNewAutoSmart/AddUnknownTypeSmart';
36
37
  import PlaybackCamera from '../screens/PlayBackCamera';
37
38
  import AllCamera from '../screens/AllCamera';
38
39
  import ManageAccessScreen from '../screens/ManageAccess';
39
40
  import MoveToAnotherSubUnit from '../screens/MoveToAnotherSubUnit';
40
41
  import GuestInfo from '../screens/GuestInfo';
41
- import ScriptDetail from '../screens/ScriptDetail';
42
- import EditActionsList from '../screens/EditActionsList';
42
+ import ScriptDetail from '../screens/Automate/ScriptDetail';
43
+ import EditActionsList from '../screens/Automate/EditActionsList';
43
44
  import SelectUnit from '../screens/SelectUnit';
44
- import SetSchedule from '../screens/SetSchedule';
45
- import SelectMonitorDevices from '../screens/AddNewAction/SelectMonitorDevices';
45
+ import SetSchedule from '../screens/Automate/SetSchedule';
46
+ import SelectMonitorDevices from '../screens/Automate/AddNewAction/SelectMonitorDevices';
46
47
  import EditSubUnit from '../screens/SubUnit/EditSubUnit';
47
- import SetupConfigCondition from '../screens/AddNewAction/SetupConfigCondition';
48
+ import SetupConfigCondition from '../screens/Automate/AddNewAction/SetupConfigCondition';
48
49
  import EditDevice from '../screens/Device/EditDevice/index';
49
50
  import EmergencySetting from '../screens/EmergencySetting';
50
51
  import ConfirmUnitDeletion from '../screens/ConfirmUnitDeletion';
@@ -59,9 +60,12 @@ import { styles } from './UnitStackStyles';
59
60
  import { useBluetoothConnection } from '../hooks/IoT';
60
61
  import { realScanBluetoothDevices } from '../iot/RemoteControl/Bluetooth';
61
62
  import { ToastBottomHelper } from '../utils/Utils';
62
- import ChooseConfig from '../screens/AddNewAction/ChooseConfig';
63
- import SelectControlDevices from '../screens/AddNewAction/SelectControlDevices';
64
- import ChooseAction from '../screens/AddNewAction/ChooseAction';
63
+ import ChooseConfig from '../screens/Automate/AddNewAction/ChooseConfig';
64
+ import SelectControlDevices from '../screens/Automate/AddNewAction/SelectControlDevices';
65
+ import ChooseAction from '../screens/Automate/AddNewAction/ChooseAction';
66
+ import ScenarioName from '../screens/Automate/Scenario/ScenarioName';
67
+ import ValueChangeName from '../screens/Automate/ValueChange/ValueChangeName';
68
+ import AddAutomationTypeSmart from '../screens/Automate/AddNewAutoSmart/AddAutomationTypeSmart';
65
69
 
66
70
  const Stack = createStackNavigator();
67
71
 
@@ -269,6 +273,13 @@ export const UnitStack = memo((props) => {
269
273
  headerShown: false,
270
274
  }}
271
275
  />
276
+ <Stack.Screen
277
+ name={Route.ChangePosition}
278
+ component={ChangePosition}
279
+ options={{
280
+ headerShown: false,
281
+ }}
282
+ />
272
283
  <Stack.Screen
273
284
  name={Route.HanetCameraStack}
274
285
  component={HanetCameraStack}
@@ -389,8 +400,29 @@ export const UnitStack = memo((props) => {
389
400
  }}
390
401
  />
391
402
  <Stack.Screen
392
- name={Route.AddNewAutoSmart}
393
- component={AddNewAutoSmart}
403
+ name={Route.AddUnknownTypeSmart}
404
+ component={AddUnknownTypeSmart}
405
+ options={{
406
+ headerShown: false,
407
+ }}
408
+ />
409
+ <Stack.Screen
410
+ name={Route.AddAutomationTypeSmart}
411
+ component={AddAutomationTypeSmart}
412
+ options={{
413
+ headerShown: false,
414
+ }}
415
+ />
416
+ <Stack.Screen
417
+ name={Route.ScenarioName}
418
+ component={ScenarioName}
419
+ options={{
420
+ headerShown: false,
421
+ }}
422
+ />
423
+ <Stack.Screen
424
+ name={Route.ValueChangeName}
425
+ component={ValueChangeName}
394
426
  options={{
395
427
  headerShown: false,
396
428
  }}
@@ -7,7 +7,7 @@ import { check, RESULTS } from 'react-native-permissions';
7
7
  import { useTranslations } from '../../hooks/Common/useTranslations';
8
8
 
9
9
  import Text from '../../commons/Text';
10
- import { ViewButtonBottom, FullLoading } from '../../commons';
10
+ import { FullLoading } from '../../commons';
11
11
  import SearchBarLocation from '../../commons/SearchLocation';
12
12
  import RowLocation from '../../commons/SearchLocation/RowLocation';
13
13
  import { axiosGet } from '../../utils/Apis/axios';
@@ -25,8 +25,7 @@ import {
25
25
  OpenSetting,
26
26
  } from '../../utils/Permission/common';
27
27
  import { openPromptEnableLocation } from '../../utils/Setting/Location';
28
-
29
- export const initialRadius = 250;
28
+ import BottomButtonView from '../../commons/BottomButtonView';
30
29
 
31
30
  navigator.geolocation = require('@react-native-community/geolocation');
32
31
 
@@ -44,11 +43,7 @@ const AddLocationMaps = memo(() => {
44
43
  location: searchedLocation,
45
44
  isAddUnit: true,
46
45
  });
47
- }, [searchedLocation, navigate]);
48
-
49
- const onBack = useCallback(() => {
50
- goBack();
51
- }, [goBack]);
46
+ }, [navigate, searchedLocation]);
52
47
 
53
48
  const onTextInput = useCallback(async (newValue) => {
54
49
  setInput(newValue);
@@ -191,7 +186,10 @@ const AddLocationMaps = memo(() => {
191
186
  {t('text_explain_add_geolocation')}
192
187
  </Text>
193
188
  <View style={styles.searchLocation}>
194
- <SearchBarLocation input={input} onTextInput={onTextInput} />
189
+ <SearchBarLocation
190
+ input={input?.description || input}
191
+ onTextInput={onTextInput}
192
+ />
195
193
  <ScrollView
196
194
  style={styles.searchData}
197
195
  scrollIndicatorInsets={{ right: 1 }}
@@ -282,13 +280,17 @@ const AddLocationMaps = memo(() => {
282
280
  </MapView>
283
281
  </View>
284
282
  </View>
285
- <ViewButtonBottom
286
- leftTitle={t('cancel')}
287
- onLeftClick={onBack}
288
- rightTitle={t('done')}
289
- onRightClick={onDone}
290
- rightDisabled={!input}
291
- accessibilityLabelPrefix={'LOCATION_'}
283
+ <BottomButtonView
284
+ rowButton
285
+ style={styles.bottomButton}
286
+ mainTitle={t('done')}
287
+ onPressMain={onDone}
288
+ secondaryTitle={t('cancel')}
289
+ onPressSecondary={goBack}
290
+ typeMain={input?.description ? 'primaryText' : 'disabled'}
291
+ typeSecondary="primaryText"
292
+ accessibilityLabelPrefix="LOCATION_"
293
+ disableBackgroundMainButton
292
294
  />
293
295
  {loading && <FullLoading />}
294
296
  </View>
@@ -57,4 +57,7 @@ export default StyleSheet.create({
57
57
  text: {
58
58
  marginLeft: 12,
59
59
  },
60
+ bottomButton: {
61
+ backgroundColor: Colors.White,
62
+ },
60
63
  });
@@ -1,6 +1,5 @@
1
- import React from 'react';
1
+ import React, { useCallback } from 'react';
2
2
  import SelectSubUnit from '../../commons/SelectSubUnit';
3
- import { useCallback } from 'react';
4
3
  import { useTranslations } from '../../hooks/Common/useTranslations';
5
4
  import { useNavigation } from '@react-navigation/native';
6
5
  import Routes from '../../utils/Route';
@@ -11,6 +11,7 @@ import { getTranslate } from '../../../utils/I18n';
11
11
  import { SCProvider } from '../../../context';
12
12
  import { mockSCStore } from '../../../context/mockStore';
13
13
  import api from '../../../utils/Apis/axios';
14
+ import { useNavigation } from '@react-navigation/native';
14
15
 
15
16
  const wrapComponent = (route) => (
16
17
  <SCProvider initState={mockSCStore({})}>
@@ -20,28 +21,15 @@ const wrapComponent = (route) => (
20
21
 
21
22
  const mock = new MockAdapter(api.axiosInstance);
22
23
 
23
- const mockedNavigate = jest.fn();
24
- const mockedGoBack = jest.fn();
25
-
26
- jest.mock('@react-navigation/native', () => {
27
- return {
28
- ...jest.requireActual('@react-navigation/native'),
29
- useNavigation: () => ({
30
- navigate: mockedNavigate,
31
- goBack: mockedGoBack,
32
- }),
33
- };
34
- });
35
-
36
24
  describe('Test AddNewGateway', () => {
37
25
  let tree;
38
26
  let route;
39
-
40
- afterEach(() => {
41
- mockedNavigate.mockClear();
42
- });
27
+ const mockedGoBack = useNavigation().goBack;
28
+ const mockedNavigate = useNavigation().navigate;
43
29
 
44
30
  beforeEach(() => {
31
+ mockedGoBack.mockClear();
32
+ mockedNavigate.mockClear();
45
33
  route = {
46
34
  params: {
47
35
  unit_id: 1,
@@ -6,19 +6,11 @@ import { ViewButtonBottom } from '../../../commons';
6
6
  import { SCProvider } from '../../../context';
7
7
  import { mockSCStore } from '../../../context/mockStore';
8
8
  import { DEVICE_TYPE } from '../../../configs/Constants';
9
+ import { useNavigation } from '@react-navigation/native';
10
+ import MockAdapter from 'axios-mock-adapter';
11
+ import api from '../../../utils/Apis/axios';
9
12
 
10
- const mockedGoBack = jest.fn();
11
- const mockedNavigate = jest.fn();
12
- jest.mock('@react-navigation/native', () => {
13
- return {
14
- ...jest.requireActual('@react-navigation/native'),
15
- useNavigation: () => ({
16
- navigate: mockedNavigate,
17
- goBack: mockedGoBack,
18
- }),
19
- useIsFocused: () => ({}),
20
- };
21
- });
13
+ new MockAdapter(api.axiosInstance);
22
14
 
23
15
  const wrapComponent = (route) => (
24
16
  <SCProvider initState={mockSCStore({})}>
@@ -27,9 +19,9 @@ const wrapComponent = (route) => (
27
19
  );
28
20
 
29
21
  describe('Test SelectSubUnit', () => {
22
+ const mockedNavigate = useNavigation().navigate;
30
23
  beforeEach(() => {
31
24
  mockedNavigate.mockClear();
32
- mockedGoBack.mockClear();
33
25
  });
34
26
  let tree;
35
27