This commit is contained in:
jungsomyeonggithub 2023-06-01 19:23:31 +09:00
parent 757afdc4aa
commit c07a155424
16 changed files with 88 additions and 135 deletions

View file

@ -2,9 +2,15 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity android:name=".ui.EopatchActivity" />
<activity android:name=".ui.AlarmHelperActivity" />
<activity android:name=".ui.DialogHelperActivity" />
<activity
android:name=".ui.EopatchActivity"
android:configChanges="orientation|layoutDirection|screenLayout|density|screenSize|smallestScreenSize"/>
<activity
android:name=".ui.AlarmHelperActivity"
android:configChanges="orientation|layoutDirection|screenLayout|density|screenSize|smallestScreenSize"/>
<activity
android:name=".ui.DialogHelperActivity"
android:configChanges="orientation|layoutDirection|screenLayout|density|screenSize|smallestScreenSize"/>
<receiver android:name=".OsAlarmReceiver"/>
</application>

View file

@ -107,14 +107,18 @@ class EopatchPumpPlugin @Inject constructor(
alarmManager.init()
}) { throwable: Throwable -> fabricPrivacy.logException(throwable) }
)
}
// following was moved from specialEnableCondition()
// specialEnableCondition() is called too often to add there executive code
// This is a required code for maintaining the patch activation phase and maintaining the alarm. It should not be deleted.
override fun specialEnableCondition(): Boolean {
//BG -> FG, restart patch activation and trigger unhandled alarm
if (preferenceManager.isInitDone()) {
patchManager.checkActivationProcess()
alarmManager.restartAll()
}
return super.specialEnableCondition()
}
override fun onStop() {

View file

@ -1,77 +0,0 @@
package info.nightscout.androidaps.plugins.pump.eopatch;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import java.util.Objects;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
public class OsAlarmService extends Service {
public static final int FOREGROUND_NOTIFICATION_ID = 34534554;
private CompositeDisposable compositeDisposable;
private boolean foreground = false;
@Override
public void onCreate() {
super.onCreate();
compositeDisposable = new CompositeDisposable();
startForeground();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground();
String action = null;
if (action == null) {
return Service.START_NOT_STICKY;
}
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
((NotificationManager) Objects.requireNonNull(getSystemService(Context.NOTIFICATION_SERVICE))).cancel(FOREGROUND_NOTIFICATION_ID);
compositeDisposable.dispose();
}
public synchronized void startForeground() {
if (!foreground) {
foreground = true;
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
public static void start(Context context) {
Intent intent = new Intent(context, OsAlarmService.class);
// context.startForegroundService(intent);
}
public static void notifyNotification(Context context, boolean isNetworkAvailable) {
notifyNotification(context);
}
public static void notifyNotification(Context context) {
// Notification builder = getNotification(context);
// ((NotificationManager) Objects.requireNonNull(context.getSystemService(Context.NOTIFICATION_SERVICE))).notify(FOREGROUND_NOTIFICATION_ID, builder);
}
}

View file

@ -14,6 +14,7 @@ import info.nightscout.androidaps.plugins.pump.eopatch.ble.IPatchManager
import info.nightscout.androidaps.plugins.pump.eopatch.ble.IPreferenceManager
import info.nightscout.androidaps.plugins.pump.eopatch.code.AlarmCategory
import info.nightscout.androidaps.plugins.pump.eopatch.event.EventEoPatchAlarm
import info.nightscout.androidaps.plugins.pump.eopatch.extension.takeOne
import info.nightscout.androidaps.plugins.pump.eopatch.ui.AlarmHelperActivity
import info.nightscout.androidaps.plugins.pump.eopatch.vo.Alarms
import info.nightscout.core.utils.fabric.FabricPrivacy
@ -160,10 +161,11 @@ class AlarmManager @Inject constructor() : IAlarmManager {
id = Notification.EOELOW_PATCH_ALERTS + (alarmCode.aeCode + 10000),
text = alarmMsg,
level = Notification.URGENT,
buttonText = R.string.confirm,
buttonText = (alarmCode == B001).takeOne(R.string.string_resume, R.string.confirm),
action = {
compositeDisposable.add(
Single.just(isValid(alarmCode))
.observeOn(aapsSchedulers.main) //don't remove
.flatMap { isValid ->
return@flatMap if (isValid) mAlarmProcess.doAction(context, alarmCode)
else Single.just(IAlarmProcess.ALARM_HANDLED)
@ -179,18 +181,17 @@ class AlarmManager @Inject constructor() : IAlarmManager {
)
}
updateState(alarmCode, AlarmState.HANDLE)
}else if(ret == IAlarmProcess.ALARM_HANDLED_BUT_NEED_STOP_BEEP){
pm.getAlarms().needToStopBeep.add(alarmCode)
updateState(alarmCode, AlarmState.HANDLE)
} else {
uiInteraction.addNotification(
id = Notification.EOELOW_PATCH_ALERTS + (alarmCode.aeCode + 10000),
text = alarmMsg,
level = Notification.URGENT
)
showNotification(alarmCode)
}
}
)
},
soundId = info.nightscout.core.ui.R.raw.error,
date = pm.getPatchConfig().patchWakeupTimestamp + TimeUnit.SECONDS.toMillis(timeOffset)
date = pm.getAlarms().getOccuredAlarmTimestamp(alarmCode)
)
}

View file

@ -35,6 +35,7 @@ import info.nightscout.androidaps.plugins.pump.eopatch.alarm.AlarmCode.B012
import info.nightscout.androidaps.plugins.pump.eopatch.alarm.AlarmCode.B018
import info.nightscout.androidaps.plugins.pump.eopatch.ble.IPatchManager
import info.nightscout.androidaps.plugins.pump.eopatch.core.response.BaseResponse
import info.nightscout.androidaps.plugins.pump.eopatch.core.response.PatchBooleanResponse
import info.nightscout.androidaps.plugins.pump.eopatch.core.response.TemperatureResponse
import info.nightscout.androidaps.plugins.pump.eopatch.event.EventDialog
import info.nightscout.androidaps.plugins.pump.eopatch.event.EventProgressDialog
@ -55,6 +56,7 @@ interface IAlarmProcess {
const val ALARM_UNHANDLED = 0
const val ALARM_PAUSE = 1
const val ALARM_HANDLED = 2
const val ALARM_HANDLED_BUT_NEED_STOP_BEEP = 3
}
}
@ -68,14 +70,14 @@ class AlarmProcess(val patchManager: IPatchManager, val rxBus: RxBus) : IAlarmPr
A117, A118 -> patchDeactivationAction(context)
A007 -> inappropriateTemperatureAction(context)
A016 -> needleInsertionErrorAction(context)
B000, B003, B018 -> Single.just(IAlarmProcess.ALARM_HANDLED)
B005, B006 -> Single.just(IAlarmProcess.ALARM_HANDLED)
B000 -> Single.just(IAlarmProcess.ALARM_HANDLED)
B003, B005, B006, B018 -> stopAeBeepAction(context, code)
B012 -> Single.just(IAlarmProcess.ALARM_HANDLED)
}
}
private fun startActivityWithSingleTop(context: Context, intent: Intent) {
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
context.startActivity(intent)
}
@ -104,7 +106,7 @@ class AlarmProcess(val patchManager: IPatchManager, val rxBus: RxBus) : IAlarmPr
Single.fromCallable {
showCommunicationFailedDialog {
startActivityWithSingleTop(context,
createIntentForCheckConnection(context, goHomeAfterDiscard = true, forceDiscard = true))
createIntentForCheckConnection(context, goHomeAfterDiscard = true, forceDiscard = true, isAlarmHandling = true))
}
IAlarmProcess.ALARM_PAUSE
}
@ -115,6 +117,7 @@ class AlarmProcess(val patchManager: IPatchManager, val rxBus: RxBus) : IAlarmPr
return actionWithPatchCheckConnection(context) {
patchManager.resumeBasal()
.map { obj: BaseResponse -> obj.isSuccess }
.onErrorReturn { false }
.flatMap { Single.just(it.takeOne(IAlarmProcess.ALARM_HANDLED, IAlarmProcess.ALARM_UNHANDLED)) }
}
}
@ -148,4 +151,15 @@ class AlarmProcess(val patchManager: IPatchManager, val rxBus: RxBus) : IAlarmPr
.defaultIfEmpty(IAlarmProcess.ALARM_UNHANDLED)
}
}
private fun stopAeBeepAction(context: Context, alarm: AlarmCode): Single<Int> {
if (patchManager.patchConnectionState.isConnected) {
return patchManager.stopAeBeep(alarm.aeCode)
.map { obj: PatchBooleanResponse -> obj.isSuccess }
.onErrorReturn { false }
.flatMap { Single.just(it.takeOne(IAlarmProcess.ALARM_HANDLED, IAlarmProcess.ALARM_HANDLED_BUT_NEED_STOP_BEEP)) }
}else{
return Single.just(IAlarmProcess.ALARM_HANDLED_BUT_NEED_STOP_BEEP)
}
}
}

View file

@ -17,6 +17,7 @@ import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventDismissNotification
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.utils.DateUtil
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.disposables.CompositeDisposable
@ -120,6 +121,7 @@ class AlarmRegistry @Inject constructor() : IAlarmRegistry {
return Maybe.fromCallable {
cancelOsAlarmInternal(alarmCode)
val pendingIntent = createPendingIntent(alarmCode, 0)
aapsLogger.debug("[${alarmCode}] OS Alarm added. ${DateUtil(mContext).toISOString(triggerTime)}")
mOsAlarmManager.setAlarmClock(AlarmClockInfo(triggerTime, pendingIntent), pendingIntent)
alarmCode
}

View file

@ -192,7 +192,6 @@ public class PatchManagerImpl {
.filter(it -> patch.getConnectionState().isConnected())
.concatMapIterable(EventEoPatchAlarm::getAlarmCodes)
.filter(AlarmCode::isPatchOccurrenceAlert)
.flatMap(it -> stopAeBeep(it.getAeCode()).toObservable())
.subscribe()
);
@ -250,6 +249,16 @@ public class PatchManagerImpl {
}
return Single.just(true);
})
.flatMap(ret -> {
if(!pm.getAlarms().getNeedToStopBeep().isEmpty()) {
return Observable.fromStream(pm.getAlarms().getNeedToStopBeep().stream())
.flatMapSingle(alarmCode -> stopAeBeep(alarmCode.getAeCode()).doOnSuccess(patchBooleanResponse -> {
pm.getAlarms().getNeedToStopBeep().remove(alarmCode);
}))
.lastOrError();
}
return Single.just(true);
})
.subscribe());
}

View file

@ -36,11 +36,10 @@ public class StartBondTask extends TaskBase {
})
.filter(result -> result == BluetoothDevice.BOND_BONDED)
.map(result -> true)
.timeout(60, TimeUnit.SECONDS)
.timeout(35, TimeUnit.SECONDS)
.doOnNext(v -> prefSetMacAddress(mac))
.doOnError(e -> {
prefSetMacAddress("");
aapsLogger.error(LTag.PUMPCOMM, (e.getMessage() != null) ? e.getMessage() : "StartBondTask error");
})
.firstOrError();
}

View file

@ -30,6 +30,8 @@ public class StopBasalTask extends TaskBase {
@Inject PumpSync pumpSync;
@Inject UserEntryLogger uel;
@Inject UpdateConnectionTask updateConnectionTask;
private final BasalStop BASAL_STOP;
private final BehaviorSubject<Boolean> bolusCheckSubject = BehaviorSubject.create();
private final BehaviorSubject<Boolean> exbolusCheckSubject = BehaviorSubject.create();
@ -93,15 +95,11 @@ public class StopBasalTask extends TaskBase {
.flatMap(v -> isReady())
.concatMapSingle(v -> BASAL_STOP.stop())
.doOnNext(this::checkResponse)
.doOnNext(v -> updateConnectionTask.enqueue())
.firstOrError()
.doOnSuccess(this::onBasalStopped)
.doOnError(e -> aapsLogger.error(LTag.PUMPCOMM, (e.getMessage() != null) ? e.getMessage() : "StopBasalTask error"));
}
private void onBasalStopped(BasalStopResponse response) {
enqueue(TaskFunc.UPDATE_CONNECTION);
}
public synchronized void enqueue() {
boolean ready = (disposable == null || disposable.isDisposed());

View file

@ -4,8 +4,6 @@ import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.media.MediaPlayer
import android.media.RingtoneManager
import android.os.Bundle
import android.view.MotionEvent
import androidx.appcompat.app.AlertDialog
@ -22,8 +20,6 @@ import info.nightscout.androidaps.plugins.pump.eopatch.ui.viewmodel.EopatchViewM
import info.nightscout.core.utils.extensions.safeGetSerializableExtra
class EopatchActivity : EoBaseActivity<ActivityEopatchBinding>() {
private var mediaPlayer: MediaPlayer? = null
private var mPatchCommCheckDialog: Dialog? = null
private var mProgressDialog: AlertDialog? = null
@ -81,26 +77,26 @@ class EopatchActivity : EoBaseActivity<ActivityEopatchBinding>() {
setResult(RESULT_DISCARDED)
if (intent.getBooleanExtra(EXTRA_GO_HOME, true)) {
backToHome(false)
backToHome()
} else {
this@EopatchActivity.finish()
}
})
}
PatchStep.COMPLETE -> backToHome(true)
PatchStep.COMPLETE -> backToHome()
PatchStep.FINISH -> {
if (!intent.getBooleanExtra(EXTRA_START_FROM_MENU, false)
|| intent.getBooleanExtra(EXTRA_GO_HOME, true)
) {
backToHome(false)
backToHome()
} else {
this@EopatchActivity.finish()
}
}
PatchStep.BACK_TO_HOME -> backToHome(false)
PatchStep.BACK_TO_HOME -> backToHome()
PatchStep.CANCEL -> this@EopatchActivity.finish()
else -> Unit
}
@ -122,6 +118,7 @@ class EopatchActivity : EoBaseActivity<ActivityEopatchBinding>() {
val step = intent.safeGetSerializableExtra(EXTRA_START_PATCH_STEP, PatchStep::class.java)
forceDiscard = intent.getBooleanExtra(EXTRA_FORCE_DISCARD, false)
isInAlarmHandling = intent.getBooleanExtra(EXTRA_IS_ALARM_HANDLING, false)
if (intent.getBooleanExtra(EXTRA_START_WITH_COMM_CHECK, false)) {
checkCommunication({
initializePatchStep(step)
@ -220,6 +217,7 @@ class EopatchActivity : EoBaseActivity<ActivityEopatchBinding>() {
}
// EventType.SHOW_BONDED_DIALOG -> this@EopatchActivity.finish()
EventType.SHOW_DISCARD_DIALOG -> {
val cancelLabel = isInAlarmHandling.takeOne(null, getString(R.string.cancel))
info.nightscout.core.ui.dialogs.AlertDialogHelper.Builder(this@EopatchActivity).apply {
setTitle(R.string.string_discard_patch)
if (isBolusActive) {
@ -238,7 +236,7 @@ class EopatchActivity : EoBaseActivity<ActivityEopatchBinding>() {
}
}
}
setNegativeButton(R.string.cancel) { _, _ ->
setNegativeButton(cancelLabel) { _, _ ->
dismissProgressDialog()
updateIncompletePatchActivationReminder()
}
@ -272,29 +270,10 @@ class EopatchActivity : EoBaseActivity<ActivityEopatchBinding>() {
}
}
private fun backToHome(isActivated: Boolean) {
if (isActivated) {
mediaPlayer = MediaPlayer.create(this, RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))?.apply {
setOnCompletionListener {
this@EopatchActivity.finish()
}
start()
}
}
private fun backToHome() {
this@EopatchActivity.finish()
}
override fun onDestroy() {
super.onDestroy()
mediaPlayer?.let {
it.stop()
it.release()
mediaPlayer = null
}
}
override fun onBackPressed() {
binding.viewModel?.apply{
when(patchStep.value){
@ -311,16 +290,18 @@ class EopatchActivity : EoBaseActivity<ActivityEopatchBinding>() {
const val EXTRA_START_WITH_COMM_CHECK = "EXTRA_START_WITH_COMM_CHECK"
const val EXTRA_GO_HOME = "EXTRA_GO_HOME"
const val EXTRA_FORCE_DISCARD = "EXTRA_FORCE_DISCARD"
const val EXTRA_IS_ALARM_HANDLING = "EXTRA_IS_ALARM_HANDLING"
const val NORMAL_TEMPERATURE_MIN = 4
const val NORMAL_TEMPERATURE_MAX = 45
@JvmStatic
@JvmOverloads
fun createIntentForCheckConnection(context: Context, goHomeAfterDiscard: Boolean = true, forceDiscard: Boolean = false): Intent {
fun createIntentForCheckConnection(context: Context, goHomeAfterDiscard: Boolean = true, forceDiscard: Boolean = false, isAlarmHandling: Boolean = false): Intent {
return Intent(context, EopatchActivity::class.java).apply {
putExtra(EXTRA_START_PATCH_STEP, PatchStep.CHECK_CONNECTION)
putExtra(EXTRA_GO_HOME, goHomeAfterDiscard)
putExtra(EXTRA_FORCE_DISCARD, forceDiscard)
putExtra(EXTRA_IS_ALARM_HANDLING, isAlarmHandling)
}
}

View file

@ -14,6 +14,7 @@ import info.nightscout.androidaps.plugins.pump.eopatch.alarm.AlarmProcess
import info.nightscout.androidaps.plugins.pump.eopatch.alarm.IAlarmProcess
import info.nightscout.androidaps.plugins.pump.eopatch.bindingadapters.setOnSafeClickListener
import info.nightscout.androidaps.plugins.pump.eopatch.ble.IPatchManager
import info.nightscout.androidaps.plugins.pump.eopatch.ble.IPreferenceManager
import info.nightscout.androidaps.plugins.pump.eopatch.databinding.DialogAlarmBinding
import info.nightscout.androidaps.plugins.pump.eopatch.ui.AlarmHelperActivity
import info.nightscout.core.ui.R
@ -32,6 +33,7 @@ class AlarmDialog : DaggerDialogFragment() {
@Inject lateinit var patchManager: IPatchManager
@Inject lateinit var rxBus: RxBus
@Inject lateinit var aapsSchedulers: AapsSchedulers
@Inject lateinit var pm: IPreferenceManager
var helperActivity: AlarmHelperActivity? = null
var alarmCode: AlarmCode? = null
@ -84,7 +86,10 @@ class AlarmDialog : DaggerDialogFragment() {
.subscribeOn(aapsSchedulers.io)
.subscribe ({ ret ->
aapsLogger.debug("Alarm processing result :${ret}")
if (ret == IAlarmProcess.ALARM_HANDLED) {
if (ret == IAlarmProcess.ALARM_HANDLED || ret == IAlarmProcess.ALARM_HANDLED_BUT_NEED_STOP_BEEP) {
if(ret == IAlarmProcess.ALARM_HANDLED_BUT_NEED_STOP_BEEP){
pm.getAlarms().needToStopBeep.add(ac)
}
alarmCode?.let{
patchManager.preferenceManager.getAlarms().handle(it)
patchManager.preferenceManager.flushAlarms()

View file

@ -74,6 +74,7 @@ class EopatchViewModel @Inject constructor(
private const val MAX_ELAPSED_MILLIS_AFTER_EXPIRATION = -12L * 60 * 60 * 1000
}
var forceDiscard = false
var isInAlarmHandling = false
var connectionTryCnt = 0
val patchConfig: PatchConfig = patchManager.patchConfig
@ -312,6 +313,7 @@ class EopatchViewModel @Inject constructor(
CommonUtils.dispose(mCommCheckDisposable)
updateIncompletePatchActivationReminder()
dismissPatchCommCheckDialogInternal(false)
connectionTryCnt = 0
}
@Synchronized

View file

@ -7,6 +7,7 @@ import info.nightscout.shared.sharedPreferences.SP
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.subjects.BehaviorSubject
import java.util.*
import kotlin.collections.HashSet
class Alarms: IPreference<Alarms> {
@Transient
@ -26,6 +27,8 @@ class Alarms: IPreference<Alarms> {
var occurred = HashMap<AlarmCode, AlarmItem>()
var needToStopBeep = HashSet<AlarmCode>()
init {
initObject()
}
@ -36,6 +39,7 @@ class Alarms: IPreference<Alarms> {
fun clear(){
registered.clear()
occurred.clear()
needToStopBeep.clear()
}
fun update(other: Alarms) {
@ -75,6 +79,13 @@ class Alarms: IPreference<Alarms> {
occurred.remove(alarmCode)
}
fun getOccuredAlarmTimestamp(alarmCode: AlarmCode): Long{
return if(occurred.containsKey(alarmCode))
occurred.getValue(alarmCode).triggerTimeMilli
else
System.currentTimeMillis()
}
private fun isRegistered(alarmCode: AlarmCode): Boolean{
return registered.containsKey(alarmCode)
}

View file

@ -144,8 +144,6 @@ class PatchConfig: IPreference<PatchConfig> {
this.standardBolusInjectCount = 0
this.extendedBolusInjectCount = 0
this.basalInjectCount = 0
this.lowReservoirAlertAmount = 10
this.patchExpireAlertTime = 4
this.remainedInsulin = 0f
}

View file

@ -4,13 +4,13 @@
<string name="eopatch_status">상태</string>
<string name="eopatch_base_basal_rate">기본 basal 양</string>
<string name="eopatch_temp_basal_rate">임시 basal 양</string>
<string name="eopatch_total_delivered">모두 주입됨</string>
<string name="eopatch_total_delivered">총 주입량</string>
<string name="symbol_day"></string>
<string name="patch_finish">종료</string>
<string name="patch_step_desc_1">1.</string>
<string name="patch_step_desc_2">2.</string>
<string name="symbol_days"></string>
<string name="string_resume">재실행</string>
<string name="string_resume">주입 재개</string>
<string name="string_suspend">중지</string>
<string name="string_suspended">중지됨</string>
<string name="string_running">실행중</string>