react-native-mytatva-rn-sdk 1.2.28 → 1.2.30
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.
|
@@ -61,925 +61,730 @@ import kotlin.coroutines.suspendCoroutine
|
|
|
61
61
|
|
|
62
62
|
@ReactModule(name = "CgmTrackyLib")
|
|
63
63
|
class CgmTrackyLibModule(reactContext: ReactApplicationContext) :
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
64
|
+
ReactContextBaseJavaModule(reactContext) {
|
|
65
|
+
private val mModel: MainActivityModel
|
|
66
|
+
var authenticateSDKService: AuthenticateSDKService
|
|
67
|
+
private val job = Job()
|
|
68
|
+
private val scope = CoroutineScope(Dispatchers.IO + job)
|
|
69
|
+
var prefsHelper: SharedPreferencesLibraryUtil
|
|
70
|
+
private val apiScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
|
71
|
+
private var debounceJob: Job? = null
|
|
72
|
+
private var lastDeviceStatus: PocDevice? = null
|
|
73
|
+
|
|
74
|
+
private var glucoseObserver: Observer<PocGlucose?>? = null
|
|
75
|
+
private var isObserving = false
|
|
76
|
+
|
|
77
|
+
init {
|
|
78
|
+
mReactContext = reactContext
|
|
79
|
+
prefsHelper = SharedPreferencesLibraryUtil(mReactContext)
|
|
80
|
+
val viewModelStore = ViewModelStore()
|
|
81
|
+
val factory =
|
|
82
|
+
ViewModelProvider.AndroidViewModelFactory.getInstance(reactContext.applicationContext as Application)
|
|
83
|
+
mModel = ViewModelProvider(viewModelStore, factory)[MainActivityModel::class.java]
|
|
84
|
+
authenticateSDKService = AuthenticateSDKService(scope = scope)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
companion object {
|
|
89
|
+
var mReactContext: ReactApplicationContext? = null
|
|
90
|
+
var userToken: String = ""
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
override fun getName(): String {
|
|
94
|
+
return "CgmTrackyLib"
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@ReactMethod
|
|
98
|
+
fun observeDeviceStatus(token: String) {
|
|
99
|
+
try {
|
|
100
|
+
userToken = token
|
|
101
|
+
Handler(Looper.getMainLooper()).post {
|
|
102
|
+
mModel.device.observeForever { device ->
|
|
103
|
+
if (device != lastDeviceStatus) {
|
|
104
|
+
lastDeviceStatus = device
|
|
105
|
+
postEventDataToAPI(device, "", lastDeviceStatus?.qrMessage ?: "")
|
|
106
|
+
resetDebounceTimer()
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (device != null) {
|
|
110
|
+
Log.d("observeDeviceStatus: ", device.toString())
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
} catch (e: Exception) {
|
|
115
|
+
Log.e("observeDeviceStatus", "observeDeviceStatus: ${e.message}")
|
|
85
116
|
}
|
|
117
|
+
}
|
|
86
118
|
|
|
119
|
+
@ReactMethod
|
|
120
|
+
fun observeTransmitterUnbindStatus(token: String) {
|
|
121
|
+
try {
|
|
122
|
+
userToken = token
|
|
87
123
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
124
|
+
authenticateSDKService.getCGMData(
|
|
125
|
+
environment = if ("uat".uppercase() == "PROD") TATVA_ENVIRONMENT.PROD else TATVA_ENVIRONMENT.STAGE,
|
|
126
|
+
token = userToken,
|
|
127
|
+
responseListener = object : AuthenticateSDKService.ResponseListener {
|
|
128
|
+
override fun onResponseSuccess(response: String) {
|
|
92
129
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
130
|
+
val response = Gson().fromJson(response, CgmSensorResponse::class.java)
|
|
131
|
+
val sensor = response.data?.firstOrNull()
|
|
96
132
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
Handler(Looper.getMainLooper()).post {
|
|
102
|
-
mModel.device.observeForever { device ->
|
|
103
|
-
if (device != lastDeviceStatus) {
|
|
104
|
-
lastDeviceStatus = device
|
|
105
|
-
postEventDataToAPI(device, "", lastDeviceStatus?.qrMessage ?: "")
|
|
106
|
-
resetDebounceTimer()
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (device != null) {
|
|
110
|
-
Log.d("observeDeviceStatus: ", device.toString())
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
} catch (e: Exception) {
|
|
115
|
-
Log.e("observeDeviceStatus", "observeDeviceStatus: ${e.message}")
|
|
116
|
-
}
|
|
117
|
-
}
|
|
133
|
+
if (sensor != null && !sensor.startDate.isNullOrEmpty() && !sensor.endDate.isNullOrEmpty()) {
|
|
134
|
+
val startDate = sensor.startDate
|
|
135
|
+
val endDate = sensor.endDate
|
|
136
|
+
val sensorId = sensor.sensorId
|
|
118
137
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
try {
|
|
122
|
-
userToken = token
|
|
123
|
-
|
|
124
|
-
authenticateSDKService.getCGMData(
|
|
125
|
-
environment = if ("uat".uppercase() == "PROD") TATVA_ENVIRONMENT.PROD else TATVA_ENVIRONMENT.STAGE,
|
|
126
|
-
token = userToken,
|
|
127
|
-
responseListener = object : AuthenticateSDKService.ResponseListener {
|
|
128
|
-
override fun onResponseSuccess(response: String) {
|
|
129
|
-
|
|
130
|
-
val response = Gson().fromJson(response, CgmSensorResponse::class.java)
|
|
131
|
-
val sensor = response.data?.firstOrNull()
|
|
132
|
-
|
|
133
|
-
if (sensor != null && !sensor.startDate.isNullOrEmpty() && !sensor.endDate.isNullOrEmpty()) {
|
|
134
|
-
val startDate = sensor.startDate
|
|
135
|
-
val endDate = sensor.endDate
|
|
136
|
-
val sensorId = sensor.sensorId
|
|
137
|
-
|
|
138
|
-
println("Start Date: $startDate")
|
|
139
|
-
println("End Date: $endDate")
|
|
140
|
-
|
|
141
|
-
if (isCurrentDateInRange(startDate, endDate)) {
|
|
142
|
-
|
|
143
|
-
println("Current date is in range")
|
|
144
|
-
|
|
145
|
-
val pocDevice =
|
|
146
|
-
RepositoryDevice.getInstance(BApplication.getContext()).latestDeviceIoThread
|
|
147
|
-
Log.d("pocDevice logsss", pocDevice.toString())
|
|
148
|
-
if (pocDevice != null) {
|
|
149
|
-
if (pocDevice.isUnBind) {
|
|
150
|
-
postEventDataToAPI(
|
|
151
|
-
pocDevice,
|
|
152
|
-
DeviceStatus.TRANSMITTER_DISCONNECT.id,
|
|
153
|
-
pocDevice.qrMessage
|
|
154
|
-
)
|
|
155
|
-
}
|
|
156
|
-
} else {
|
|
157
|
-
postEventDataToAPI(
|
|
158
|
-
pocDevice,
|
|
159
|
-
DeviceStatus.TRANSMITTER_DISCONNECT.id,
|
|
160
|
-
sensorId
|
|
161
|
-
)
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
} else {
|
|
165
|
-
println("Current date is out of range")
|
|
166
|
-
}
|
|
167
|
-
} else {
|
|
168
|
-
println("Start or End date not available")
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
override fun onResponseFail() {
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
)
|
|
138
|
+
println("Start Date: $startDate")
|
|
139
|
+
println("End Date: $endDate")
|
|
176
140
|
|
|
177
|
-
|
|
178
|
-
Log.e("observeTransmitterUnbindStatus", "observeTransmitterUnbindStatus: ${e.message}")
|
|
179
|
-
}
|
|
180
|
-
}
|
|
141
|
+
if (isCurrentDateInRange(startDate, endDate)) {
|
|
181
142
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
val bleStatus = bluetoothAdapter?.isEnabled == true
|
|
187
|
-
var status = ""
|
|
188
|
-
|
|
189
|
-
Log.d("ble Status", bleStatus.toString())
|
|
190
|
-
Log.d("device.isBoundAndConnect Status", device?.isBoundAndConnect.toString())
|
|
191
|
-
Log.d("device.isUnBind Status", device?.isUnBind.toString())
|
|
192
|
-
Log.d("device.isBoundButDisConnect Status", device?.isBoundButDisConnect.toString())
|
|
193
|
-
|
|
194
|
-
status = if (mStatus.isEmpty()) {
|
|
195
|
-
when {
|
|
196
|
-
device?.isBoundAndConnect == true -> DeviceStatus.CONNECTED.id
|
|
197
|
-
!bleStatus -> DeviceStatus.BLUETOOTH_OFF.id
|
|
198
|
-
device?.isUnBind == true -> DeviceStatus.TRANSMITTER_DISCONNECT.id
|
|
199
|
-
device?.isBoundButDisConnect == true -> DeviceStatus.DISCONNECTED.id
|
|
200
|
-
else -> "" // fallback if no status matches
|
|
201
|
-
}
|
|
202
|
-
} else {
|
|
203
|
-
mStatus
|
|
204
|
-
}
|
|
143
|
+
println("Current date is in range")
|
|
144
|
+
|
|
145
|
+
val pocDevice =
|
|
146
|
+
RepositoryDevice.getInstance(BApplication.getContext()).latestDeviceIoThread
|
|
205
147
|
|
|
206
|
-
if (
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
val obj = JSONObject().apply {
|
|
215
|
-
put("sensorId", sensorId ?: "")
|
|
216
|
-
put("status", status)
|
|
217
|
-
put("rawData", rawData)
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
authenticateSDKService.postDeviceData(
|
|
221
|
-
environment = if ("uat".uppercase() == "PROD") TATVA_ENVIRONMENT.PROD else TATVA_ENVIRONMENT.STAGE,
|
|
222
|
-
data = obj.toString(),
|
|
223
|
-
token = userToken,
|
|
224
|
-
loaderListener = object : LoaderListener {
|
|
225
|
-
override fun onShowLoader() {}
|
|
226
|
-
override fun onHideLoader() {}
|
|
227
|
-
}
|
|
148
|
+
if (pocDevice != null) {
|
|
149
|
+
Log.d("pocDevice logsss", pocDevice.toString())
|
|
150
|
+
|
|
151
|
+
if (pocDevice.isUnBind) {
|
|
152
|
+
postEventDataToAPI(
|
|
153
|
+
pocDevice,
|
|
154
|
+
DeviceStatus.TRANSMITTER_DISCONNECT.id,
|
|
155
|
+
pocDevice.qrMessage
|
|
228
156
|
)
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
Log.d("pocDevice logsss", "Data null")
|
|
160
|
+
|
|
161
|
+
postEventDataToAPI(
|
|
162
|
+
pocDevice,
|
|
163
|
+
DeviceStatus.TRANSMITTER_DISCONNECT.id,
|
|
164
|
+
sensorId
|
|
165
|
+
)
|
|
229
166
|
}
|
|
230
167
|
|
|
231
|
-
|
|
232
|
-
|
|
168
|
+
} else {
|
|
169
|
+
println("Current date is out of range")
|
|
170
|
+
}
|
|
171
|
+
} else {
|
|
172
|
+
println("Start or End date not available")
|
|
233
173
|
}
|
|
234
|
-
|
|
235
|
-
}
|
|
174
|
+
}
|
|
236
175
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
debounceJob = apiScope.launch {
|
|
240
|
-
delay(60 * 60 * 1000L) // 60 minutes in ms
|
|
241
|
-
lastDeviceStatus = null // Reset status after timeout
|
|
242
|
-
println("60 min window expired, status reset.")
|
|
176
|
+
override fun onResponseFail() {
|
|
177
|
+
}
|
|
243
178
|
}
|
|
244
|
-
|
|
179
|
+
)
|
|
245
180
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
try {
|
|
249
|
-
userToken = token
|
|
250
|
-
val intent = Intent(currentActivity, StartCGMActivity::class.java)
|
|
251
|
-
currentActivity?.startActivity(intent)
|
|
252
|
-
} catch (e: Exception) {
|
|
253
|
-
Log.e("startCgmTracky", "startCgmTracky: ${e.message}")
|
|
254
|
-
}
|
|
181
|
+
} catch (e: Exception) {
|
|
182
|
+
Log.e("observeTransmitterUnbindStatus", "observeTransmitterUnbindStatus: ${e.message}")
|
|
255
183
|
}
|
|
184
|
+
}
|
|
256
185
|
|
|
257
|
-
|
|
258
|
-
|
|
186
|
+
private fun postEventDataToAPI(device: PocDevice?, mStatus: String, sensorId: String?) {
|
|
187
|
+
apiScope.launch {
|
|
188
|
+
try {
|
|
189
|
+
val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter()
|
|
190
|
+
val bleStatus = bluetoothAdapter?.isEnabled == true
|
|
191
|
+
var status = ""
|
|
192
|
+
|
|
193
|
+
status = if (mStatus.isEmpty()) {
|
|
194
|
+
when {
|
|
195
|
+
device?.isBoundAndConnect == true -> DeviceStatus.CONNECTED.id
|
|
196
|
+
!bleStatus -> DeviceStatus.BLUETOOTH_OFF.id
|
|
197
|
+
device?.isUnBind == true -> DeviceStatus.TRANSMITTER_DISCONNECT.id
|
|
198
|
+
device?.isBoundButDisConnect == true -> DeviceStatus.DISCONNECTED.id
|
|
199
|
+
else -> "" // fallback if no status matches
|
|
200
|
+
}
|
|
201
|
+
} else {
|
|
202
|
+
mStatus
|
|
203
|
+
}
|
|
259
204
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
205
|
+
if (status.isNotEmpty()) {
|
|
206
|
+
val rawData = JSONObject().apply {
|
|
207
|
+
put("transmitterName", device?.name ?: "")
|
|
208
|
+
put("SensorId", sensorId ?: "")
|
|
209
|
+
put("Sensor", sensorId ?: "")
|
|
210
|
+
put("timeInMillis", Date().time)
|
|
211
|
+
}
|
|
263
212
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
213
|
+
val obj = JSONObject().apply {
|
|
214
|
+
put("sensorId", sensorId ?: "")
|
|
215
|
+
put("status", status)
|
|
216
|
+
put("rawData", rawData)
|
|
217
|
+
}
|
|
267
218
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
true
|
|
276
|
-
)
|
|
277
|
-
} else {
|
|
278
|
-
Intent(currentActivity, PermissionActivity::class.java).putExtra(
|
|
279
|
-
"IsForReconnect",
|
|
280
|
-
true
|
|
281
|
-
)
|
|
219
|
+
authenticateSDKService.postDeviceData(
|
|
220
|
+
environment = if ("uat".uppercase() == "PROD") TATVA_ENVIRONMENT.PROD else TATVA_ENVIRONMENT.STAGE,
|
|
221
|
+
data = obj.toString(),
|
|
222
|
+
token = userToken,
|
|
223
|
+
loaderListener = object : LoaderListener {
|
|
224
|
+
override fun onShowLoader() {}
|
|
225
|
+
override fun onHideLoader() {}
|
|
282
226
|
}
|
|
283
|
-
|
|
284
|
-
} catch (e: Exception) {
|
|
285
|
-
Log.e("reconnectCgmTracky", "reconnectCgmTracky: ${e.message}")
|
|
227
|
+
)
|
|
286
228
|
}
|
|
287
|
-
}
|
|
288
229
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
230
|
+
} catch (e: Exception) {
|
|
231
|
+
e.printStackTrace()
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private fun resetDebounceTimer() {
|
|
237
|
+
debounceJob?.cancel() // Cancel any existing timer
|
|
238
|
+
debounceJob = apiScope.launch {
|
|
239
|
+
delay(60 * 60 * 1000L) // 60 minutes in ms
|
|
240
|
+
lastDeviceStatus = null // Reset status after timeout
|
|
241
|
+
println("60 min window expired, status reset.")
|
|
297
242
|
}
|
|
243
|
+
}
|
|
298
244
|
|
|
299
|
-
|
|
300
|
-
|
|
245
|
+
@ReactMethod
|
|
246
|
+
fun startCgmTracky(token: String) {
|
|
247
|
+
try {
|
|
248
|
+
userToken = token
|
|
249
|
+
val intent = Intent(currentActivity, StartCGMActivity::class.java)
|
|
250
|
+
currentActivity?.startActivity(intent)
|
|
251
|
+
} catch (e: Exception) {
|
|
252
|
+
Log.e("startCgmTracky", "startCgmTracky: ${e.message}")
|
|
253
|
+
}
|
|
254
|
+
}
|
|
301
255
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
requiredPermissions.addAll(PermissionUtils.BLUETOOTH_S)
|
|
305
|
-
}
|
|
256
|
+
fun isCurrentDateInRange(startDateStr: String, endDateStr: String): Boolean {
|
|
257
|
+
val format = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
|
|
306
258
|
|
|
307
|
-
|
|
308
|
-
|
|
259
|
+
val startDate = format.parse(startDateStr)
|
|
260
|
+
val endDate = format.parse(endDateStr)
|
|
261
|
+
val currentDate = Date()
|
|
309
262
|
|
|
310
|
-
|
|
311
|
-
|
|
263
|
+
return startDate != null && endDate != null &&
|
|
264
|
+
!currentDate.before(startDate) && !currentDate.after(endDate)
|
|
265
|
+
}
|
|
312
266
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
267
|
+
@ReactMethod
|
|
268
|
+
fun reconnectCgmTracky(token: String) {
|
|
269
|
+
try {
|
|
270
|
+
userToken = token
|
|
271
|
+
val intent = if (areAllPermissionsGranted()) {
|
|
272
|
+
Intent(currentActivity, SearchTransmitterActivity::class.java).putExtra(
|
|
273
|
+
"IsForReconnect",
|
|
274
|
+
true
|
|
275
|
+
)
|
|
276
|
+
} else {
|
|
277
|
+
Intent(currentActivity, PermissionActivity::class.java).putExtra(
|
|
278
|
+
"IsForReconnect",
|
|
279
|
+
true
|
|
280
|
+
)
|
|
281
|
+
}
|
|
282
|
+
currentActivity?.startActivity(intent)
|
|
283
|
+
} catch (e: Exception) {
|
|
284
|
+
Log.e("reconnectCgmTracky", "reconnectCgmTracky: ${e.message}")
|
|
319
285
|
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
@ReactMethod
|
|
289
|
+
fun openHelpSupport() {
|
|
290
|
+
try {
|
|
291
|
+
val intent = Intent(currentActivity, HelpActivity::class.java)
|
|
292
|
+
currentActivity?.startActivity(intent)
|
|
293
|
+
} catch (e: Exception) {
|
|
294
|
+
Log.e("openHelpSupport", "openHelpSupport: ${e.message}")
|
|
295
|
+
}
|
|
296
|
+
}
|
|
320
297
|
|
|
298
|
+
private fun areAllPermissionsGranted(): Boolean {
|
|
299
|
+
val requiredPermissions = mutableListOf<String>()
|
|
321
300
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
Handler(Looper.getMainLooper()).post {
|
|
327
|
-
//Observe latest glucose data
|
|
328
|
-
mModel.latestGlucose.observeForever { pocGlucose ->
|
|
329
|
-
if (pocGlucose != null) {
|
|
330
|
-
|
|
331
|
-
if (pocGlucose.errorCode == enumError.NONE) {
|
|
332
|
-
if (pocGlucose.showGlucoseMG > 0) {
|
|
333
|
-
val dto: GlucoseLog = mapToDto(pocGlucose)
|
|
334
|
-
val logs: ArrayList<GlucoseLog> = ArrayList()
|
|
335
|
-
logs.add(dto)
|
|
336
|
-
|
|
337
|
-
val request: GlucoseLogRequest =
|
|
338
|
-
GlucoseLogRequest(vendor = "GoodFlip", logs = logs)
|
|
339
|
-
val gson: Gson = GsonBuilder().create()
|
|
340
|
-
val json = gson.toJson(request)
|
|
341
|
-
|
|
342
|
-
Log.d("Glucose data 3 min==> ", "Glucose data 3 min==> final Json: $json")
|
|
343
|
-
|
|
344
|
-
authenticateSDKService.postCGMData(
|
|
345
|
-
environment = if ("uat".uppercase() == "PROD") TATVA_ENVIRONMENT.PROD else TATVA_ENVIRONMENT.STAGE,
|
|
346
|
-
data = json.toString(),
|
|
347
|
-
token = userToken,
|
|
348
|
-
responseListener = object :
|
|
349
|
-
AuthenticateSDKService.ResponseListener {
|
|
350
|
-
override fun onResponseSuccess() {
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
override fun onResponseFail() {
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
)
|
|
357
|
-
}
|
|
358
|
-
} else {
|
|
359
|
-
if (pocGlucose.errorCode == enumError.ERROR_FLOODING_WATER) {
|
|
360
|
-
lastDeviceStatus =
|
|
361
|
-
pocGlucose.deviceId.toInt().let { mModel.getDeviceInfo(it) }
|
|
362
|
-
lastDeviceStatus?.let {
|
|
363
|
-
postEventDataToAPI(
|
|
364
|
-
it,
|
|
365
|
-
DeviceStatus.MOISTURE_DETECT.id
|
|
366
|
-
)
|
|
367
|
-
}
|
|
368
|
-
resetDebounceTimer()
|
|
369
|
-
} else if (pocGlucose.errorCode == enumError.ERROR_CURRENT_SMALL || pocGlucose.errorCode == enumError.ERROR_NOISE || pocGlucose.errorCode == enumError.ERROR_SENSITIVITY_ATTENUATION) {
|
|
370
|
-
lastDeviceStatus =
|
|
371
|
-
pocGlucose.deviceId.toInt().let { mModel.getDeviceInfo(it) }
|
|
372
|
-
lastDeviceStatus?.let {
|
|
373
|
-
postEventDataToAPI(
|
|
374
|
-
it,
|
|
375
|
-
DeviceStatus.WEAK_SIGNAL.id
|
|
376
|
-
)
|
|
377
|
-
}
|
|
378
|
-
resetDebounceTimer()
|
|
379
|
-
} else {
|
|
380
|
-
lastDeviceStatus =
|
|
381
|
-
pocGlucose.deviceId.toInt().let { mModel.getDeviceInfo(it) }
|
|
382
|
-
lastDeviceStatus?.let {
|
|
383
|
-
postEventDataToAPI(
|
|
384
|
-
it,
|
|
385
|
-
DeviceStatus.ERROR_COMMON.id
|
|
386
|
-
)
|
|
387
|
-
}
|
|
388
|
-
resetDebounceTimer()
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
} catch (e: Exception) {
|
|
395
|
-
Log.e("observeGlucoseData", "observeGlucoseData: ${e.message}")
|
|
396
|
-
}
|
|
397
|
-
}*/
|
|
398
|
-
|
|
399
|
-
@ReactMethod
|
|
400
|
-
fun observeGlucoseData(token: String) {
|
|
401
|
-
try {
|
|
402
|
-
userToken = token
|
|
301
|
+
// Add Bluetooth permissions
|
|
302
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
303
|
+
requiredPermissions.addAll(PermissionUtils.BLUETOOTH_S)
|
|
304
|
+
}
|
|
403
305
|
|
|
404
|
-
|
|
405
|
-
|
|
306
|
+
// Add location permissions
|
|
307
|
+
requiredPermissions.addAll(PermissionUtils.LOCAL_PERMISSION)
|
|
406
308
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
// Critical fix: Explicitly handle nullable parameter
|
|
410
|
-
if (pocGlucose != null) {
|
|
411
|
-
handleGlucoseData(pocGlucose)
|
|
412
|
-
} else {
|
|
413
|
-
Log.w("observeGlucoseData", "Received null glucose data - skipping processing")
|
|
414
|
-
}
|
|
415
|
-
}
|
|
309
|
+
// Add camera permission
|
|
310
|
+
requiredPermissions.addAll(PermissionUtils.CAMERA_PERMISSION)
|
|
416
311
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
isObserving = true
|
|
423
|
-
Log.d("observeGlucoseData", "Observer added successfully")
|
|
424
|
-
} catch (e: Exception) {
|
|
425
|
-
Log.e("observeGlucoseData", "Error adding observer: ${e.message}")
|
|
426
|
-
glucoseObserver = null
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
} catch (e: Exception) {
|
|
431
|
-
Log.e("observeGlucoseData", "observeGlucoseData: ${e.message}")
|
|
432
|
-
e.printStackTrace()
|
|
433
|
-
}
|
|
312
|
+
return requiredPermissions.all {
|
|
313
|
+
ContextCompat.checkSelfPermission(
|
|
314
|
+
mReactContext!!,
|
|
315
|
+
it
|
|
316
|
+
) == PackageManager.PERMISSION_GRANTED
|
|
434
317
|
}
|
|
318
|
+
}
|
|
435
319
|
|
|
320
|
+
@ReactMethod
|
|
321
|
+
fun observeGlucoseData(token: String) {
|
|
322
|
+
try {
|
|
323
|
+
userToken = token
|
|
436
324
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
325
|
+
// Remove existing observer if any to prevent memory leaks
|
|
326
|
+
stopObservingGlucoseData()
|
|
327
|
+
|
|
328
|
+
// Create new observer with explicit nullable parameter type
|
|
329
|
+
glucoseObserver = Observer<PocGlucose?> { pocGlucose ->
|
|
330
|
+
if (pocGlucose != null) {
|
|
331
|
+
// Add timestamp check to prevent processing old data
|
|
332
|
+
val currentTime = System.currentTimeMillis()
|
|
333
|
+
val dataAge = currentTime - pocGlucose.timeInMillis
|
|
334
|
+
|
|
335
|
+
// Only process data that's relatively recent (within last 10 minutes as example)
|
|
336
|
+
// Adjust this threshold based on your requirements
|
|
337
|
+
if (dataAge <= 10 * 60 * 1000L) { // 10 minutes
|
|
338
|
+
handleGlucoseData(pocGlucose)
|
|
339
|
+
} else {
|
|
340
|
+
Log.d("observeGlucoseData", "Skipping old glucose data: age = ${dataAge}ms")
|
|
341
|
+
}
|
|
342
|
+
} else {
|
|
343
|
+
Log.w("observeGlucoseData", "Received null glucose data - skipping processing")
|
|
344
|
+
}
|
|
345
|
+
}
|
|
444
346
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
val json = gson.toJson(request)
|
|
457
|
-
|
|
458
|
-
Log.d("Glucose data 3 min==> ", "Glucose data 3 min==> final Json: $json")
|
|
459
|
-
|
|
460
|
-
authenticateSDKService.postCGMData(
|
|
461
|
-
environment = if ("uat".uppercase() == "PROD") TATVA_ENVIRONMENT.PROD else TATVA_ENVIRONMENT.STAGE,
|
|
462
|
-
data = json,
|
|
463
|
-
token = userToken,
|
|
464
|
-
responseListener = object : AuthenticateSDKService.ResponseListener {
|
|
465
|
-
override fun onResponseSuccess(response: String) {
|
|
466
|
-
updateSyncMetadata(pocGlucose)
|
|
467
|
-
Log.d("CGM Data", "Single glucose data uploaded successfully")
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
override fun onResponseFail() {
|
|
471
|
-
Log.e("CGM Data", "Failed to upload single glucose data")
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
)
|
|
475
|
-
} else {
|
|
476
|
-
Log.d(
|
|
477
|
-
"handleGlucoseData",
|
|
478
|
-
"Glucose value is 0 or negative: ${pocGlucose.showGlucoseMG}"
|
|
479
|
-
)
|
|
480
|
-
}
|
|
481
|
-
} else {
|
|
482
|
-
Log.d("handleGlucoseData", "Glucose data has error: ${pocGlucose.errorCode}")
|
|
483
|
-
handleGlucoseError(pocGlucose)
|
|
484
|
-
}
|
|
485
|
-
} catch (e: Exception) {
|
|
486
|
-
Log.e("handleGlucoseData", "Error handling glucose data: ${e.message}")
|
|
487
|
-
e.printStackTrace()
|
|
347
|
+
// Add observer on main thread
|
|
348
|
+
Handler(Looper.getMainLooper()).post {
|
|
349
|
+
glucoseObserver?.let { observer ->
|
|
350
|
+
try {
|
|
351
|
+
mModel.latestGlucose.observeForever(observer)
|
|
352
|
+
isObserving = true
|
|
353
|
+
Log.d("observeGlucoseData", "Live glucose observer started successfully")
|
|
354
|
+
} catch (e: Exception) {
|
|
355
|
+
Log.e("observeGlucoseData", "Error adding observer: ${e.message}")
|
|
356
|
+
glucoseObserver = null
|
|
357
|
+
}
|
|
488
358
|
}
|
|
359
|
+
}
|
|
360
|
+
} catch (e: Exception) {
|
|
361
|
+
Log.e("observeGlucoseData", "observeGlucoseData: ${e.message}")
|
|
362
|
+
e.printStackTrace()
|
|
489
363
|
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
private fun handleGlucoseData(pocGlucose: PocGlucose) {
|
|
367
|
+
try {
|
|
368
|
+
// Additional safety check
|
|
369
|
+
if (pocGlucose.glucoseId == null) {
|
|
370
|
+
Log.w("handleGlucoseData", "Glucose ID is null, skipping processing")
|
|
371
|
+
return
|
|
372
|
+
}
|
|
490
373
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
else -> {
|
|
516
|
-
Log.d(
|
|
517
|
-
"handleGlucoseError",
|
|
518
|
-
"Common error detected: ${pocGlucose.errorCode}"
|
|
519
|
-
)
|
|
520
|
-
DeviceStatus.ERROR_COMMON.id
|
|
521
|
-
}
|
|
522
|
-
}
|
|
374
|
+
Log.d("handleGlucoseData", "Processing glucose data: ${pocGlucose.glucoseId}")
|
|
375
|
+
|
|
376
|
+
if (pocGlucose.errorCode == enumError.NONE) {
|
|
377
|
+
if (pocGlucose.showGlucoseMG > 0) {
|
|
378
|
+
val dto: GlucoseLog = mapToDto(pocGlucose)
|
|
379
|
+
val logs: ArrayList<GlucoseLog> = ArrayList()
|
|
380
|
+
logs.add(dto)
|
|
381
|
+
|
|
382
|
+
val request: GlucoseLogRequest =
|
|
383
|
+
GlucoseLogRequest(vendor = "GoodFlip", logs = logs)
|
|
384
|
+
val gson: Gson = GsonBuilder().create()
|
|
385
|
+
val json = gson.toJson(request)
|
|
386
|
+
|
|
387
|
+
Log.d("Glucose data 3 min==> ", "Glucose data 3 min==> final Json: $json")
|
|
388
|
+
|
|
389
|
+
authenticateSDKService.postCGMData(
|
|
390
|
+
environment = if ("uat".uppercase() == "PROD") TATVA_ENVIRONMENT.PROD else TATVA_ENVIRONMENT.STAGE,
|
|
391
|
+
data = json,
|
|
392
|
+
token = userToken,
|
|
393
|
+
responseListener = object : AuthenticateSDKService.ResponseListener {
|
|
394
|
+
override fun onResponseSuccess(response: String) {
|
|
395
|
+
updateSyncMetadata(pocGlucose)
|
|
396
|
+
Log.d("CGM Data", "Single glucose data uploaded successfully")
|
|
397
|
+
}
|
|
523
398
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
Log.e(
|
|
528
|
-
"handleGlucoseError",
|
|
529
|
-
"Device info not found for deviceId: ${pocGlucose.deviceId}"
|
|
530
|
-
)
|
|
399
|
+
override fun onResponseFail() {
|
|
400
|
+
Log.e("CGM Data", "Failed to upload single glucose data")
|
|
401
|
+
}
|
|
531
402
|
}
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
403
|
+
)
|
|
404
|
+
} else {
|
|
405
|
+
Log.d(
|
|
406
|
+
"handleGlucoseData",
|
|
407
|
+
"Glucose value is 0 or negative: ${pocGlucose.showGlucoseMG}"
|
|
408
|
+
)
|
|
535
409
|
}
|
|
410
|
+
} else {
|
|
411
|
+
Log.d("handleGlucoseData", "Glucose data has error: ${pocGlucose.errorCode}")
|
|
412
|
+
handleGlucoseError(pocGlucose)
|
|
413
|
+
}
|
|
414
|
+
} catch (e: Exception) {
|
|
415
|
+
Log.e("handleGlucoseData", "Error handling glucose data: ${e.message}")
|
|
416
|
+
e.printStackTrace()
|
|
536
417
|
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Extract error handling logic
|
|
421
|
+
private fun handleGlucoseError(pocGlucose: PocGlucose) {
|
|
422
|
+
try {
|
|
423
|
+
// Additional safety check for deviceId
|
|
424
|
+
if (pocGlucose.deviceId == null) {
|
|
425
|
+
Log.e("handleGlucoseError", "Device ID is null, cannot process error")
|
|
426
|
+
return
|
|
427
|
+
}
|
|
537
428
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
429
|
+
val deviceInfo = mModel.getDeviceInfo(pocGlucose.deviceId.toInt())
|
|
430
|
+
deviceInfo?.let {
|
|
431
|
+
val statusId = when (pocGlucose.errorCode) {
|
|
432
|
+
enumError.ERROR_FLOODING_WATER -> {
|
|
433
|
+
Log.d("handleGlucoseError", "Moisture detected")
|
|
434
|
+
DeviceStatus.MOISTURE_DETECT.id
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
enumError.ERROR_CURRENT_SMALL,
|
|
438
|
+
enumError.ERROR_NOISE,
|
|
439
|
+
enumError.ERROR_SENSITIVITY_ATTENUATION -> {
|
|
440
|
+
Log.d("handleGlucoseError", "Weak signal detected")
|
|
441
|
+
DeviceStatus.WEAK_SIGNAL.id
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
else -> {
|
|
445
|
+
Log.d(
|
|
446
|
+
"handleGlucoseError",
|
|
447
|
+
"Common error detected: ${pocGlucose.errorCode}"
|
|
552
448
|
)
|
|
449
|
+
DeviceStatus.ERROR_COMMON.id
|
|
553
450
|
}
|
|
554
|
-
} else {
|
|
555
|
-
observeGlucoseData(userToken)
|
|
556
451
|
}
|
|
557
452
|
|
|
558
|
-
|
|
559
|
-
|
|
453
|
+
postEventDataToAPI(it, statusId, it.qrMessage)
|
|
454
|
+
resetDebounceTimer()
|
|
455
|
+
} ?: run {
|
|
456
|
+
Log.e(
|
|
457
|
+
"handleGlucoseError",
|
|
458
|
+
"Device info not found for deviceId: ${pocGlucose.deviceId}"
|
|
459
|
+
)
|
|
560
460
|
}
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
@ReactMethod
|
|
565
|
-
fun observeAllGlucoseData(token: String) {
|
|
566
|
-
userToken = token
|
|
567
|
-
Log.e("userToken", "userToken: $token")
|
|
568
|
-
|
|
569
|
-
// Stop current observation to prevent duplicates
|
|
570
|
-
stopObservingGlucoseData()
|
|
571
|
-
|
|
572
|
-
try {
|
|
573
|
-
val lastSyncData = prefsHelper.lastSyncData
|
|
574
|
-
Log.d("lastSyncData: ", Gson().toJson(lastSyncData).toString())
|
|
575
|
-
|
|
576
|
-
if (lastSyncData != null) {
|
|
577
|
-
CoroutineScope(Dispatchers.IO).launch {
|
|
578
|
-
val glucoseData = mModel.getGlucoseBetweenTime(lastSyncData.lastSyncTime)
|
|
579
|
-
if (glucoseData != null) {
|
|
580
|
-
getGlucoseDataAndUploadInBatch(glucoseData)
|
|
581
|
-
} else {
|
|
582
|
-
Log.d(
|
|
583
|
-
"observeAllGlucoseData",
|
|
584
|
-
"No glucose data found, starting live observation"
|
|
585
|
-
)
|
|
586
|
-
observeGlucoseData(userToken)
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
} else {
|
|
590
|
-
observeGlucoseData(userToken)
|
|
591
|
-
}
|
|
592
|
-
} catch (e: Exception) {
|
|
593
|
-
Log.e("observeAllGlucoseData", "observeAllGlucoseData Error: ${e.message}")
|
|
594
|
-
}
|
|
461
|
+
} catch (e: Exception) {
|
|
462
|
+
Log.e("handleGlucoseError", "Error handling glucose error: ${e.message}")
|
|
463
|
+
e.printStackTrace()
|
|
595
464
|
}
|
|
465
|
+
}
|
|
596
466
|
|
|
597
|
-
@ReactMethod
|
|
598
|
-
fun stopObservingGlucoseData() {
|
|
599
|
-
try {
|
|
600
|
-
glucoseObserver?.let { observer ->
|
|
601
|
-
Handler(Looper.getMainLooper()).post {
|
|
602
|
-
try {
|
|
603
|
-
mModel.latestGlucose.removeObserver(observer)
|
|
604
|
-
isObserving = false
|
|
605
|
-
Log.d("stopObservingGlucoseData", "Observer removed successfully")
|
|
606
|
-
} catch (e: Exception) {
|
|
607
|
-
Log.e("stopObservingGlucoseData", "Error removing observer: ${e.message}")
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
glucoseObserver = null
|
|
612
|
-
} catch (e: Exception) {
|
|
613
|
-
Log.e("stopObservingGlucoseData", "Error stopping observer: ${e.message}")
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
467
|
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
if (!isObserving) {
|
|
621
|
-
observeGlucoseData(userToken)
|
|
622
|
-
}
|
|
623
|
-
return
|
|
624
|
-
}
|
|
468
|
+
@ReactMethod
|
|
469
|
+
fun observeAllGlucoseData(token: String) {
|
|
470
|
+
userToken = token
|
|
625
471
|
|
|
626
|
-
|
|
627
|
-
|
|
472
|
+
// Stop current observation to prevent duplicates
|
|
473
|
+
stopObservingGlucoseData()
|
|
628
474
|
|
|
629
|
-
|
|
475
|
+
try {
|
|
476
|
+
val lastSyncData = prefsHelper.lastSyncData
|
|
477
|
+
Log.d("lastSyncData: ", Gson().toJson(lastSyncData).toString())
|
|
630
478
|
|
|
479
|
+
if (lastSyncData != null) {
|
|
631
480
|
CoroutineScope(Dispatchers.IO).launch {
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
countdownDays = pocGlucose.countdownDays,
|
|
642
|
-
hypoglycemiaEarlyWarnMinutes = pocGlucose.hypoglycemiaEarlyWarnMinutes,
|
|
643
|
-
showGlucoseMG = pocGlucose.showGlucoseMG,
|
|
644
|
-
glucoseId = pocGlucose.glucoseId,
|
|
645
|
-
name = pocGlucose.name,
|
|
646
|
-
bytes = pocGlucose.bytes,
|
|
647
|
-
showGlucose = pocGlucose.showGlucose,
|
|
648
|
-
Ib = pocGlucose.ib,
|
|
649
|
-
Iw = pocGlucose.iw,
|
|
650
|
-
countdownHours = pocGlucose.countdownHours,
|
|
651
|
-
T = pocGlucose.t,
|
|
652
|
-
year = pocGlucose.year,
|
|
653
|
-
month = pocGlucose.month,
|
|
654
|
-
day = pocGlucose.day,
|
|
655
|
-
hour = pocGlucose.hour,
|
|
656
|
-
minute = pocGlucose.minute,
|
|
657
|
-
trendObject = com.mytatvarnsdk.model.TrendObject(
|
|
658
|
-
trendId = pocGlucose.trend.trendId,
|
|
659
|
-
drawableId = pocGlucose.trend.drawableId,
|
|
660
|
-
widgetImg = pocGlucose.trend.widgetImg,
|
|
661
|
-
apsChangeRate = pocGlucose.trend.apsChangeRate
|
|
662
|
-
),
|
|
663
|
-
glucoseStatusObject = com.mytatvarnsdk.model.GlucoseStatusObject(
|
|
664
|
-
statusId = pocGlucose.glucoseStatus.statusId
|
|
665
|
-
),
|
|
666
|
-
errorObject = com.mytatvarnsdk.model.ErrorObject(
|
|
667
|
-
errorId = pocGlucose.errorCode.errorId,
|
|
668
|
-
sound = pocGlucose.errorCode.sound
|
|
669
|
-
)
|
|
670
|
-
)
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
if (transformedLogs.isEmpty()) {
|
|
674
|
-
Log.d("Batch Upload", "Batch $index skipped - no valid glucose readings")
|
|
675
|
-
continue
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
val allResult = AllCGMLogRequest(vendor = "GoodFlip", logs = transformedLogs)
|
|
679
|
-
val json = Gson().toJson(allResult)
|
|
680
|
-
|
|
681
|
-
Log.d("Batch Upload JSON", "Batch $index with ${transformedLogs.size} records")
|
|
682
|
-
logLongJson("Batch $index JSON=>>> ", json)
|
|
683
|
-
|
|
684
|
-
val uploadSuccessful = uploadBatchSynchronously(json, index)
|
|
685
|
-
|
|
686
|
-
if (uploadSuccessful) {
|
|
687
|
-
lastSyncedRecord = batch.lastOrNull()
|
|
688
|
-
updateSyncMetadata(lastSyncedRecord)
|
|
689
|
-
Log.d("Batch Upload", "✅ Batch $index uploaded successfully")
|
|
690
|
-
} else {
|
|
691
|
-
allBatchesSuccessful = false
|
|
692
|
-
Log.e("Batch Upload", "❌ Batch $index failed, stopping further uploads")
|
|
693
|
-
break
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
delay(500L) // Rate limiting between batches
|
|
697
|
-
|
|
698
|
-
} catch (e: Exception) {
|
|
699
|
-
Log.e("Batch Upload", "❌ Batch $index exception: ${e.message}")
|
|
700
|
-
allBatchesSuccessful = false
|
|
701
|
-
break
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
// Handle last synced record error status
|
|
706
|
-
lastSyncedRecord?.let { record ->
|
|
707
|
-
if (record.errorCode != enumError.NONE) {
|
|
708
|
-
handleGlucoseError(record)
|
|
709
|
-
}
|
|
481
|
+
val glucoseData = mModel.getGlucoseBetweenTime(lastSyncData.lastSyncTime)
|
|
482
|
+
if (glucoseData != null && glucoseData.isNotEmpty()) {
|
|
483
|
+
// Process batch data and wait for completion
|
|
484
|
+
processBatchDataAndStartObserver(glucoseData)
|
|
485
|
+
} else {
|
|
486
|
+
Log.d("observeAllGlucoseData", "No historical data found, starting live observation")
|
|
487
|
+
// Start live observation immediately if no historical data
|
|
488
|
+
Handler(Looper.getMainLooper()).post {
|
|
489
|
+
observeGlucoseData(userToken)
|
|
710
490
|
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
} else {
|
|
494
|
+
// No sync data exists, start live observation
|
|
495
|
+
observeGlucoseData(userToken)
|
|
496
|
+
}
|
|
497
|
+
} catch (e: Exception) {
|
|
498
|
+
Log.e("observeAllGlucoseData", "observeAllGlucoseData Error: ${e.message}")
|
|
499
|
+
// Fallback to live observation on error
|
|
500
|
+
observeGlucoseData(userToken)
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// New method to handle batch processing and ensure proper sequencing
|
|
505
|
+
private suspend fun processBatchDataAndStartObserver(dataList: List<PocGlucose>) {
|
|
506
|
+
try {
|
|
507
|
+
// Process all batches
|
|
508
|
+
val success = processBatchDataSynchronously(dataList)
|
|
509
|
+
|
|
510
|
+
// Only start live observer after batch processing is completely done
|
|
511
|
+
if (success) {
|
|
512
|
+
Log.d(
|
|
513
|
+
"processBatchDataAndStartObserver",
|
|
514
|
+
"Batch processing completed successfully, starting live observer"
|
|
515
|
+
)
|
|
516
|
+
} else {
|
|
517
|
+
Log.w(
|
|
518
|
+
"processBatchDataAndStartObserver",
|
|
519
|
+
"Batch processing had failures, still starting live observer"
|
|
520
|
+
)
|
|
521
|
+
}
|
|
711
522
|
|
|
712
|
-
|
|
523
|
+
// Start live observation on main thread after batch completion
|
|
524
|
+
Handler(Looper.getMainLooper()).post {
|
|
525
|
+
if (!isObserving) {
|
|
526
|
+
observeGlucoseData(userToken)
|
|
527
|
+
}
|
|
528
|
+
}
|
|
713
529
|
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
530
|
+
} catch (e: Exception) {
|
|
531
|
+
Log.e("processBatchDataAndStartObserver", "Error in batch processing: ${e.message}")
|
|
532
|
+
// Start live observation even on error
|
|
533
|
+
Handler(Looper.getMainLooper()).post {
|
|
534
|
+
if (!isObserving) {
|
|
535
|
+
observeGlucoseData(userToken)
|
|
718
536
|
}
|
|
537
|
+
}
|
|
719
538
|
}
|
|
539
|
+
}
|
|
720
540
|
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
environment = if ("uat".uppercase() == "PROD") TATVA_ENVIRONMENT.PROD else TATVA_ENVIRONMENT.STAGE,
|
|
727
|
-
data = json,
|
|
728
|
-
token = userToken,
|
|
729
|
-
responseListener = object : AuthenticateSDKService.ResponseListener {
|
|
730
|
-
override fun onResponseSuccess(response: String) {
|
|
731
|
-
continuation.resume(true)
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
override fun onResponseFail() {
|
|
735
|
-
continuation.resume(false)
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
)
|
|
739
|
-
} catch (e: Exception) {
|
|
740
|
-
Log.e("uploadBatchSynchronously", "Exception in batch $batchIndex: ${e.message}")
|
|
741
|
-
continuation.resume(false)
|
|
742
|
-
}
|
|
743
|
-
}
|
|
541
|
+
// Updated batch processing method with better sync control
|
|
542
|
+
private suspend fun processBatchDataSynchronously(dataList: List<PocGlucose>): Boolean {
|
|
543
|
+
if (dataList.isEmpty()) {
|
|
544
|
+
Log.d("processBatchDataSynchronously", "No data to upload")
|
|
545
|
+
return true
|
|
744
546
|
}
|
|
745
547
|
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
548
|
+
val batchSize = 40
|
|
549
|
+
val chunks = dataList.chunked(batchSize)
|
|
550
|
+
var lastSyncedRecord: PocGlucose? = null
|
|
551
|
+
var allBatchesSuccessful = true
|
|
552
|
+
|
|
553
|
+
Log.d("processBatchDataSynchronously", "Starting batch upload with ${chunks.size} batches")
|
|
554
|
+
|
|
555
|
+
for ((index, batch) in chunks.withIndex()) {
|
|
556
|
+
try {
|
|
557
|
+
val transformedLogs = batch.filter { it.showGlucoseMG > 0 }.map { pocGlucose ->
|
|
558
|
+
CgmLog(
|
|
559
|
+
timeInMillis = pocGlucose.timeInMillis,
|
|
560
|
+
countdownMinutes = pocGlucose.countdownMinutes,
|
|
561
|
+
countdownDays = pocGlucose.countdownDays,
|
|
562
|
+
hypoglycemiaEarlyWarnMinutes = pocGlucose.hypoglycemiaEarlyWarnMinutes,
|
|
563
|
+
showGlucoseMG = pocGlucose.showGlucoseMG,
|
|
564
|
+
glucoseId = pocGlucose.glucoseId,
|
|
565
|
+
name = pocGlucose.name,
|
|
566
|
+
bytes = pocGlucose.bytes,
|
|
567
|
+
showGlucose = pocGlucose.showGlucose,
|
|
568
|
+
Ib = pocGlucose.ib,
|
|
569
|
+
Iw = pocGlucose.iw,
|
|
570
|
+
countdownHours = pocGlucose.countdownHours,
|
|
571
|
+
T = pocGlucose.t,
|
|
572
|
+
year = pocGlucose.year,
|
|
573
|
+
month = pocGlucose.month,
|
|
574
|
+
day = pocGlucose.day,
|
|
575
|
+
hour = pocGlucose.hour,
|
|
576
|
+
minute = pocGlucose.minute,
|
|
577
|
+
trendObject = com.mytatvarnsdk.model.TrendObject(
|
|
578
|
+
trendId = pocGlucose.trend.trendId,
|
|
579
|
+
drawableId = pocGlucose.trend.drawableId,
|
|
580
|
+
widgetImg = pocGlucose.trend.widgetImg,
|
|
581
|
+
apsChangeRate = pocGlucose.trend.apsChangeRate
|
|
582
|
+
),
|
|
583
|
+
glucoseStatusObject = com.mytatvarnsdk.model.GlucoseStatusObject(
|
|
584
|
+
statusId = pocGlucose.glucoseStatus.statusId
|
|
585
|
+
),
|
|
586
|
+
errorObject = com.mytatvarnsdk.model.ErrorObject(
|
|
587
|
+
errorId = pocGlucose.errorCode.errorId,
|
|
588
|
+
sound = pocGlucose.errorCode.sound
|
|
589
|
+
)
|
|
590
|
+
)
|
|
760
591
|
}
|
|
761
|
-
}
|
|
762
592
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
593
|
+
if (transformedLogs.isEmpty()) {
|
|
594
|
+
Log.d("processBatchDataSynchronously", "Batch $index skipped - no valid glucose readings")
|
|
595
|
+
continue
|
|
596
|
+
}
|
|
766
597
|
|
|
767
|
-
val
|
|
598
|
+
val allResult = AllCGMLogRequest(vendor = "GoodFlip", logs = transformedLogs)
|
|
599
|
+
val json = Gson().toJson(allResult)
|
|
768
600
|
|
|
769
|
-
|
|
601
|
+
Log.d("Batch Upload", "Processing batch $index with ${transformedLogs.size} records")
|
|
602
|
+
logLongJson("Batch $index JSON=>>> ", json)
|
|
770
603
|
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
for ((index, batch) in chunks.withIndex()) {
|
|
774
|
-
try {
|
|
775
|
-
val transformedLogs = batch.filter { it.showGlucoseMG > 0 }.map {
|
|
776
|
-
CgmLog(
|
|
777
|
-
timeInMillis = it.timeInMillis,
|
|
778
|
-
countdownMinutes = it.countdownMinutes,
|
|
779
|
-
countdownDays = it.countdownDays,
|
|
780
|
-
hypoglycemiaEarlyWarnMinutes = it.hypoglycemiaEarlyWarnMinutes,
|
|
781
|
-
showGlucoseMG = it.showGlucoseMG,
|
|
782
|
-
glucoseId = it.glucoseId,
|
|
783
|
-
name = it.name,
|
|
784
|
-
bytes = it.bytes,
|
|
785
|
-
showGlucose = it.showGlucose,
|
|
786
|
-
Ib = it.ib,
|
|
787
|
-
Iw = it.iw,
|
|
788
|
-
countdownHours = it.countdownHours,
|
|
789
|
-
T = it.t,
|
|
790
|
-
year = it.year,
|
|
791
|
-
month = it.month,
|
|
792
|
-
day = it.day,
|
|
793
|
-
hour = it.hour,
|
|
794
|
-
minute = it.minute,
|
|
795
|
-
trendObject = com.mytatvarnsdk.model.TrendObject(
|
|
796
|
-
trendId = it.trend.trendId,
|
|
797
|
-
drawableId = it.trend.drawableId,
|
|
798
|
-
widgetImg = it.trend.widgetImg,
|
|
799
|
-
apsChangeRate = it.trend.apsChangeRate
|
|
800
|
-
),
|
|
801
|
-
glucoseStatusObject = com.mytatvarnsdk.model.GlucoseStatusObject(
|
|
802
|
-
statusId = it.glucoseStatus.statusId
|
|
803
|
-
),
|
|
804
|
-
errorObject = com.mytatvarnsdk.model.ErrorObject(
|
|
805
|
-
errorId = it.errorCode.errorId,
|
|
806
|
-
sound = it.errorCode.sound
|
|
807
|
-
)
|
|
808
|
-
)
|
|
809
|
-
}
|
|
604
|
+
val uploadSuccessful = uploadBatchSynchronously(json, index)
|
|
810
605
|
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
environment = if ("uat".uppercase() == "PROD") TATVA_ENVIRONMENT.PROD else TATVA_ENVIRONMENT.STAGE,
|
|
823
|
-
data = json.toString(),
|
|
824
|
-
token = userToken,
|
|
825
|
-
responseListener = object : AuthenticateSDKService.ResponseListener {
|
|
826
|
-
override fun onResponseSuccess() {
|
|
827
|
-
lastSyncedRecord = batch.lastOrNull()
|
|
828
|
-
|
|
829
|
-
lastSyncedRecord?.let {
|
|
830
|
-
val syncData =
|
|
831
|
-
SyncMeta(
|
|
832
|
-
Date().time,
|
|
833
|
-
it.timeInMillis,
|
|
834
|
-
it.deviceId,
|
|
835
|
-
it.glucoseId
|
|
836
|
-
)
|
|
837
|
-
prefsHelper.lastSyncData = syncData
|
|
838
|
-
Log.d(
|
|
839
|
-
"lastSyncedRecord stored:--- ",
|
|
840
|
-
Gson().toJson(syncData).toString()
|
|
841
|
-
)
|
|
842
|
-
}
|
|
843
|
-
}
|
|
606
|
+
if (uploadSuccessful) {
|
|
607
|
+
lastSyncedRecord = batch.lastOrNull()
|
|
608
|
+
// Update sync metadata after each successful batch
|
|
609
|
+
updateSyncMetadata(lastSyncedRecord)
|
|
610
|
+
Log.d("Batch Upload", "✅ Batch $index uploaded and synced successfully")
|
|
611
|
+
} else {
|
|
612
|
+
allBatchesSuccessful = false
|
|
613
|
+
Log.e("Batch Upload", "❌ Batch $index failed")
|
|
614
|
+
// Continue with next batch instead of breaking (optional based on your needs)
|
|
615
|
+
// break
|
|
616
|
+
}
|
|
844
617
|
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
)
|
|
618
|
+
// Rate limiting between batches
|
|
619
|
+
delay(500L)
|
|
850
620
|
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
621
|
+
} catch (e: Exception) {
|
|
622
|
+
Log.e("Batch Upload", "❌ Batch $index exception: ${e.message}")
|
|
623
|
+
allBatchesSuccessful = false
|
|
624
|
+
// Continue processing other batches
|
|
625
|
+
}
|
|
626
|
+
}
|
|
857
627
|
|
|
628
|
+
// Handle error status for the last processed record
|
|
629
|
+
lastSyncedRecord?.let { record ->
|
|
630
|
+
if (record.errorCode != enumError.NONE) {
|
|
631
|
+
handleGlucoseError(record)
|
|
632
|
+
}
|
|
633
|
+
}
|
|
858
634
|
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
postEventDataToAPI(
|
|
866
|
-
it,
|
|
867
|
-
DeviceStatus.MOISTURE_DETECT.id
|
|
868
|
-
)
|
|
869
|
-
}
|
|
870
|
-
resetDebounceTimer()
|
|
871
|
-
} else if (lastSyncedRecord?.errorCode == enumError.ERROR_CURRENT_SMALL || lastSyncedRecord?.errorCode == enumError.ERROR_NOISE || lastSyncedRecord?.errorCode == enumError.ERROR_SENSITIVITY_ATTENUATION) {
|
|
872
|
-
lastDeviceStatus =
|
|
873
|
-
lastSyncedRecord?.deviceId!!.toInt().let { mModel.getDeviceInfo(it) }
|
|
874
|
-
lastDeviceStatus?.let {
|
|
875
|
-
postEventDataToAPI(
|
|
876
|
-
it,
|
|
877
|
-
DeviceStatus.WEAK_SIGNAL.id
|
|
878
|
-
)
|
|
879
|
-
}
|
|
880
|
-
resetDebounceTimer()
|
|
881
|
-
} else {
|
|
882
|
-
lastDeviceStatus =
|
|
883
|
-
lastSyncedRecord?.deviceId!!.toInt().let { mModel.getDeviceInfo(it) }
|
|
884
|
-
lastDeviceStatus?.let {
|
|
885
|
-
postEventDataToAPI(
|
|
886
|
-
it,
|
|
887
|
-
DeviceStatus.ERROR_COMMON.id
|
|
888
|
-
)
|
|
889
|
-
}
|
|
890
|
-
resetDebounceTimer()
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
}
|
|
635
|
+
Log.d(
|
|
636
|
+
"processBatchDataSynchronously",
|
|
637
|
+
"Batch processing completed. Overall success: $allBatchesSuccessful"
|
|
638
|
+
)
|
|
639
|
+
return allBatchesSuccessful
|
|
640
|
+
}
|
|
894
641
|
|
|
895
|
-
Log.e("Batch Upload", "All data uploaded")
|
|
896
642
|
|
|
897
|
-
|
|
643
|
+
@ReactMethod
|
|
644
|
+
fun stopObservingGlucoseData() {
|
|
645
|
+
try {
|
|
646
|
+
glucoseObserver?.let { observer ->
|
|
647
|
+
Handler(Looper.getMainLooper()).post {
|
|
648
|
+
try {
|
|
649
|
+
mModel.latestGlucose.removeObserver(observer)
|
|
650
|
+
isObserving = false
|
|
651
|
+
Log.d("stopObservingGlucoseData", "Observer removed successfully")
|
|
652
|
+
} catch (e: Exception) {
|
|
653
|
+
Log.e("stopObservingGlucoseData", "Error removing observer: ${e.message}")
|
|
654
|
+
}
|
|
898
655
|
}
|
|
899
|
-
} else {
|
|
900
|
-
observeGlucoseData(userToken)
|
|
901
656
|
}
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
val maxLogSize = 4000
|
|
906
|
-
for (i in 0..message.length / maxLogSize) {
|
|
907
|
-
val start = i * maxLogSize
|
|
908
|
-
val end = (i + 1) * maxLogSize
|
|
909
|
-
if (start < message.length) {
|
|
910
|
-
Log.d(tag, message.substring(start, minOf(end, message.length)))
|
|
911
|
-
}
|
|
912
|
-
}
|
|
657
|
+
glucoseObserver = null
|
|
658
|
+
} catch (e: Exception) {
|
|
659
|
+
Log.e("stopObservingGlucoseData", "Error stopping observer: ${e.message}")
|
|
913
660
|
}
|
|
661
|
+
}
|
|
914
662
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
}
|
|
663
|
+
// Helper method for synchronous batch upload
|
|
664
|
+
private suspend fun uploadBatchSynchronously(json: String, batchIndex: Int): Boolean {
|
|
665
|
+
return suspendCoroutine { continuation ->
|
|
666
|
+
try {
|
|
667
|
+
authenticateSDKService.postCGMData(
|
|
668
|
+
environment = if ("uat".uppercase() == "PROD") TATVA_ENVIRONMENT.PROD else TATVA_ENVIRONMENT.STAGE,
|
|
669
|
+
data = json,
|
|
670
|
+
token = userToken,
|
|
671
|
+
responseListener = object : AuthenticateSDKService.ResponseListener {
|
|
672
|
+
override fun onResponseSuccess(response: String) {
|
|
673
|
+
continuation.resume(true)
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
override fun onResponseFail() {
|
|
677
|
+
continuation.resume(false)
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
)
|
|
681
|
+
} catch (e: Exception) {
|
|
682
|
+
Log.e("uploadBatchSynchronously", "Exception in batch $batchIndex: ${e.message}")
|
|
683
|
+
continuation.resume(false)
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
}
|
|
940
687
|
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
dto.errorObject = errorObj
|
|
959
|
-
|
|
960
|
-
return dto
|
|
688
|
+
private fun updateSyncMetadata(lastRecord: PocGlucose?) {
|
|
689
|
+
lastRecord?.let {
|
|
690
|
+
try {
|
|
691
|
+
val syncData = SyncMeta(
|
|
692
|
+
Date().time,
|
|
693
|
+
it.timeInMillis,
|
|
694
|
+
it.deviceId,
|
|
695
|
+
it.glucoseId
|
|
696
|
+
)
|
|
697
|
+
prefsHelper.lastSyncData = syncData
|
|
698
|
+
Log.d(
|
|
699
|
+
"Sync Metadata",
|
|
700
|
+
"Sync metadata updated: glucoseId=${it.glucoseId}, time=${it.timeInMillis}"
|
|
701
|
+
)
|
|
702
|
+
} catch (e: Exception) {
|
|
703
|
+
Log.e("updateSyncMetadata", "Error updating sync metadata: ${e.message}")
|
|
704
|
+
}
|
|
961
705
|
}
|
|
706
|
+
}
|
|
962
707
|
|
|
963
708
|
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
709
|
+
fun logLongJson(tag: String, message: String) {
|
|
710
|
+
val maxLogSize = 4000
|
|
711
|
+
for (i in 0..message.length / maxLogSize) {
|
|
712
|
+
val start = i * maxLogSize
|
|
713
|
+
val end = (i + 1) * maxLogSize
|
|
714
|
+
if (start < message.length) {
|
|
715
|
+
Log.d(tag, message.substring(start, minOf(end, message.length)))
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
fun mapToDto(glucose: PocGlucose): GlucoseLog {
|
|
721
|
+
val dto: GlucoseLog = GlucoseLog()
|
|
722
|
+
dto.timeInMillis = glucose.getTimeInMillis()
|
|
723
|
+
dto.countdownMinutes = glucose.getCountdownMinutes()
|
|
724
|
+
dto.countdownHours = glucose.getCountdownHours()
|
|
725
|
+
dto.countdownDays = glucose.getCountdownDays()
|
|
726
|
+
dto.hypoglycemiaEarlyWarnMinutes = glucose.getHypoglycemiaEarlyWarnMinutes()
|
|
727
|
+
dto.showGlucoseMG = glucose.getShowGlucoseMG()
|
|
728
|
+
dto.glucoseId = glucose.getGlucoseId()
|
|
729
|
+
dto.name = glucose.getName()
|
|
730
|
+
dto.showGlucose = glucose.getShowGlucose()
|
|
731
|
+
dto.Ib = glucose.getIb()
|
|
732
|
+
dto.Iw = glucose.getIw()
|
|
733
|
+
dto.T = glucose.getT()
|
|
734
|
+
dto.year = glucose.getYear()
|
|
735
|
+
dto.month = glucose.getMonth()
|
|
736
|
+
dto.day = glucose.getDay()
|
|
737
|
+
dto.hour = glucose.getHour()
|
|
738
|
+
dto.minute = glucose.getMinute()
|
|
739
|
+
|
|
740
|
+
// Convert byte[] to List<Integer>
|
|
741
|
+
dto.bytes = ArrayList()
|
|
742
|
+
for (b in glucose.getBytes()) {
|
|
743
|
+
dto.bytes?.add(b.toInt() and 0xFF) // Prevent negative values
|
|
744
|
+
}
|
|
967
745
|
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
746
|
+
// Trend
|
|
747
|
+
val trendObj: TrendObject = TrendObject()
|
|
748
|
+
trendObj.trendId = glucose.getTrend().getTrendId()
|
|
749
|
+
trendObj.drawableId = glucose.getTrend().getDrawableId()
|
|
750
|
+
trendObj.widgetImg = glucose.getTrend().getWidgetImg()
|
|
751
|
+
trendObj.apsChangeRate = glucose.getTrend().getApsChangeRate()
|
|
752
|
+
dto.trendObject = trendObj
|
|
753
|
+
|
|
754
|
+
// Status
|
|
755
|
+
val statusObj: GlucoseStatusObject = GlucoseStatusObject()
|
|
756
|
+
statusObj.statusId = glucose.getGlucoseStatus().getStatusId()
|
|
757
|
+
dto.glucoseStatusObject = statusObj
|
|
758
|
+
|
|
759
|
+
// Error
|
|
760
|
+
val errorObj: ErrorObject = ErrorObject()
|
|
761
|
+
errorObj.errorId = glucose.getErrorCode().getErrorId()
|
|
762
|
+
errorObj.sound = glucose.getErrorCode().getSound().toString()
|
|
763
|
+
dto.errorObject = errorObj
|
|
764
|
+
|
|
765
|
+
return dto
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
@ReactMethod
|
|
770
|
+
fun sendDataToReact(data: String, status: String, eventName: String) {
|
|
771
|
+
Log.d("sendDataToReact: data ", data)
|
|
772
|
+
|
|
773
|
+
try {
|
|
774
|
+
val map: WritableMap = Arguments.createMap().apply {
|
|
775
|
+
putString("data", data)
|
|
776
|
+
putString("status", status)
|
|
777
|
+
}
|
|
973
778
|
|
|
974
|
-
|
|
779
|
+
Log.d("sendDataToReact: ", map.toString())
|
|
975
780
|
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
}
|
|
781
|
+
mReactContext?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
782
|
+
?.emit(eventName, map)
|
|
783
|
+
} catch (e: Exception) {
|
|
784
|
+
Log.e("Error sendDataToReact: ", e.message.toString())
|
|
785
|
+
e.printStackTrace()
|
|
982
786
|
}
|
|
787
|
+
}
|
|
983
788
|
|
|
984
789
|
}
|
|
985
790
|
|