From 9a1262cc4ed7a02a74b301671f709a3f2c8c05b3 Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Tue, 13 Aug 2019 12:30:23 +0100 Subject: [PATCH] - refactoring to use OmnipodCommunicationManager with existing code - added kt for OmnipodFragment --- .../RileyLinkCommunicationManager.java | 8 +- .../plugins/pump/omnipod/OmnipodFragment.java | 514 ------------------ .../plugins/pump/omnipod/OmnipodFragment.kt | 312 +++++++++++ .../pump/omnipod/OmnipodPumpPlugin.java | 5 +- .../comm/OmnipodCommunicationManager.java | 17 + .../comm/OmnipodCommunicationService.java | 43 +- .../defs/schedule/BasalScheduleEntry.java | 3 +- .../events/EventOmnipodRefreshButtonState.kt | 5 + app/src/main/res/layout/omnipod_fragment.xml | 47 -- app/src/main/res/values/strings.xml | 4 +- 10 files changed, 370 insertions(+), 588 deletions(-) delete mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/events/EventOmnipodRefreshButtonState.kt diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkCommunicationManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkCommunicationManager.java index 52e1c5608c..6f67b275f5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkCommunicationManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkCommunicationManager.java @@ -61,23 +61,23 @@ public abstract class RileyLinkCommunicationManager { // All pump communications go through this function. - protected E sendAndListen(RLMessage msg, int timeout_ms, Class clazz) + public E sendAndListen(RLMessage msg, int timeout_ms, Class clazz) throws RileyLinkCommunicationException { return sendAndListen(msg, timeout_ms, null, clazz); } - protected E sendAndListen(RLMessage msg, int timeout_ms, Integer extendPreamble_ms, Class clazz) + public E sendAndListen(RLMessage msg, int timeout_ms, Integer extendPreamble_ms, Class clazz) throws RileyLinkCommunicationException { return sendAndListen(msg, timeout_ms, 0, extendPreamble_ms, clazz); } // For backward compatibility - protected E sendAndListen(RLMessage msg, int timeout_ms, int repeatCount, Integer extendPreamble_ms, Class clazz) + public E sendAndListen(RLMessage msg, int timeout_ms, int repeatCount, Integer extendPreamble_ms, Class clazz) throws RileyLinkCommunicationException { return sendAndListen(msg, timeout_ms, repeatCount, 0, extendPreamble_ms, clazz); } - protected E sendAndListen(RLMessage msg, int timeout_ms, int repeatCount, int retryCount, Integer extendPreamble_ms, Class clazz) + public E sendAndListen(RLMessage msg, int timeout_ms, int repeatCount, int retryCount, Integer extendPreamble_ms, Class clazz) throws RileyLinkCommunicationException { if (showPumpMessages) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.java deleted file mode 100644 index 343849729b..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.java +++ /dev/null @@ -1,514 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod; - -import android.app.Activity; -import android.content.Intent; -import android.graphics.Color; -import android.os.Bundle; -import android.os.Handler; -import android.text.Spanned; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.crashlytics.android.Crashlytics; -import com.joanzapata.iconify.widget.IconTextView; -import com.squareup.otto.Subscribe; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Date; - -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.OnClick; -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.events.EventExtendedBolusChange; -import info.nightscout.androidaps.events.EventPumpStatusChanged; -import info.nightscout.androidaps.events.EventTempBasalChange; -import info.nightscout.androidaps.logging.L; -import info.nightscout.androidaps.plugins.common.SubscriberFragment; -import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusActivity; -import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodDeviceStatusChange; -import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodPumpValuesChanged; -import info.nightscout.androidaps.plugins.pump.omnipod.service.OmnipodPumpStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil; -import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; -import info.nightscout.androidaps.queue.events.EventQueueChanged; -import info.nightscout.androidaps.utils.DateUtil; -import info.nightscout.androidaps.utils.DecimalFormatter; -import info.nightscout.androidaps.utils.SetWarnColor; - -/** - * Created by andy on 4.8.2019 - */ -public class OmnipodFragment extends SubscriberFragment { - - private static Logger LOG = LoggerFactory.getLogger(L.PUMP); - - @BindView(R.id.omnipod_lastconnection) - TextView lastConnectionView; - @BindView(R.id.omnipod_lastbolus) - TextView lastBolusView; - @BindView(R.id.omnipod_basabasalrate) - TextView basaBasalRateView; - - @BindView(R.id.omnipod_tempbasal) - TextView tempBasalView; - @BindView(R.id.omnipod_pumpstate_battery) - TextView batteryView; - @BindView(R.id.omnipod_rl_status) - IconTextView rileyLinkStatus; - @BindView(R.id.omnipod_reservoir) - TextView reservoirView; - @BindView(R.id.omnipod_errors) - TextView errorsView; - @BindView(R.id.omnipod_queue) - TextView queueView; - @BindView(R.id.overview_pumpstatuslayout_omnipod) - LinearLayout pumpStatusLayout; - @BindView(R.id.overview_pump_omnipod) - TextView overviewPumpOmnipodView; - @BindView(R.id.omnipod_pod_status) - IconTextView pumpStatusIconView; - @BindView(R.id.omnipod_refresh) - Button refreshButton; - private Handler loopHandler = new Handler(); - private static Activity localActivity; - - static Button refreshButtonStatic; - - private Runnable refreshLoop = new Runnable() { - - @Override - public void run() { - updateGUI(); - loopHandler.postDelayed(refreshLoop, 60 * 1000L); - } - }; - - - public OmnipodFragment() { - } - - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - loopHandler.postDelayed(refreshLoop, 60 * 1000L); - } - - - @Override - public void onDestroy() { - super.onDestroy(); - loopHandler.removeCallbacks(refreshLoop); - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - try { - View view = inflater.inflate(R.layout.omnipod_fragment, container, false); - unbinder = ButterKnife.bind(this, view); - - overviewPumpOmnipodView.setBackgroundColor(MainApp.sResources.getColor(R.color.colorInitializingBorder)); - - rileyLinkStatus.setText(getTranslation(RileyLinkServiceState.NotStarted.getResourceId(getTargetDevice()))); - rileyLinkStatus.setTextSize(14); - - pumpStatusIconView.setTextColor(Color.WHITE); - pumpStatusIconView.setTextSize(14); - pumpStatusIconView.setText("{fa-bed}"); - - refreshButtonStatic = refreshButton; - - return view; - } catch (Exception e) { - Crashlytics.logException(e); - } - - return null; - } - - - @OnClick(R.id.omnipod_pod_mgmt) - void onHistoryClick() { - // TODO -// if (MedtronicUtil.getPumpStatus().verifyConfiguration()) { -// startActivity(new Intent(getContext(), MedtronicHistoryActivity.class)); -// } else { -// MedtronicUtil.displayNotConfiguredDialog(getContext()); -// } - } - - - @OnClick(R.id.omnipod_refresh) - void onRefreshClick() { - // TODO -// if (!MedtronicUtil.getPumpStatus().verifyConfiguration()) { -// MedtronicUtil.displayNotConfiguredDialog(getContext()); -// return; -// } -// -// if (refreshButtonStatic != null) -// refreshButtonStatic.setEnabled(false); -// -// MedtronicPumpPlugin.getPlugin().resetStatusState(); -// -// ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("Clicked refresh", new Callback() { -// -// @Override -// public void run() { -// Activity activity = getActivity(); -// -// if (activity != null) { -// activity.runOnUiThread(() -> { -// if (refreshButtonStatic != null) -// refreshButtonStatic.setEnabled(true); -// }); -// } -// } -// }); - } - - - @OnClick(R.id.omnipod_stats) - void onStatsClick() { - if (OmnipodUtil.getPumpStatus().verifyConfiguration()) { - startActivity(new Intent(getContext(), RileyLinkStatusActivity.class)); - } else { - OmnipodUtil.displayNotConfiguredDialog(getContext()); - } - } - - - @Subscribe - public void onStatusEvent(final EventPumpStatusChanged c) { - updateGUI(); - } - - - public static void refreshButtonEnabled(boolean enable) { - if (localActivity != null) { - localActivity.runOnUiThread(() -> { - if (refreshButtonStatic != null) { - refreshButtonStatic.setEnabled(enable); - } - }); - } - } - - - public static Activity getCustomActivity() { - return localActivity; - } - - - @Subscribe - public void onStatusEvent(final EventOmnipodDeviceStatusChange eventStatusChange) { - if (isLogEnabled()) - LOG.info("onStatusEvent(EventOmnipodDeviceStatusChange): {}", eventStatusChange); - Activity activity = getActivity(); - - if (activity != null) { - localActivity = activity; - activity.runOnUiThread(() -> { - OmnipodPumpStatus pumpStatus = OmnipodUtil.getPumpStatus(); - setDeviceStatus(pumpStatus); - }); - } - } - - - private synchronized void setDeviceStatus(OmnipodPumpStatus pumpStatus) { - - pumpStatus.rileyLinkServiceState = (RileyLinkServiceState) checkStatusSet(pumpStatus.rileyLinkServiceState, - RileyLinkUtil.getServiceState()); - - if (pumpStatus.rileyLinkServiceState != null && rileyLinkStatus != null) { - - int resourceId = pumpStatus.rileyLinkServiceState.getResourceId(getTargetDevice()); - rileyLinkStatus.setTextColor(Color.WHITE); - rileyLinkStatus.setTextSize(14); - - if (pumpStatus.rileyLinkServiceState == RileyLinkServiceState.NotStarted) { - rileyLinkStatus.setText(getTranslation(resourceId)); - rileyLinkStatus.setTextSize(14); - } else if (pumpStatus.rileyLinkServiceState.isConnecting()) { - rileyLinkStatus.setText("{fa-bluetooth-b spin} " + getTranslation(resourceId)); - } else if (pumpStatus.rileyLinkServiceState.isError()) { - - RileyLinkError rileyLinkError = RileyLinkUtil.getError(); - - if (rileyLinkError == null) - rileyLinkStatus.setText("{fa-bluetooth-b} " + getTranslation(resourceId)); - else - rileyLinkStatus.setText("{fa-bluetooth-b} " - + getTranslation(rileyLinkError.getResourceId(RileyLinkTargetDevice.MedtronicPump))); - - rileyLinkStatus.setTextColor(Color.RED); - } else { - rileyLinkStatus.setText("{fa-bluetooth-b} " + getTranslation(resourceId)); - } - } - - pumpStatus.rileyLinkError = (RileyLinkError) checkStatusSet(pumpStatus.rileyLinkError, RileyLinkUtil.getError()); - - if (errorsView != null) { - if (pumpStatus.rileyLinkError != null) { - int resourceId = pumpStatus.rileyLinkError.getResourceId(getTargetDevice()); - errorsView.setText(getTranslation(resourceId)); - } else - errorsView.setText("-"); - } - -// pumpStatus.pumpDeviceState = (PumpDeviceState) checkStatusSet(pumpStatus.pumpDeviceState, -// MedtronicUtil.getPumpDeviceState()); -// - if (pumpStatusIconView != null) { -// -// if (pumpStatus.pumpDeviceState != null) { -// -// switch (pumpStatus.pumpDeviceState) { -// case Sleeping: -// pumpStatusIconView.setText("{fa-bed} "); // + pumpStatus.pumpDeviceState.name()); -// break; -// -// case NeverContacted: -// case WakingUp: -// case PumpUnreachable: -// case ErrorWhenCommunicating: -// case TimeoutWhenCommunicating: -// case InvalidConfiguration: -// pumpStatusIconView.setText(" " + getTranslation(pumpStatus.pumpDeviceState.getResourceId())); -// break; -// -// case Active: { -// MedtronicCommandType cmd = MedtronicUtil.getCurrentCommand(); -// -// LOG.debug("Command: " + cmd); -// -// if (cmd == null) -// pumpStatusIconView.setText(" " + MainApp.gs(pumpStatus.pumpDeviceState.getResourceId())); -// else { -// Integer resourceId = cmd.getResourceId(); -// -// if (cmd == MedtronicCommandType.GetHistoryData) { -// -// if (MedtronicUtil.frameNumber == null) { -// pumpStatusIconView.setText(MainApp.gs( -// R.string.medtronic_cmd_desc_get_history_request, MedtronicUtil.pageNumber)); -// } else { -// pumpStatusIconView.setText(MainApp.gs(resourceId, MedtronicUtil.pageNumber, -// MedtronicUtil.frameNumber)); -// } -// -// } else { -// if (resourceId == null) { -// pumpStatusIconView.setText(" " + cmd.getCommandDescription()); -// } else { -// pumpStatusIconView.setText(" " + getTranslation(resourceId)); -// } -// } -// -// } -// -// } -// break; -// -// default: -// LOG.warn("Unknown pump state: " + pumpStatus.pumpDeviceState); -// } -// } else { -// pumpStatusIconView.setText("{fa-bed} "); -// } - - // TODO - pumpStatusIconView.setText("{fa-bed} "); - } - - if (queueView != null) { - Spanned status = ConfigBuilderPlugin.getPlugin().getCommandQueue().spannedStatus(); - if (status.toString().equals("")) { - queueView.setVisibility(View.GONE); - } else { - queueView.setVisibility(View.VISIBLE); - queueView.setText(status); - } - } - - } - - - public Object checkStatusSet(Object object1, Object object2) { - if (object1 == null) { - return object2; - } else { - if (!object1.equals(object2)) { - return object2; - } else - return object1; - } - } - - - public RileyLinkTargetDevice getTargetDevice() { - return RileyLinkTargetDevice.Omnipod; - } - - - public String getTranslation(int resourceId) { - return MainApp.gs(resourceId); - } - - - @Subscribe - public void onStatusEvent(final EventOmnipodPumpValuesChanged s) { - if (isLogEnabled()) - LOG.debug("EventOmnipodPumpValuesChanged triggered"); - updateGUI(); - } - - - @Subscribe - public void onStatusEvent(final EventTempBasalChange s) { - updateGUI(); - } - - - @Subscribe - public void onStatusEvent(final EventExtendedBolusChange s) { - updateGUI(); - } - - - @Subscribe - public void onStatusEvent(final EventQueueChanged s) { - updateGUI(); - } - - - // GUI functions - @Override - protected void updateGUI() { - Activity activity = getActivity(); - if (activity != null && basaBasalRateView != null) - activity.runOnUiThread(() -> { - - if (lastConnectionView == null) // ui not yet initialized - return; - - localActivity = activity; - OmnipodPumpPlugin plugin = OmnipodPumpPlugin.getPlugin(); - OmnipodPumpStatus pumpStatus = OmnipodUtil.getPumpStatus(); - - setDeviceStatus(pumpStatus); - - // last connection - String minAgo = DateUtil.minAgo(pumpStatus.lastConnection); - long min = (System.currentTimeMillis() - pumpStatus.lastConnection) / 1000 / 60; - if (pumpStatus.lastConnection + 60 * 1000 > System.currentTimeMillis()) { - lastConnectionView.setText(R.string.combo_pump_connected_now); - lastConnectionView.setTextColor(Color.WHITE); - } else if (pumpStatus.lastConnection + 30 * 60 * 1000 < System.currentTimeMillis()) { - - if (min < 60) { - lastConnectionView.setText(MainApp.gs(R.string.minago, min)); - } else if (min < 1440) { - int h = (int) (min / 60); - - lastConnectionView.setText(MainApp.gq(R.plurals.objective_hours, h, h) + " " - + MainApp.gs(R.string.ago)); - } else { - - int h = (int) (min / 60); - int d = h / 24; - // h = h - (d * 24); - - lastConnectionView.setText(MainApp.gq(R.plurals.objective_days, d, d) + " " - + MainApp.gs(R.string.ago)); - } - lastConnectionView.setTextColor(Color.RED); - } else { - lastConnectionView.setText(minAgo); - lastConnectionView.setTextColor(Color.WHITE); - } - - // last bolus - Double bolus = pumpStatus.lastBolusAmount; - Date bolusTime = pumpStatus.lastBolusTime; - if (bolus != null && bolusTime != null) { - long agoMsc = System.currentTimeMillis() - pumpStatus.lastBolusTime.getTime(); - double bolusMinAgo = agoMsc / 60d / 1000d; - String unit = MainApp.gs(R.string.insulin_unit_shortname); - String ago; - if ((agoMsc < 60 * 1000)) { - ago = MainApp.gs(R.string.combo_pump_connected_now); - } else if (bolusMinAgo < 60) { - ago = DateUtil.minAgo(pumpStatus.lastBolusTime.getTime()); - } else { - ago = DateUtil.hourAgo(pumpStatus.lastBolusTime.getTime()); - } - lastBolusView.setText(MainApp.gs(R.string.combo_last_bolus, bolus, unit, ago)); - } else { - lastBolusView.setText(""); - } - - // base basal rate - basaBasalRateView.setText("(" + (pumpStatus.activeProfileName) + ") " - + MainApp.gs(R.string.pump_basebasalrate, plugin.getBaseBasalRate())); - - if (ConfigBuilderPlugin.getPlugin().getActivePump().isFakingTempsByExtendedBoluses()) { - if (TreatmentsPlugin.getPlugin().isInHistoryRealTempBasalInProgress()) { - tempBasalView.setText(TreatmentsPlugin.getPlugin() - .getRealTempBasalFromHistory(System.currentTimeMillis()).toStringFull()); - } else { - tempBasalView.setText(""); - } - } else { - // v2 plugin - if (TreatmentsPlugin.getPlugin().isTempBasalInProgress()) { - tempBasalView.setText(TreatmentsPlugin.getPlugin() - .getTempBasalFromHistory(System.currentTimeMillis()).toStringFull()); - } else { - tempBasalView.setText(""); - } - } - - // battery - // TODO this might need to be removed, I am not sure if pods have battery status - batteryView.setText("{fa-battery-" + (pumpStatus.batteryRemaining / 25) + "} "); -// if (MedtronicUtil.getBatteryType() == BatteryType.None || pumpStatus.batteryVoltage == null) { -// batteryView.setText("{fa-battery-" + (pumpStatus.batteryRemaining / 25) + "} "); -// } else { -// batteryView.setText("{fa-battery-" + (pumpStatus.batteryRemaining / 25) + "} " + pumpStatus.batteryRemaining + "%" + String.format(" (%.2f V)", pumpStatus.batteryVoltage)); -// } - SetWarnColor.setColorInverse(batteryView, pumpStatus.batteryRemaining, 25d, 10d); - - // reservoir - reservoirView.setText(DecimalFormatter.to0Decimal(pumpStatus.reservoirRemainingUnits) + " / " - + pumpStatus.reservoirFullUnits + " " + MainApp.gs(R.string.insulin_unit_shortname)); - SetWarnColor.setColorInverse(reservoirView, pumpStatus.reservoirRemainingUnits, 50d, 20d); - - errorsView.setText(pumpStatus.getErrorInfo()); - - }); - } - - - private boolean isLogEnabled() { - return L.isEnabled(L.PUMP); - } - - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt new file mode 100644 index 0000000000..88a3043b8d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt @@ -0,0 +1,312 @@ +package info.nightscout.androidaps.plugins.pump.omnipod + +import android.content.Intent +import android.graphics.Color +import android.os.Bundle +import android.os.Handler +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.squareup.otto.Subscribe +import info.nightscout.androidaps.MainApp +import info.nightscout.androidaps.R +import info.nightscout.androidaps.events.EventExtendedBolusChange +import info.nightscout.androidaps.events.EventPumpStatusChanged +import info.nightscout.androidaps.events.EventTempBasalChange +import info.nightscout.androidaps.logging.L +import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusActivity + +import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodDeviceStatusChange +import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodPumpValuesChanged +import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodRefreshButtonState +import info.nightscout.androidaps.plugins.pump.omnipod.service.OmnipodPumpStatus +import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil +import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin +import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.events.EventQueueChanged +import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.FabricPrivacy +import info.nightscout.androidaps.utils.SetWarnColor +import info.nightscout.androidaps.utils.T +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.disposables.Disposable +import kotlinx.android.synthetic.main.omnipod_fragment.* +import org.slf4j.LoggerFactory + + +class OmnipodFragment : Fragment() { + private val log = LoggerFactory.getLogger(L.PUMP) + private var disposable: CompositeDisposable = CompositeDisposable() + + operator fun CompositeDisposable.plusAssign(disposable: Disposable) { + add(disposable) + } + + private val loopHandler = Handler() + private lateinit var refreshLoop: Runnable + + init { + refreshLoop = Runnable { + activity?.runOnUiThread { updateGUI() } + loopHandler.postDelayed(refreshLoop, T.mins(1).msecs()) + } + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.omnipod_fragment, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + omnipod_pod_status.setBackgroundColor(MainApp.gc(R.color.colorInitializingBorder)) + + omnipod_rl_status.text = MainApp.gs(RileyLinkServiceState.NotStarted.getResourceId(RileyLinkTargetDevice.Omnipod)) + + omnipod_pod_status.setTextColor(Color.WHITE) + omnipod_pod_status.text = "{fa-bed}" + + omnipod_pod_mgmt.setOnClickListener { +// if (OmnipodUtil.getPumpStatus().verifyConfiguration()) { +// startActivity(Intent(context, MedtronicHistoryActivity::class.java)) +// } else { +// OmnipodUtil.displayNotConfiguredDialog(context) +// } + } + + omnipod_refresh.setOnClickListener { +// if (!OmnipodUtil.getPumpStatus().verifyConfiguration()) { +// OmnipodUtil.displayNotConfiguredDialog(context) +// } else { +// omnipod_refresh.isEnabled = false +// MedtronicPumpPlugin.getPlugin().resetStatusState() +// ConfigBuilderPlugin.getPlugin().commandQueue.readStatus("Clicked refresh", object : Callback() { +// override fun run() { +// activity?.runOnUiThread { omnipod_refresh.isEnabled = true } +// } +// }) +// } + } + + omnipod_stats.setOnClickListener { + if (OmnipodUtil.getPumpStatus().verifyConfiguration()) { + startActivity(Intent(context, RileyLinkStatusActivity::class.java)) + } else { + OmnipodUtil.displayNotConfiguredDialog(context) + } + } + + updateGUI() + } + + override fun onResume() { + super.onResume() + MainApp.bus().register(this) + loopHandler.postDelayed(refreshLoop, T.mins(1).msecs()) + disposable += RxBus + .toObservable(EventOmnipodRefreshButtonState::class.java) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ omnipod_refresh.isEnabled = it.newState }, { FabricPrivacy.logException(it) }) + disposable += RxBus + .toObservable(EventOmnipodDeviceStatusChange::class.java) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ + if (L.isEnabled(L.PUMP)) + log.info("onStatusEvent(EventOmnipodDeviceStatusChange): {}", it) + setDeviceStatus() + }, { FabricPrivacy.logException(it) }) + disposable += RxBus + .toObservable(EventOmnipodPumpValuesChanged::class.java) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ updateGUI() }, { FabricPrivacy.logException(it) }) + } + + + override fun onPause() { + super.onPause() + disposable.clear() + MainApp.bus().unregister(this) + loopHandler.removeCallbacks(refreshLoop) + } + + @Subscribe + fun onStatusEvent(c: EventPumpStatusChanged) { + activity?.runOnUiThread { updateGUI() } + } + + @Subscribe + fun onStatusEvent(s: EventTempBasalChange) { + activity?.runOnUiThread { updateGUI() } + } + + @Subscribe + fun onStatusEvent(s: EventExtendedBolusChange) { + activity?.runOnUiThread { updateGUI() } + } + + @Subscribe + fun onStatusEvent(s: EventQueueChanged) { + activity?.runOnUiThread { updateGUI() } + } + + @Synchronized + private fun setDeviceStatus() { + val pumpStatus: OmnipodPumpStatus = OmnipodUtil.getPumpStatus() + pumpStatus.rileyLinkServiceState = checkStatusSet(pumpStatus.rileyLinkServiceState, + RileyLinkUtil.getServiceState()) as RileyLinkServiceState? + + val resourceId = pumpStatus.rileyLinkServiceState.getResourceId(RileyLinkTargetDevice.MedtronicPump) + val rileyLinkError = RileyLinkUtil.getError() + omnipod_rl_status.text = + when { + pumpStatus.rileyLinkServiceState == RileyLinkServiceState.NotStarted -> MainApp.gs(resourceId) + pumpStatus.rileyLinkServiceState.isConnecting -> "{fa-bluetooth-b spin} " + MainApp.gs(resourceId) + pumpStatus.rileyLinkServiceState.isError && rileyLinkError == null -> "{fa-bluetooth-b} " + MainApp.gs(resourceId) + pumpStatus.rileyLinkServiceState.isError && rileyLinkError != null -> "{fa-bluetooth-b} " + MainApp.gs(rileyLinkError.getResourceId(RileyLinkTargetDevice.MedtronicPump)) + else -> "{fa-bluetooth-b} " + MainApp.gs(resourceId) + } + omnipod_rl_status.setTextColor(if (rileyLinkError != null) Color.RED else Color.WHITE) + + pumpStatus.rileyLinkError = checkStatusSet(pumpStatus.rileyLinkError, RileyLinkUtil.getError()) as RileyLinkError? + + omnipod_errors.text = + pumpStatus.rileyLinkError?.let { + MainApp.gs(it.getResourceId(RileyLinkTargetDevice.Omnipod)) + } ?: "-" + +// pumpStatus.pumpDeviceState = checkStatusSet(pumpStatus.pumpDeviceState, +// OmnipodUtil.getPumpDeviceState()) as PumpDeviceState? +// +// when (pumpStatus.pumpDeviceState) { +// null, +// PumpDeviceState.Sleeping -> omnipod_pod_status.text = "{fa-bed} " // + pumpStatus.pumpDeviceState.name()); +// PumpDeviceState.NeverContacted, +// PumpDeviceState.WakingUp, +// PumpDeviceState.PumpUnreachable, +// PumpDeviceState.ErrorWhenCommunicating, +// PumpDeviceState.TimeoutWhenCommunicating, +// PumpDeviceState.InvalidConfiguration -> omnipod_pod_status.text = " " + MainApp.gs(pumpStatus.pumpDeviceState.resourceId) +// PumpDeviceState.Active -> { +// val cmd = OmnipodUtil.getCurrentCommand() +// if (cmd == null) +// omnipod_pod_status.text = " " + MainApp.gs(pumpStatus.pumpDeviceState.resourceId) +// else { +// log.debug("Command: " + cmd) +// val cmdResourceId = cmd.resourceId +// if (cmd == MedtronicCommandType.GetHistoryData) { +// omnipod_pod_status.text = OmnipodUtil.frameNumber?.let { +// MainApp.gs(cmdResourceId, OmnipodUtil.pageNumber, OmnipodUtil.frameNumber) +// } +// ?: MainApp.gs(R.string.medtronic_cmd_desc_get_history_request, OmnipodUtil.pageNumber) +// } else { +// omnipod_pod_status.text = " " + (cmdResourceId?.let { MainApp.gs(it) } +// ?: cmd.getCommandDescription()) +// } +// } +// } +// else -> log.warn("Unknown pump state: " + pumpStatus.pumpDeviceState) +// } + + val status = ConfigBuilderPlugin.getPlugin().commandQueue.spannedStatus() + if (status.toString() == "") { + omnipod_queue.visibility = View.GONE + } else { + omnipod_queue.visibility = View.VISIBLE + omnipod_queue.text = status + } + } + + + private fun checkStatusSet(object1: Any?, object2: Any?): Any? { + return if (object1 == null) { + object2 + } else { + if (object1 != object2) { + object2 + } else + object1 + } + } + + // GUI functions + fun updateGUI() { + val plugin = OmnipodPumpPlugin.getPlugin() + val pumpStatus = OmnipodUtil.getPumpStatus() + + setDeviceStatus() + + // last connection + if (pumpStatus.lastConnection != 0L) { + val minAgo = DateUtil.minAgo(pumpStatus.lastConnection) + val min = (System.currentTimeMillis() - pumpStatus.lastConnection) / 1000 / 60 + if (pumpStatus.lastConnection + 60 * 1000 > System.currentTimeMillis()) { + omnipod_lastconnection.setText(R.string.combo_pump_connected_now) + omnipod_lastconnection.setTextColor(Color.WHITE) + } else if (pumpStatus.lastConnection + 30 * 60 * 1000 < System.currentTimeMillis()) { + + if (min < 60) { + omnipod_lastconnection.text = MainApp.gs(R.string.minago, min) + } else if (min < 1440) { + val h = (min / 60).toInt() + omnipod_lastconnection.text = (MainApp.gq(R.plurals.objective_hours, h, h) + " " + + MainApp.gs(R.string.ago)) + } else { + val h = (min / 60).toInt() + val d = h / 24 + // h = h - (d * 24); + omnipod_lastconnection.text = (MainApp.gq(R.plurals.objective_days, d, d) + " " + + MainApp.gs(R.string.ago)) + } + omnipod_lastconnection.setTextColor(Color.RED) + } else { + omnipod_lastconnection.text = minAgo + omnipod_lastconnection.setTextColor(Color.WHITE) + } + } + + // last bolus + val bolus = pumpStatus.lastBolusAmount + val bolusTime = pumpStatus.lastBolusTime + if (bolus != null && bolusTime != null) { + val agoMsc = System.currentTimeMillis() - pumpStatus.lastBolusTime.time + val bolusMinAgo = agoMsc.toDouble() / 60.0 / 1000.0 + val unit = MainApp.gs(R.string.insulin_unit_shortname) + val ago: String + if (agoMsc < 60 * 1000) { + ago = MainApp.gs(R.string.combo_pump_connected_now) + } else if (bolusMinAgo < 60) { + ago = DateUtil.minAgo(pumpStatus.lastBolusTime.time) + } else { + ago = DateUtil.hourAgo(pumpStatus.lastBolusTime.time) + } + omnipod_lastbolus.text = MainApp.gs(R.string.combo_last_bolus, bolus, unit, ago) + } else { + omnipod_lastbolus.text = "" + } + + // base basal rate + omnipod_basabasalrate.text = ("(" + pumpStatus.activeProfileName + ") " + + MainApp.gs(R.string.pump_basebasalrate, plugin.baseBasalRate)) + + omnipod_tempbasal.text = TreatmentsPlugin.getPlugin() + .getTempBasalFromHistory(System.currentTimeMillis())?.toStringFull() ?: "" + + // reservoir + if (RileyLinkUtil.isSame(pumpStatus.reservoirRemainingUnits, 0.0)) { + omnipod_reservoir.text = MainApp.gs(R.string.omnipod_reservoir_over50) + } else { + omnipod_reservoir.text = MainApp.gs(R.string.omnipod_reservoir_left, pumpStatus.reservoirRemainingUnits) + } + SetWarnColor.setColorInverse(omnipod_reservoir, pumpStatus.reservoirRemainingUnits, 50.0, 20.0) + + omnipod_errors.text = pumpStatus.errorInfo + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java index aadbb1ad58..7b699667c4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java @@ -33,6 +33,7 @@ import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction; import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType; import info.nightscout.androidaps.plugins.pump.common.PumpPluginAbstract; @@ -42,12 +43,14 @@ import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ResetRileyLinkConfigurationTask; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTaskExecutor; +import info.nightscout.androidaps.plugins.pump.medtronic.events.EventRefreshButtonState; import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; import info.nightscout.androidaps.plugins.pump.omnipod.comm.ui.OmnipodUIComm; import info.nightscout.androidaps.plugins.pump.omnipod.comm.ui.OmnipodUITask; import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommandType; import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCustomActionType; import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodPumpValuesChanged; +import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodRefreshButtonState; import info.nightscout.androidaps.plugins.pump.omnipod.service.OmnipodPumpStatus; import info.nightscout.androidaps.plugins.pump.omnipod.service.RileyLinkOmnipodService; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; @@ -306,7 +309,7 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements PumpInterfa private void setRefreshButtonEnabled(boolean enabled) { - OmnipodFragment.refreshButtonEnabled(enabled); + RxBus.INSTANCE.send(new EventOmnipodRefreshButtonState(enabled)); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodCommunicationManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodCommunicationManager.java index 41d8ff847e..d3d6e9ea42 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodCommunicationManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodCommunicationManager.java @@ -13,7 +13,10 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkCons import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RFSpy; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RLMessage; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RLMessageType; +import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodManager; +import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.PairAction; import info.nightscout.androidaps.plugins.pump.omnipod.comm.data.PodCommResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil; import info.nightscout.androidaps.utils.SP; @@ -26,6 +29,8 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager i private static OmnipodCommunicationManager omnipodCommunicationManager; String errorMessage; + OmnipodCommunicationService communicationService; + OmnipodManager omnipodManager; public OmnipodCommunicationManager(Context context, RFSpy rfspy) { @@ -33,9 +38,17 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager i omnipodCommunicationManager = this; OmnipodUtil.getPumpStatus().previousConnection = SP.getLong( RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L); + communicationService = new OmnipodCommunicationService(this); + omnipodManager = new OmnipodManager(communicationService, getPodSessionState()); } + private PodSessionState getPodSessionState() { + return null; + } + + + public static OmnipodCommunicationManager getInstance() { return omnipodCommunicationManager; } @@ -82,6 +95,10 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager i // This are just skeleton methods, we need to see what we can get returned and act accordingly public PodCommResponse initPod() { + omnipodManager.pairAndPrime(); + + + return null; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodCommunicationService.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodCommunicationService.java index 2a93c00f1d..39b1f397ce 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodCommunicationService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodCommunicationService.java @@ -35,30 +35,33 @@ import info.nightscout.androidaps.plugins.pump.omnipod.exception.PodReturnedErro * Created by andy on 6/29/18. */ -public class OmnipodCommunicationService extends RileyLinkCommunicationManager { +public class OmnipodCommunicationService /*extends RileyLinkCommunicationManager*/ { private static final Logger LOG = LoggerFactory.getLogger(OmnipodCommunicationService.class); + //RFSpy rfspy = null; + OmnipodCommunicationManager communicationManager; - public OmnipodCommunicationService(RFSpy rfspy) { - super(rfspy); + public OmnipodCommunicationService(OmnipodCommunicationManager communicationManager) { + //this.rfspy = rfspy; + this.communicationManager = communicationManager; } - @Override - protected void configurePumpSpecificSettings() { - } +// @Override +// protected void configurePumpSpecificSettings() { +// } +// +// @Override +// public boolean tryToConnectToDevice() { +// // TODO +// return false; +// } +// +// @Override +// public byte[] createPumpMessageContent(RLMessageType type) { +// return new byte[0]; +// } - @Override - public boolean tryToConnectToDevice() { - // TODO - return false; - } - - @Override - public byte[] createPumpMessageContent(RLMessageType type) { - return new byte[0]; - } - - @Override + //@Override public E createResponseMessage(byte[] payload, Class clazz) { return (E) new OmnipodPacket(payload); } @@ -196,7 +199,7 @@ public class OmnipodCommunicationService extends RileyLinkCommunicationManager { OmnipodPacket ack = createAckPacket(podState, packetAddress, messageAddress); boolean quiet = false; while (!quiet) try { - sendAndListen(ack, 300, 1, 0, 40, OmnipodPacket.class); + this.communicationManager.sendAndListen(ack, 300, 1, 0, 40, OmnipodPacket.class); } catch (RileyLinkCommunicationException ex) { if (RileyLinkBLEError.Timeout.equals(ex.getErrorCode())) { quiet = true; @@ -224,7 +227,7 @@ public class OmnipodCommunicationService extends RileyLinkCommunicationManager { while (System.currentTimeMillis() < timeoutTime) { OmnipodPacket response = null; try { - response = sendAndListen(packet, responseTimeoutMilliseconds, repeatCount, 9, preambleExtensionMilliseconds, OmnipodPacket.class); + response = this.communicationManager.sendAndListen(packet, responseTimeoutMilliseconds, repeatCount, 9, preambleExtensionMilliseconds, OmnipodPacket.class); } catch (Exception ex) { LOG.debug("Ignoring exception in exchangePackets: " + ex.getClass().getSimpleName() + ": " + ex.getMessage()); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BasalScheduleEntry.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BasalScheduleEntry.java index 0e7a06f730..23b491a4bc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BasalScheduleEntry.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BasalScheduleEntry.java @@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule; import org.joda.time.Duration; import info.nightscout.androidaps.Constants; +import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; public class BasalScheduleEntry { private final double rate; @@ -11,7 +12,7 @@ public class BasalScheduleEntry { public BasalScheduleEntry(double rate, Duration startTime) { if (rate < 0D) { throw new IllegalArgumentException("Rate should be >= 0"); - } else if (rate > Constants.MAX_BASAL_RATE) { + } else if (rate > OmnipodConst.MAX_BASAL_RATE) { throw new IllegalArgumentException("Rate exceeds max basal rate"); } this.rate = rate; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/events/EventOmnipodRefreshButtonState.kt b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/events/EventOmnipodRefreshButtonState.kt new file mode 100644 index 0000000000..8bbbfd33e6 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/events/EventOmnipodRefreshButtonState.kt @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.events + +import info.nightscout.androidaps.events.Event + +class EventOmnipodRefreshButtonState (val newState : Boolean): Event() \ No newline at end of file diff --git a/app/src/main/res/layout/omnipod_fragment.xml b/app/src/main/res/layout/omnipod_fragment.xml index e017a35329..868f48e276 100644 --- a/app/src/main/res/layout/omnipod_fragment.xml +++ b/app/src/main/res/layout/omnipod_fragment.xml @@ -144,53 +144,6 @@ android:text="content" android:textAlignment="center" /> - - - - - - - - - - - - - Pod Mgmt Pod Status + %1$d U left + Over 50 U Operation is not possible.\n\n You need to configure Omnipod first, before you can use this operation. @@ -1699,4 +1701,4 @@ %1$d minute %1$d minutes - \ No newline at end of file +