Merge pull request #364 from bartsopers/dash
More Omnipod Dash preparation + some Eros fixes
This commit is contained in:
commit
aaa1ecea8d
|
@ -186,6 +186,7 @@ dependencies {
|
|||
implementation project(':insight')
|
||||
implementation project(':rileylink')
|
||||
implementation project(':medtronic')
|
||||
implementation project(':omnipod-common')
|
||||
implementation project(':omnipod-eros')
|
||||
implementation project(':omnipod-dash')
|
||||
|
||||
|
|
|
@ -633,8 +633,8 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
|||
binding.infoLayout.apsModeText.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
pump.isSuspended() -> {
|
||||
binding.infoLayout.apsMode.setImageResource(if (pump.pumpDescription.pumpType == PumpType.Insulet_Omnipod) {
|
||||
pump.isSuspended() -> {
|
||||
binding.infoLayout.apsMode.setImageResource(if (pump.model() == PumpType.Omnipod_Eros || pump.model() == PumpType.Omnipod_Dash) {
|
||||
// For Omnipod, indicate the pump as disconnected when it's suspended.
|
||||
// The only way to 'reconnect' it, is through the Omnipod tab
|
||||
R.drawable.ic_loop_disconnected
|
||||
|
@ -906,7 +906,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
|||
if (menuChartSettings[g + 1][OverviewMenus.CharType.COB.ordinal]) secondGraphData.addCob(fromTime, now, useCobForScale, if (useCobForScale) 1.0 else 0.5)
|
||||
if (menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal]) secondGraphData.addDeviations(fromTime, now, useDevForScale, 1.0, alignDevBgiScale)
|
||||
if (menuChartSettings[g + 1][OverviewMenus.CharType.SEN.ordinal]) secondGraphData.addRatio(fromTime, now, useRatioForScale, 1.0)
|
||||
if (menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal]) secondGraphData.addMinusBGI(fromTime, endTime, useBGIForScale, if(alignDevBgiScale) 1.0 else 0.8, alignDevBgiScale)
|
||||
if (menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal]) secondGraphData.addMinusBGI(fromTime, endTime, useBGIForScale, if (alignDevBgiScale) 1.0 else 0.8, alignDevBgiScale)
|
||||
if (menuChartSettings[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] && buildHelper.isDev()) secondGraphData.addDeviationSlope(fromTime, now, useDSForScale, 1.0)
|
||||
|
||||
// set manual x bounds to have nice steps
|
||||
|
|
|
@ -36,11 +36,11 @@ class StatusLightHandler @Inject constructor(
|
|||
handleAge(careportal_cannula_age, CareportalEvent.SITECHANGE, R.string.key_statuslights_cage_warning, 48.0, R.string.key_statuslights_cage_critical, 72.0)
|
||||
handleAge(careportal_insulin_age, CareportalEvent.INSULINCHANGE, R.string.key_statuslights_iage_warning, 72.0, R.string.key_statuslights_iage_critical, 144.0)
|
||||
handleAge(careportal_sensor_age, CareportalEvent.SENSORCHANGE, R.string.key_statuslights_sage_warning, 216.0, R.string.key_statuslights_sage_critical, 240.0)
|
||||
if (pump.pumpDescription.isBatteryReplaceable) {
|
||||
if (pump.pumpDescription.isBatteryReplaceable || (pump is OmnipodErosPumpPlugin && pump.isUseRileyLinkBatteryLevel && pump.isBatteryChangeLoggingEnabled)) {
|
||||
handleAge(careportal_pb_age, CareportalEvent.PUMPBATTERYCHANGE, R.string.key_statuslights_bage_warning, 216.0, R.string.key_statuslights_bage_critical, 240.0)
|
||||
}
|
||||
if (!config.NSCLIENT) {
|
||||
if (pump.model() == PumpType.Insulet_Omnipod) {
|
||||
if (pump.model() == PumpType.Omnipod_Eros || pump.model() == PumpType.Omnipod_Dash) {
|
||||
handleOmnipodReservoirLevel(careportal_reservoir_level, R.string.key_statuslights_res_critical, 10.0, R.string.key_statuslights_res_warning, 80.0, pump.reservoirLevel, "U")
|
||||
} else {
|
||||
handleLevel(careportal_reservoir_level, R.string.key_statuslights_res_critical, 10.0, R.string.key_statuslights_res_warning, 80.0, pump.reservoirLevel, "U")
|
||||
|
@ -52,8 +52,14 @@ class StatusLightHandler @Inject constructor(
|
|||
}
|
||||
|
||||
if (!config.NSCLIENT) {
|
||||
if (pump.model() == PumpType.Insulet_Omnipod && pump is OmnipodErosPumpPlugin) { // instance of check is needed because at startup, pump can still be VirtualPumpPlugin and that will cause a crash because of the class cast below
|
||||
handleOmnipodBatteryLevel(careportal_battery_level, R.string.key_statuslights_bat_critical, 26.0, R.string.key_statuslights_bat_warning, 51.0, pump.batteryLevel.toDouble(), "%", pump.isUseRileyLinkBatteryLevel)
|
||||
if (pump.model() == PumpType.Omnipod_Dash) {
|
||||
// Omnipod Dash does not report its battery level
|
||||
careportal_battery_level?.text = resourceHelper.gs(R.string.notavailable)
|
||||
careportal_battery_level?.setTextColor(Color.WHITE)
|
||||
} else if (pump.model() == PumpType.Omnipod_Eros && pump is OmnipodErosPumpPlugin) { // instance of check is needed because at startup, pump can still be VirtualPumpPlugin and that will cause a crash because of the class cast below
|
||||
// The Omnipod Eros does not report its battery level. However, some RileyLink alternatives do.
|
||||
// Depending on the user's configuration, we will either show the battery level reported by the RileyLink or "n/a"
|
||||
handleOmnipodErosBatteryLevel(careportal_battery_level, R.string.key_statuslights_bat_critical, 26.0, R.string.key_statuslights_bat_warning, 51.0, pump.batteryLevel.toDouble(), "%", pump.isUseRileyLinkBatteryLevel)
|
||||
} else if (pump.model() != PumpType.AccuChekCombo) {
|
||||
handleLevel(careportal_battery_level, R.string.key_statuslights_bat_critical, 26.0, R.string.key_statuslights_bat_warning, 51.0, pump.batteryLevel.toDouble(), "%")
|
||||
}
|
||||
|
@ -93,7 +99,7 @@ class StatusLightHandler @Inject constructor(
|
|||
}
|
||||
|
||||
@Suppress("SameParameterValue")
|
||||
private fun handleOmnipodBatteryLevel(view: TextView?, criticalSetting: Int, criticalDefaultValue: Double, warnSetting: Int, warnDefaultValue: Double, level: Double, units: String, useRileyLinkBatteryLevel: Boolean) {
|
||||
private fun handleOmnipodErosBatteryLevel(view: TextView?, criticalSetting: Int, criticalDefaultValue: Double, warnSetting: Int, warnDefaultValue: Double, level: Double, units: String, useRileyLinkBatteryLevel: Boolean) {
|
||||
if (useRileyLinkBatteryLevel) {
|
||||
handleLevel(view, criticalSetting, criticalDefaultValue, warnSetting, warnDefaultValue, level, units)
|
||||
} else {
|
||||
|
|
|
@ -27,6 +27,7 @@ import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
|||
import info.nightscout.androidaps.plugins.profile.ns.NSProfileFragment
|
||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.OmnipodDashPumpPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.eros.OmnipodErosPumpPlugin
|
||||
import info.nightscout.androidaps.setupwizard.elements.*
|
||||
import info.nightscout.androidaps.setupwizard.events.EventSWUpdate
|
||||
|
@ -284,14 +285,14 @@ class SWDefinition @Inject constructor(
|
|||
.add(SWInfoText(injector)
|
||||
.label(R.string.setupwizard_pump_pump_not_initialized)
|
||||
.visibility { !isPumpInitialized() })
|
||||
.add( // Omnipod only
|
||||
.add( // Omnipod Eros only
|
||||
SWInfoText(injector)
|
||||
.label(R.string.setupwizard_pump_waiting_for_riley_link_connection)
|
||||
.visibility {
|
||||
val activePump = activePlugin.activePump
|
||||
activePump is OmnipodErosPumpPlugin && !activePump.isRileyLinkReady
|
||||
})
|
||||
.add( // Omnipod only
|
||||
.add( // Omnipod Eros only
|
||||
SWEventListener(injector, EventRileyLinkDeviceStatusChange::class.java)
|
||||
.label(R.string.setupwizard_pump_riley_link_status)
|
||||
.visibility { activePlugin.activePump is OmnipodErosPumpPlugin })
|
||||
|
@ -301,18 +302,21 @@ class SWDefinition @Inject constructor(
|
|||
.visibility {
|
||||
// Hide for Omnipod, because as we don't require a Pod to be paired in the setup wizard,
|
||||
// Getting the status might not be possible
|
||||
activePlugin.activePump !is OmnipodErosPumpPlugin
|
||||
activePlugin.activePump !is OmnipodErosPumpPlugin && activePlugin.activePump !is OmnipodDashPumpPlugin
|
||||
})
|
||||
.add(SWEventListener(injector, EventPumpStatusChanged::class.java)
|
||||
.visibility { activePlugin.activePump !is OmnipodErosPumpPlugin })
|
||||
.visibility { activePlugin.activePump !is OmnipodErosPumpPlugin && activePlugin.activePump !is OmnipodDashPumpPlugin })
|
||||
.validator { isPumpInitialized() }
|
||||
|
||||
private fun isPumpInitialized(): Boolean {
|
||||
val activePump = activePlugin.activePump
|
||||
|
||||
// For Omnipod, consider the pump initialized when a RL has been configured successfully
|
||||
// Users will be prompted to activate a Pod after completing the setup wizard.
|
||||
return activePump.isInitialized() || (activePump is OmnipodErosPumpPlugin && activePump.isRileyLinkReady)
|
||||
// For Omnipod, activating a Pod can be done after setup through the Omnipod fragment
|
||||
// For the Eros model, consider the pump initialized when a RL has been configured successfully
|
||||
// For Dash model, consider the pump setup without any extra conditions
|
||||
return activePump.isInitialized()
|
||||
|| (activePump is OmnipodErosPumpPlugin && activePump.isRileyLinkReady)
|
||||
|| activePump is OmnipodDashPumpPlugin
|
||||
}
|
||||
|
||||
private val screenAps = SWScreen(injector, R.string.configbuilder_aps)
|
||||
|
|
|
@ -42,6 +42,7 @@ dependencies {
|
|||
api "io.reactivex.rxjava2:rxkotlin:$rxkotlin_version"
|
||||
api "io.reactivex.rxjava2:rxandroid:$rxandroid_version"
|
||||
api "org.apache.commons:commons-lang3:$commonslang3_version"
|
||||
api "commons-codec:commons-codec:$commonscodec_version"
|
||||
|
||||
//CryptoUtil
|
||||
api 'com.madgag.spongycastle:core:1.58.0.0'
|
||||
|
|
|
@ -98,12 +98,19 @@ public enum PumpType {
|
|||
|
||||
|
||||
// Insulet
|
||||
Insulet_Omnipod("Insulet Omnipod", ManufacturerType.Insulet, "Omnipod (Eros)", 0.05d, null, //
|
||||
Omnipod_Eros("Omnipod", ManufacturerType.Insulet, "Eros", 0.05d, null, //
|
||||
new DoseSettings(0.05d, 30, 8 * 60, 0.05d), //
|
||||
PumpTempBasalType.Absolute, //
|
||||
new DoseSettings(0.05d, 30, 12 * 60, 0d, 30.0d), PumpCapability.BasalRate_Duration30minAllowed, //
|
||||
0.05d, null, 0.05d, null, PumpCapability.OmnipodCapabilities, true),
|
||||
|
||||
Omnipod_Dash("Omnipod", ManufacturerType.Insulet, "Dash", 0.05d, null, //
|
||||
new DoseSettings(0.05d, 30, 8 * 60, 0.05d), //
|
||||
PumpTempBasalType.Absolute, //
|
||||
new DoseSettings(0.05d, 30, 12 * 60, 0d, 30.0d), PumpCapability.BasalRate_Duration30minAllowed, //
|
||||
0.05d, null, 0.05d, null, PumpCapability.OmnipodCapabilities, false),
|
||||
|
||||
|
||||
// Medtronic
|
||||
Medtronic_512_712("Medtronic 512/712", ManufacturerType.Medtronic, "512/712", 0.1d, null, //
|
||||
new DoseSettings(0.05d, 30, 8 * 60, 0.05d), //
|
||||
|
|
|
@ -19,6 +19,8 @@ files:
|
|||
translation: /dana/src/main/res/values-%android_code%/strings.xml
|
||||
- source: /medtronic/src/main/res/values/strings.xml
|
||||
translation: /medtronic/src/main/res/values-%android_code%/strings.xml
|
||||
- source: /omnipod-common/src/main/res/values/strings.xml
|
||||
translation: /omnipod-common/src/main/res/values-%android_code%/strings.xml
|
||||
- source: /omnipod-dash/src/main/res/values/strings.xml
|
||||
translation: /omnipod-dash/src/main/res/values-%android_code%/strings.xml
|
||||
- source: /omnipod-eros/src/main/res/values/strings.xml
|
||||
|
|
1
omnipod-common/.gitignore
vendored
Normal file
1
omnipod-common/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/build
|
20
omnipod-common/build.gradle
Normal file
20
omnipod-common/build.gradle
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
apply plugin: 'com.hiya.jacoco-android'
|
||||
|
||||
apply from: "${project.rootDir}/gradle/android_dependencies.gradle"
|
||||
apply from: "${project.rootDir}/gradle/android_module_dependencies.gradle"
|
||||
apply from: "${project.rootDir}/gradle/test_dependencies.gradle"
|
||||
|
||||
android {
|
||||
defaultConfig {
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':core')
|
||||
}
|
0
omnipod-common/consumer-rules.pro
Normal file
0
omnipod-common/consumer-rules.pro
Normal file
21
omnipod-common/proguard-rules.pro
vendored
Normal file
21
omnipod-common/proguard-rules.pro
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
5
omnipod-common/src/main/AndroidManifest.xml
Normal file
5
omnipod-common/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="info.nightscout.androidaps.plugins.pump.omnipod.common">
|
||||
|
||||
<application></application>
|
||||
</manifest>
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.eros.dagger
|
||||
package info.nightscout.androidaps.plugins.pump.omnipod.common.dagger
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
|
@ -15,7 +15,7 @@ annotation class OmnipodPluginQualifier
|
|||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
|
||||
@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
|
||||
@MapKey
|
||||
internal annotation class ViewModelKey(val value: KClass<out ViewModel>)
|
||||
annotation class ViewModelKey(val value: KClass<out ViewModel>)
|
||||
|
||||
// TODO: These annotations and Factories could be used globally -> move to core or app
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.dagger
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.fragment.action.InitializePodFragment
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.fragment.action.InsertCannulaFragment
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.fragment.info.AttachPodFragment
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.fragment.info.PodActivatedFragment
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.fragment.info.StartPodActivationFragment
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.fragment.action.DeactivatePodFragment
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.fragment.info.PodDeactivatedFragment
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.fragment.info.PodDiscardedFragment
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.fragment.info.StartPodDeactivationFragment
|
||||
import javax.inject.Provider
|
||||
|
||||
@Module
|
||||
abstract class OmnipodWizardModule {
|
||||
|
||||
companion object {
|
||||
|
||||
@Provides
|
||||
@OmnipodPluginQualifier
|
||||
fun providesViewModelFactory(@OmnipodPluginQualifier viewModels: MutableMap<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>): ViewModelProvider.Factory {
|
||||
return ViewModelFactory(viewModels)
|
||||
}
|
||||
}
|
||||
|
||||
// #### FRAGMENTS ##############################################################################
|
||||
|
||||
// POD ACTIVATION
|
||||
|
||||
@FragmentScope
|
||||
@ContributesAndroidInjector
|
||||
internal abstract fun contributesStartPodActivationFragment(): StartPodActivationFragment
|
||||
|
||||
@FragmentScope
|
||||
@ContributesAndroidInjector
|
||||
internal abstract fun contributesInitializeActionFragment(): InitializePodFragment
|
||||
|
||||
@FragmentScope
|
||||
@ContributesAndroidInjector
|
||||
internal abstract fun contributesAttachPodFragment(): AttachPodFragment
|
||||
|
||||
@FragmentScope
|
||||
@ContributesAndroidInjector
|
||||
internal abstract fun contributesInsertCannulaFragment(): InsertCannulaFragment
|
||||
|
||||
@FragmentScope
|
||||
@ContributesAndroidInjector
|
||||
internal abstract fun contributesPodActivatedFragment(): PodActivatedFragment
|
||||
|
||||
// POD DEACTIVATION
|
||||
|
||||
@FragmentScope
|
||||
@ContributesAndroidInjector
|
||||
internal abstract fun contributesStartPodDeactivationFragment(): StartPodDeactivationFragment
|
||||
|
||||
@FragmentScope
|
||||
@ContributesAndroidInjector
|
||||
internal abstract fun contributesDeactivatePodFragment(): DeactivatePodFragment
|
||||
|
||||
@FragmentScope
|
||||
@ContributesAndroidInjector
|
||||
internal abstract fun contributesPodDeactivatedFragment(): PodDeactivatedFragment
|
||||
|
||||
@FragmentScope
|
||||
@ContributesAndroidInjector
|
||||
internal abstract fun contributesPodDiscardedFragment(): PodDiscardedFragment
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.definition;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.R;
|
||||
|
||||
/**
|
||||
* Created by andy on 4.8.2019
|
||||
*/
|
||||
public enum OmnipodCommandType {
|
||||
INITIALIZE_POD(R.string.omnipod_common_cmd_initialize_pod), // First step of Pod activation
|
||||
INSERT_CANNULA(R.string.omnipod_common_cmd_insert_cannula), // Second step of Pod activation
|
||||
DEACTIVATE_POD(R.string.omnipod_common_cmd_deactivate_pod), //
|
||||
SET_BASAL_PROFILE(R.string.omnipod_common_cmd_set_basal_schedule), //
|
||||
SET_BOLUS(R.string.omnipod_common_cmd_set_bolus), //
|
||||
CANCEL_BOLUS(R.string.omnipod_common_cmd_cancel_bolus), //
|
||||
SET_TEMPORARY_BASAL(R.string.omnipod_common_cmd_set_tbr), //
|
||||
CANCEL_TEMPORARY_BASAL(R.string.omnipod_common_cmd_cancel_tbr_by_driver), //
|
||||
DISCARD_POD(R.string.omnipod_common_cmd_discard_pod), //
|
||||
GET_POD_STATUS(R.string.omnipod_common_cmd_get_pod_status), //
|
||||
SET_TIME(R.string.omnipod_common_cmd_set_time), //
|
||||
CONFIGURE_ALERTS(R.string.omnipod_common_cmd_configure_alerts), //
|
||||
ACKNOWLEDGE_ALERTS(R.string.omnipod_common_cmd_silence_alerts), //
|
||||
READ_POD_PULSE_LOG(R.string.omnipod_common_cmd_read_pulse_log), //
|
||||
SUSPEND_DELIVERY(R.string.omnipod_common_cmd_suspend_delivery),
|
||||
RESUME_DELIVERY(R.string.omnipod_common_cmd_resume_delivery),
|
||||
PLAY_TEST_BEEP(R.string.omnipod_common_cmd_play_test_beep);
|
||||
|
||||
private final int resourceId;
|
||||
|
||||
OmnipodCommandType(int resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
public int getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import info.nightscout.androidaps.queue.commands.CustomCommand;
|
||||
|
||||
public final class CommandAcknowledgeAlerts implements CustomCommand {
|
||||
@NotNull @Override public String getStatusDescription() {
|
||||
return "ACKNOWLEDGE ALERTS";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import info.nightscout.androidaps.queue.commands.CustomCommand;
|
||||
|
||||
public final class CommandDeactivatePod implements CustomCommand {
|
||||
@NotNull @Override public String getStatusDescription() {
|
||||
return "DEACTIVATE POD";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import info.nightscout.androidaps.queue.commands.CustomCommand;
|
||||
|
||||
public final class CommandHandleTimeChange implements CustomCommand {
|
||||
private final boolean requestedByUser;
|
||||
|
||||
public CommandHandleTimeChange(boolean requestedByUser) {
|
||||
this.requestedByUser = requestedByUser;
|
||||
}
|
||||
|
||||
public boolean isRequestedByUser() {
|
||||
return requestedByUser;
|
||||
}
|
||||
|
||||
@NotNull @Override public String getStatusDescription() {
|
||||
return "HANDLE TIME CHANGE";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import info.nightscout.androidaps.queue.commands.CustomCommand;
|
||||
|
||||
public class CommandPlayTestBeep implements CustomCommand {
|
||||
@NotNull @Override public String getStatusDescription() {
|
||||
return "PLAY TEST BEEP";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import info.nightscout.androidaps.queue.commands.CustomCommand;
|
||||
|
||||
public final class CommandResumeDelivery implements CustomCommand {
|
||||
@NotNull @Override public String getStatusDescription() {
|
||||
return "RESUME DELIVERY";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import info.nightscout.androidaps.queue.commands.CustomCommand;
|
||||
|
||||
public final class CommandSuspendDelivery implements CustomCommand {
|
||||
@NotNull @Override public String getStatusDescription() {
|
||||
return "SUSPEND DELIVERY";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import info.nightscout.androidaps.queue.commands.CustomCommand;
|
||||
|
||||
public final class CommandUpdateAlertConfiguration implements CustomCommand {
|
||||
@NotNull @Override public String getStatusDescription() {
|
||||
return "UPDATE ALERT CONFIGURATION";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.IdRes
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.activity.OmnipodWizardActivityBase
|
||||
|
||||
abstract class PodActivationWizardActivity : OmnipodWizardActivityBase() {
|
||||
companion object {
|
||||
|
||||
const val KEY_TYPE = "wizardType"
|
||||
const val KEY_START_DESTINATION = "startDestination"
|
||||
}
|
||||
|
||||
enum class Type {
|
||||
SHORT,
|
||||
LONG
|
||||
}
|
||||
|
||||
@IdRes
|
||||
private var startDestination: Int = R.id.startPodActivationFragment
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setContentView(R.layout.omnipod_common_pod_activation_wizard_activity)
|
||||
|
||||
startDestination = savedInstanceState?.getInt(KEY_START_DESTINATION, R.id.startPodActivationFragment)
|
||||
?: if (intent.getSerializableExtra(KEY_TYPE) as Type == Type.LONG) {
|
||||
R.id.startPodActivationFragment
|
||||
} else {
|
||||
R.id.attachPodFragment
|
||||
}
|
||||
|
||||
setStartDestination(startDestination)
|
||||
}
|
||||
|
||||
private fun setStartDestination(@IdRes startDestination: Int) {
|
||||
this.startDestination = startDestination
|
||||
val navController = getNavController()
|
||||
val navInflater = navController.navInflater
|
||||
val graph = navInflater.inflate(R.navigation.omnipod_common_pod_activation_wizard_navigation_graph)
|
||||
graph.startDestination = startDestination
|
||||
navController.graph = graph
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putInt(KEY_START_DESTINATION, startDestination)
|
||||
}
|
||||
|
||||
override fun getTotalDefinedNumberOfSteps(): Int = 5
|
||||
|
||||
override fun getActualNumberOfSteps(): Int {
|
||||
if (startDestination == R.id.attachPodFragment) {
|
||||
return 3
|
||||
}
|
||||
return 5
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.fragment.action
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.dagger.OmnipodPluginQualifier
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.viewmodel.action.InitializePodViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
class InitializePodFragment : PodActivationActionFragmentBase() {
|
||||
|
||||
@Inject
|
||||
@OmnipodPluginQualifier
|
||||
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val vm: InitializePodViewModel by viewModels { viewModelFactory }
|
||||
this.viewModel = vm
|
||||
}
|
||||
|
||||
@IdRes
|
||||
override fun getNextPageActionId(): Int = R.id.action_initializePodFragment_to_attachPodFragment
|
||||
|
||||
override fun getIndex(): Int = 2
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.fragment.action
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.dagger.OmnipodPluginQualifier
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.viewmodel.action.InsertCannulaViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
class InsertCannulaFragment : PodActivationActionFragmentBase() {
|
||||
|
||||
@Inject
|
||||
@OmnipodPluginQualifier
|
||||
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val vm: InsertCannulaViewModel by viewModels { viewModelFactory }
|
||||
this.viewModel = vm
|
||||
}
|
||||
|
||||
@IdRes
|
||||
override fun getNextPageActionId(): Int = R.id.action_insertCannulaFragment_to_PodActivatedFragment
|
||||
|
||||
override fun getIndex(): Int = 4
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.fragment.action
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.viewmodel.action.PodActivationActionViewModelBase
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.fragment.ActionFragmentBase
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.PodDeactivationWizardActivity
|
||||
|
||||
abstract class PodActivationActionFragmentBase : ActionFragmentBase() {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
view.findViewById<Button>(R.id.omnipod_wizard_button_deactivate_pod).setOnClickListener {
|
||||
activity?.let {
|
||||
startActivity(Intent(it, PodDeactivationWizardActivity::class.java))
|
||||
it.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure() {
|
||||
(viewModel as? PodActivationActionViewModelBase)?.let { viewModel ->
|
||||
if (viewModel.isPodDeactivatable() and (viewModel.isPodInAlarm() or viewModel.isPodActivationTimeExceeded())) {
|
||||
view?.let {
|
||||
it.findViewById<Button>(R.id.omnipod_wizard_button_retry)?.visibility = View.GONE
|
||||
it.findViewById<Button>(R.id.omnipod_wizard_button_deactivate_pod)?.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.fragment.info
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.dagger.OmnipodPluginQualifier
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.viewmodel.info.AttachPodViewModel
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.fragment.InfoFragmentBase
|
||||
import javax.inject.Inject
|
||||
|
||||
class AttachPodFragment : InfoFragmentBase() {
|
||||
|
||||
@Inject
|
||||
@OmnipodPluginQualifier
|
||||
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val vm: AttachPodViewModel by viewModels { viewModelFactory }
|
||||
this.viewModel = vm
|
||||
}
|
||||
|
||||
@IdRes
|
||||
override fun getNextPageActionId(): Int = R.id.action_attachPodFragment_to_insertCannulaFragment
|
||||
|
||||
override fun getIndex(): Int = 3
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
view.findViewById<Button>(R.id.button_next).setOnClickListener {
|
||||
context?.let {
|
||||
AlertDialog.Builder(it)
|
||||
.setIcon(android.R.drawable.ic_dialog_alert)
|
||||
.setTitle(getString(getTitleId()))
|
||||
.setMessage(getString(R.string.omnipod_common_pod_activation_wizard_attach_pod_confirm_insert_cannula_text))
|
||||
.setPositiveButton(getString(R.string.omnipod_common_ok)) { _, _ -> findNavController().navigate(getNextPageActionId()) }
|
||||
.setNegativeButton(getString(R.string.omnipod_common_cancel), null)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.fragment.info
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.dagger.OmnipodPluginQualifier
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.viewmodel.info.PodActivatedViewModel
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.fragment.InfoFragmentBase
|
||||
import javax.inject.Inject
|
||||
|
||||
class PodActivatedFragment : InfoFragmentBase() {
|
||||
|
||||
@Inject
|
||||
@OmnipodPluginQualifier
|
||||
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val vm: PodActivatedViewModel by viewModels { viewModelFactory }
|
||||
this.viewModel = vm
|
||||
}
|
||||
|
||||
@IdRes
|
||||
override fun getNextPageActionId(): Int? = null
|
||||
|
||||
override fun getIndex(): Int = 5
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.fragment.info
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.dagger.OmnipodPluginQualifier
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.viewmodel.info.StartPodActivationViewModel
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.fragment.InfoFragmentBase
|
||||
import javax.inject.Inject
|
||||
|
||||
class StartPodActivationFragment : InfoFragmentBase() {
|
||||
|
||||
@Inject
|
||||
@OmnipodPluginQualifier
|
||||
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val vm: StartPodActivationViewModel by viewModels { viewModelFactory }
|
||||
this.viewModel = vm
|
||||
}
|
||||
|
||||
@IdRes
|
||||
override fun getNextPageActionId(): Int = R.id.action_startPodActivationFragment_to_initializePodFragment
|
||||
|
||||
override fun getIndex(): Int = 1
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.viewmodel.action
|
||||
|
||||
abstract class InitializePodViewModel : PodActivationActionViewModelBase()
|
|
@ -0,0 +1,3 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.viewmodel.action
|
||||
|
||||
abstract class InsertCannulaViewModel : PodActivationActionViewModelBase()
|
|
@ -0,0 +1,12 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.viewmodel.action
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.viewmodel.ActionViewModelBase
|
||||
|
||||
abstract class PodActivationActionViewModelBase : ActionViewModelBase() {
|
||||
|
||||
abstract fun isPodInAlarm(): Boolean
|
||||
|
||||
abstract fun isPodActivationTimeExceeded(): Boolean
|
||||
|
||||
abstract fun isPodDeactivatable(): Boolean
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.viewmodel.info
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.viewmodel.ViewModelBase
|
||||
|
||||
abstract class AttachPodViewModel : ViewModelBase()
|
|
@ -0,0 +1,5 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.viewmodel.info
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.viewmodel.ViewModelBase
|
||||
|
||||
abstract class PodActivatedViewModel : ViewModelBase()
|
|
@ -0,0 +1,5 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.viewmodel.info
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.viewmodel.ViewModelBase
|
||||
|
||||
abstract class StartPodActivationViewModel : ViewModelBase()
|
|
@ -1,16 +1,14 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.eros.ui.wizard.common.activity
|
||||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.activity
|
||||
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.eros.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.R
|
||||
|
||||
abstract class OmnipodWizardActivityBase : NoSplashAppCompatActivity() {
|
||||
|
||||
override fun onBackPressed() {
|
||||
exitActivityAfterConfirmation()
|
||||
}
|
||||
override fun onBackPressed() = exitActivityAfterConfirmation()
|
||||
|
||||
fun exitActivityAfterConfirmation() {
|
||||
if (getNavController().previousBackStackEntry == null) {
|
||||
|
@ -18,10 +16,10 @@ abstract class OmnipodWizardActivityBase : NoSplashAppCompatActivity() {
|
|||
} else {
|
||||
AlertDialog.Builder(this)
|
||||
.setIcon(android.R.drawable.ic_dialog_alert)
|
||||
.setTitle(getString(R.string.omnipod_wizard_exit_confirmation_title))
|
||||
.setMessage(getString(R.string.omnipod_wizard_exit_confirmation_text))
|
||||
.setPositiveButton(getString(R.string.omnipod_yes)) { _, _ -> finish() }
|
||||
.setNegativeButton(getString(R.string.omnipod_no), null)
|
||||
.setTitle(getString(R.string.omnipod_common_wizard_exit_confirmation_title))
|
||||
.setMessage(getString(R.string.omnipod_common_wizard_exit_confirmation_text))
|
||||
.setPositiveButton(getString(R.string.omnipod_common_yes)) { _, _ -> finish() }
|
||||
.setNegativeButton(getString(R.string.omnipod_common_no), null)
|
||||
.show()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.fragment
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import android.widget.ImageView
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.LayoutRes
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.viewmodel.ActionViewModelBase
|
||||
import info.nightscout.androidaps.utils.extensions.toVisibility
|
||||
|
||||
abstract class ActionFragmentBase : WizardFragmentBase() {
|
||||
|
||||
val actionViewModel: ActionViewModelBase
|
||||
get() = viewModel as ActionViewModelBase
|
||||
|
||||
@SuppressLint("CutPasteId")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.navButtonsLayout.buttonNext.isEnabled = false
|
||||
view.findViewById<TextView>(R.id.omnipod_wizard_action_page_text).setText(getTextId())
|
||||
|
||||
view.findViewById<Button>(R.id.omnipod_wizard_button_retry).setOnClickListener { actionViewModel.executeAction() }
|
||||
|
||||
actionViewModel.isActionExecutingLiveData.observe(viewLifecycleOwner, { isExecuting ->
|
||||
if (isExecuting) {
|
||||
view.findViewById<TextView>(R.id.omnipod_wizard_action_error).visibility = View.GONE
|
||||
view.findViewById<Button>(R.id.omnipod_wizard_button_deactivate_pod).visibility = View.GONE
|
||||
view.findViewById<Button>(R.id.omnipod_wizard_button_discard_pod).visibility = View.GONE
|
||||
view.findViewById<Button>(R.id.omnipod_wizard_button_retry).visibility = View.GONE
|
||||
}
|
||||
view.findViewById<ProgressBar>(R.id.omnipod_wizard_action_progress_indication).visibility = isExecuting.toVisibility()
|
||||
view.findViewById<Button>(R.id.button_cancel).isEnabled = !isExecuting
|
||||
})
|
||||
|
||||
actionViewModel.actionResultLiveData.observe(viewLifecycleOwner, { result ->
|
||||
result?.let {
|
||||
val isExecuting = isActionExecuting()
|
||||
|
||||
view.findViewById<Button>(R.id.button_next).isEnabled = result.success
|
||||
view.findViewById<ImageView>(R.id.omnipod_wizard_action_success).visibility = result.success.toVisibility()
|
||||
view.findViewById<TextView>(R.id.omnipod_wizard_action_error).visibility = (!isExecuting && !result.success).toVisibility()
|
||||
view.findViewById<Button>(R.id.omnipod_wizard_button_retry).visibility = (!isExecuting && !result.success).toVisibility()
|
||||
|
||||
if (!result.success) {
|
||||
view.findViewById<TextView>(R.id.omnipod_wizard_action_error).text = result.comment
|
||||
onFailure()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (savedInstanceState == null && !isActionExecuting()) {
|
||||
actionViewModel.executeAction()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected fun isActionExecuting() = actionViewModel.isActionExecutingLiveData.value!!
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
actionViewModel.isActionExecutingLiveData.removeObservers(viewLifecycleOwner)
|
||||
actionViewModel.actionResultLiveData.removeObservers(viewLifecycleOwner)
|
||||
}
|
||||
|
||||
abstract fun onFailure()
|
||||
|
||||
@LayoutRes
|
||||
override fun getLayoutId(): Int = R.layout.omnipod_common_wizard_action_page_fragment
|
||||
}
|
|
@ -1,11 +1,10 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.eros.ui.wizard.common.fragment
|
||||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.annotation.StringRes
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.eros.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.R
|
||||
|
||||
abstract class InfoFragmentBase : WizardFragmentBase() {
|
||||
|
||||
|
@ -15,11 +14,6 @@ abstract class InfoFragmentBase : WizardFragmentBase() {
|
|||
view.findViewById<TextView>(R.id.omnipod_wizard_info_page_text).setText(getTextId())
|
||||
}
|
||||
|
||||
@StringRes
|
||||
abstract fun getTextId(): Int
|
||||
|
||||
@LayoutRes
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.omnipod_wizard_info_page_fragment
|
||||
}
|
||||
override fun getLayoutId(): Int = R.layout.omnipod_common_wizard_info_page_fragment
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.eros.ui.wizard.common.fragment
|
||||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.fragment
|
||||
|
||||
import android.content.res.ColorStateList
|
||||
import android.os.Bundle
|
||||
|
@ -10,28 +10,33 @@ import androidx.annotation.LayoutRes
|
|||
import androidx.annotation.StringRes
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.eros.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.eros.databinding.OmnipodWizardBaseFragmentBinding
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.eros.ui.wizard.common.activity.OmnipodWizardActivityBase
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.databinding.OmnipodCommonWizardBaseFragmentBinding
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.databinding.OmnipodCommonWizardProgressIndicationBinding
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.activity.OmnipodWizardActivityBase
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.viewmodel.ViewModelBase
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
abstract class WizardFragmentBase : DaggerFragment() {
|
||||
|
||||
var _binding: OmnipodWizardBaseFragmentBinding? = null
|
||||
protected lateinit var viewModel: ViewModelBase
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
var _binding: OmnipodCommonWizardBaseFragmentBinding? = null
|
||||
var _progressIndicationBinding: OmnipodCommonWizardProgressIndicationBinding? = null
|
||||
|
||||
// These properties are only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
val binding get() = _binding!!
|
||||
val progressIndicationBinding get() = _progressIndicationBinding!!
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
_binding = OmnipodWizardBaseFragmentBinding.inflate(inflater, container, false)
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||
OmnipodCommonWizardBaseFragmentBinding.inflate(inflater, container, false).also {
|
||||
_binding = it
|
||||
_progressIndicationBinding = OmnipodCommonWizardProgressIndicationBinding.bind(it.root)
|
||||
|
||||
binding.fragmentContent.let {
|
||||
it.layoutResource = getLayoutId()
|
||||
it.inflate()
|
||||
}
|
||||
return binding.root
|
||||
}
|
||||
it.fragmentContent.layoutResource = getLayoutId()
|
||||
it.fragmentContent.inflate()
|
||||
}.root
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
@ -41,7 +46,7 @@ abstract class WizardFragmentBase : DaggerFragment() {
|
|||
val nextPage = getNextPageActionId()
|
||||
|
||||
if (nextPage == null) {
|
||||
binding.navButtonsLayout.buttonNext.text = getString(R.string.omnipod_wizard_button_finish)
|
||||
binding.navButtonsLayout.buttonNext.text = getString(R.string.omnipod_common_wizard_button_finish)
|
||||
binding.navButtonsLayout.buttonNext.backgroundTintList = ColorStateList.valueOf(resources.getColor(R.color.omnipod_wizard_finish_button, context?.theme))
|
||||
}
|
||||
|
||||
|
@ -73,7 +78,7 @@ abstract class WizardFragmentBase : DaggerFragment() {
|
|||
val currentFragment = getIndex() - (it.getTotalDefinedNumberOfSteps() - numberOfSteps)
|
||||
val progressPercentage = (currentFragment / numberOfSteps.toDouble() * 100).roundToInt()
|
||||
|
||||
binding.progressIndicationLayout.progressIndication.progress = progressPercentage
|
||||
progressIndicationBinding.progressIndication.progress = progressPercentage
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,7 +89,9 @@ abstract class WizardFragmentBase : DaggerFragment() {
|
|||
protected abstract fun getNextPageActionId(): Int?
|
||||
|
||||
@StringRes
|
||||
protected abstract fun getTitleId(): Int
|
||||
protected fun getTitleId(): Int = viewModel.getTitleId()
|
||||
|
||||
@StringRes protected fun getTextId(): Int = viewModel.getTextId()
|
||||
|
||||
protected abstract fun getIndex(): Int
|
||||
}
|
|
@ -1,15 +1,14 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.eros.ui.wizard.common.viewmodel
|
||||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.viewmodel
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import info.nightscout.androidaps.data.PumpEnactResult
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import io.reactivex.subjects.SingleSubject
|
||||
|
||||
abstract class ActionViewModelBase : ViewModel() {
|
||||
abstract class ActionViewModelBase : ViewModelBase() {
|
||||
|
||||
private val _isActionExecutingLiveData = MutableLiveData<Boolean>(false)
|
||||
private val _isActionExecutingLiveData = MutableLiveData(false)
|
||||
val isActionExecutingLiveData: LiveData<Boolean> = _isActionExecutingLiveData
|
||||
|
||||
private val _actionResultLiveData = MutableLiveData<PumpEnactResult?>(null)
|
||||
|
@ -17,7 +16,7 @@ abstract class ActionViewModelBase : ViewModel() {
|
|||
|
||||
fun executeAction() {
|
||||
_isActionExecutingLiveData.postValue(true)
|
||||
SingleSubject.fromCallable<PumpEnactResult>(this::doExecuteAction)
|
||||
SingleSubject.fromCallable(this::doExecuteAction)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.doOnSuccess { result ->
|
||||
_isActionExecutingLiveData.postValue(false)
|
|
@ -0,0 +1,11 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.viewmodel
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
||||
abstract class ViewModelBase : ViewModel() {
|
||||
|
||||
@StringRes abstract fun getTitleId(): Int
|
||||
|
||||
@StringRes abstract fun getTextId(): Int
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation
|
||||
|
||||
import android.os.Bundle
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.activity.OmnipodWizardActivityBase
|
||||
|
||||
abstract class PodDeactivationWizardActivity : OmnipodWizardActivityBase() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setContentView(R.layout.omnipod_common_pod_deactivation_wizard_activity)
|
||||
}
|
||||
|
||||
override fun getTotalDefinedNumberOfSteps(): Int = 3
|
||||
|
||||
override fun getActualNumberOfSteps(): Int = 3
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.fragment.action
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.dagger.OmnipodPluginQualifier
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.fragment.ActionFragmentBase
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.viewmodel.action.DeactivatePodViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
class DeactivatePodFragment : ActionFragmentBase() {
|
||||
|
||||
@Inject
|
||||
@OmnipodPluginQualifier
|
||||
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||
|
||||
private lateinit var buttonDiscardPod: Button
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val vm: DeactivatePodViewModel by viewModels { viewModelFactory }
|
||||
this.viewModel = vm
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
view.findViewById<Button>(R.id.omnipod_wizard_button_discard_pod)?.setOnClickListener {
|
||||
context?.let {
|
||||
AlertDialog.Builder(it)
|
||||
.setIcon(android.R.drawable.ic_dialog_alert)
|
||||
.setTitle(getString(R.string.omnipod_common_pod_deactivation_wizard_discard_pod))
|
||||
.setMessage(getString(R.string.omnipod_common_pod_deactivation_wizard_discard_pod_confirmation))
|
||||
.setPositiveButton(getString(R.string.omnipod_common_yes)) { _, _ ->
|
||||
(viewModel as DeactivatePodViewModel).discardPod()
|
||||
findNavController().navigate(R.id.action_deactivatePodFragment_to_podDiscardedFragment)
|
||||
}
|
||||
.setNegativeButton(getString(R.string.omnipod_common_no), null)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure() {
|
||||
buttonDiscardPod.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
@IdRes
|
||||
override fun getNextPageActionId(): Int = R.id.action_deactivatePodFragment_to_podDeactivatedFragment
|
||||
|
||||
override fun getIndex(): Int = 2
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.fragment.info
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.dagger.OmnipodPluginQualifier
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.fragment.InfoFragmentBase
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.viewmodel.info.PodDeactivatedViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
class PodDeactivatedFragment : InfoFragmentBase() {
|
||||
|
||||
@Inject
|
||||
@OmnipodPluginQualifier
|
||||
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val vm: PodDeactivatedViewModel by viewModels { viewModelFactory }
|
||||
this.viewModel = vm
|
||||
}
|
||||
|
||||
@IdRes
|
||||
override fun getNextPageActionId(): Int? = null
|
||||
|
||||
override fun getIndex(): Int = 3
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.fragment.info
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.dagger.OmnipodPluginQualifier
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.fragment.InfoFragmentBase
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.viewmodel.info.PodDiscardedViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
class PodDiscardedFragment : InfoFragmentBase() {
|
||||
|
||||
@Inject
|
||||
@OmnipodPluginQualifier
|
||||
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val vm: PodDiscardedViewModel by viewModels { viewModelFactory }
|
||||
this.viewModel = vm
|
||||
}
|
||||
|
||||
@IdRes
|
||||
override fun getNextPageActionId(): Int? = null
|
||||
|
||||
override fun getIndex(): Int = 3
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.fragment.info
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.dagger.OmnipodPluginQualifier
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.fragment.InfoFragmentBase
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.viewmodel.info.StartPodDeactivationViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
class StartPodDeactivationFragment : InfoFragmentBase() {
|
||||
|
||||
@Inject
|
||||
@OmnipodPluginQualifier
|
||||
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val vm: StartPodDeactivationViewModel by viewModels { viewModelFactory }
|
||||
this.viewModel = vm
|
||||
}
|
||||
|
||||
@IdRes
|
||||
override fun getNextPageActionId(): Int = R.id.action_startPodDeactivationFragment_to_deactivatePodFragment
|
||||
|
||||
override fun getIndex(): Int = 1
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.viewmodel.action
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.viewmodel.ActionViewModelBase
|
||||
|
||||
abstract class DeactivatePodViewModel : ActionViewModelBase() {
|
||||
|
||||
abstract fun discardPod()
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.viewmodel.info
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.viewmodel.ViewModelBase
|
||||
|
||||
abstract class PodDeactivatedViewModel : ViewModelBase()
|
|
@ -0,0 +1,5 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.viewmodel.info
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.viewmodel.ViewModelBase
|
||||
|
||||
abstract class PodDiscardedViewModel : ViewModelBase()
|
|
@ -0,0 +1,5 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.viewmodel.info
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.common.viewmodel.ViewModelBase
|
||||
|
||||
abstract class StartPodDeactivationViewModel : ViewModelBase()
|
|
@ -0,0 +1,68 @@
|
|||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_refresh_status"
|
||||
style="@style/ButtonSmallFontStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:drawableTop="@drawable/ic_omnipod_overview_refresh_pod_status"
|
||||
android:drawablePadding="@dimen/omnipod_icon_button_drawable_padding"
|
||||
android:text="@string/refresh" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_pod_management"
|
||||
style="@style/ButtonSmallFontStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:drawableTop="@drawable/ic_omnipod_overview_pod_management"
|
||||
android:drawablePadding="@dimen/omnipod_icon_button_drawable_padding"
|
||||
android:text="@string/omnipod_common_overview_button_pod_management" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_silence_alerts"
|
||||
style="@style/ButtonSmallFontStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:drawableTop="@drawable/ic_omnipod_overview_silence_alerts"
|
||||
android:drawablePadding="@dimen/omnipod_icon_button_drawable_padding"
|
||||
android:text="@string/omnipod_common_overview_button_silence_alerts" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_set_time"
|
||||
style="@style/ButtonSmallFontStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:drawableTop="@drawable/ic_omnipod_overview_set_time"
|
||||
android:drawablePadding="@dimen/omnipod_icon_button_drawable_padding"
|
||||
android:text="@string/omnipod_common_overview_button_set_time"
|
||||
android:visibility="gone" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_resume_delivery"
|
||||
style="@style/ButtonSmallFontStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:drawableTop="@drawable/ic_omnipod_overview_resume_delivery"
|
||||
android:drawablePadding="@dimen/omnipod_icon_button_drawable_padding"
|
||||
android:text="@string/omnipod_common_overview_button_resume_delivery"
|
||||
android:visibility="gone" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_suspend_delivery"
|
||||
style="@style/ButtonSmallFontStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:drawableTop="@drawable/ic_omnipod_overview_suspend_delivery"
|
||||
android:drawablePadding="@dimen/omnipod_icon_button_drawable_padding"
|
||||
android:text="@string/omnipod_common_overview_button_suspend_delivery"
|
||||
android:visibility="gone" />
|
||||
|
||||
</merge>
|
|
@ -0,0 +1,692 @@
|
|||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<!-- Unique ID -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.5"
|
||||
android:gravity="end"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/omnipod_common_overview_pod_unique_id"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pod_address"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Pod Lot -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.5"
|
||||
android:gravity="end"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/omnipod_common_overview_lot_number"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pod_lot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Pod Tid -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.5"
|
||||
android:gravity="end"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/omnipod_common_overview_pod_sequence_number"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pod_tid"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Pod fw version -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.5"
|
||||
android:gravity="end"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/omnipod_common_overview_firmware_version"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/firmware_version"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Pod Time -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.5"
|
||||
android:gravity="end"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/omnipod_common_overview_time_on_pod"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/time_on_pod"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Pod Expires -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.5"
|
||||
android:gravity="end"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/omnipod_common_overview_pod_expiry_date"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pod_expiry_date"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Pod Status -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.5"
|
||||
android:gravity="end"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/omnipod_common_overview_pod_status"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<com.joanzapata.iconify.widget.IconTextView
|
||||
android:id="@+id/pod_status"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text=""
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/queue"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text=""
|
||||
android:textAlignment="center" />
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@color/list_delimiter" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.5"
|
||||
android:gravity="end"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/omnipod_common_overview_last_connection"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/last_connection"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@color/list_delimiter" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.5"
|
||||
android:gravity="end"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/omnipod_common_overview_last_bolus"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/last_bolus"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@color/list_delimiter" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.5"
|
||||
android:gravity="end"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/omnipod_common_overview_base_basal_rate"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/base_basal_rate"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@color/list_delimiter" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.5"
|
||||
android:gravity="end"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/omnipod_common_overview_temp_basal_rate"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/temp_basal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@color/list_delimiter" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.5"
|
||||
android:gravity="end"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/omnipod_common_overview_reservoir"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/reservoir"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@color/list_delimiter" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.5"
|
||||
android:gravity="end"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/omnipod_common_overview_total_delivered"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/total_delivered"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@color/list_delimiter" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.5"
|
||||
android:gravity="end"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/omnipod_common_overview_errors"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/errors"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@color/list_delimiter" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.5"
|
||||
android:gravity="end"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/omnipod_common_overview_pod_active_alerts"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pod_active_alerts"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@color/list_delimiter" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:paddingTop="10dp"
|
||||
android:rotationX="180"
|
||||
android:rotationY="180"
|
||||
app:drawableTopCompat="@drawable/ic_pod" />
|
||||
</merge>
|
|
@ -11,5 +11,5 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
app:navGraph="@navigation/omnipod_pod_deactivation_wizard_navigation_graph" />
|
||||
app:navGraph="@navigation/omnipod_common_pod_deactivation_wizard_navigation_graph" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -56,7 +56,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:text="@string/omnipod_wizard_button_deactivate_pod"
|
||||
android:text="@string/omnipod_common_wizard_button_deactivate_pod"
|
||||
android:visibility="gone" />
|
||||
|
||||
<Button
|
||||
|
@ -64,7 +64,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:text="@string/omnipod_wizard_button_discard_pod"
|
||||
android:text="@string/omnipod_common_wizard_button_discard_pod"
|
||||
android:visibility="gone" />
|
||||
|
||||
<Button
|
||||
|
@ -72,7 +72,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:text="@string/omnipod_wizard_button_retry"
|
||||
android:text="@string/omnipod_common_wizard_button_retry"
|
||||
android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
|
@ -5,9 +5,7 @@
|
|||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
android:id="@+id/progress_indication_layout"
|
||||
layout="@layout/omnipod_wizard_progress_indication" />
|
||||
<include layout="@layout/omnipod_common_wizard_progress_indication" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fragment_title"
|
||||
|
@ -30,5 +28,5 @@
|
|||
|
||||
<include
|
||||
android:id="@+id/nav_buttons_layout"
|
||||
layout="@layout/omnipod_wizard_nav_buttons" />
|
||||
layout="@layout/omnipod_common_wizard_nav_buttons" />
|
||||
</LinearLayout>
|
|
@ -9,12 +9,12 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/omnipod_wizard_button_cancel" />
|
||||
android:text="@string/omnipod_common_wizard_button_cancel" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_next"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/omnipod_wizard_button_next" />
|
||||
android:text="@string/omnipod_common_wizard_button_next" />
|
||||
</LinearLayout>
|
|
@ -1,8 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_indication"
|
||||
|
@ -13,4 +10,4 @@
|
|||
android:progress="0"
|
||||
android:progressTint="@color/omnipod_wizard_progress_bar"
|
||||
android:scaleY=".5" />
|
||||
</LinearLayout>
|
||||
</merge>
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
app:startDestination="@id/startPodActivationFragment">
|
||||
<fragment
|
||||
android:id="@+id/startPodActivationFragment"
|
||||
android:name="info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.fragment.info.StartPodActivationFragment"
|
||||
android:label="StartPodActivationFragment">
|
||||
<action
|
||||
android:id="@+id/action_startPodActivationFragment_to_initializePodFragment"
|
||||
app:destination="@id/initializePodFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/initializePodFragment"
|
||||
android:name="info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.fragment.action.InitializePodFragment"
|
||||
android:label="InitializePodFragment">
|
||||
<action
|
||||
android:id="@+id/action_initializePodFragment_to_attachPodFragment"
|
||||
app:destination="@id/attachPodFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/attachPodFragment"
|
||||
android:name="info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.fragment.info.AttachPodFragment"
|
||||
android:label="AttachPodFragment">
|
||||
<action
|
||||
android:id="@+id/action_attachPodFragment_to_insertCannulaFragment"
|
||||
app:destination="@id/insertCannulaFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/insertCannulaFragment"
|
||||
android:name="info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.fragment.action.InsertCannulaFragment"
|
||||
android:label="InsertCannulaFragment">
|
||||
<action
|
||||
android:id="@+id/action_insertCannulaFragment_to_PodActivatedFragment"
|
||||
app:destination="@id/PodActivatedFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/PodActivatedFragment"
|
||||
android:name="info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.fragment.info.PodActivatedFragment"
|
||||
android:label="PodActivatedFragment" />
|
||||
</navigation>
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
app:startDestination="@id/startPodDeactivationFragment">
|
||||
<fragment
|
||||
android:id="@+id/startPodDeactivationFragment"
|
||||
android:name="info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.fragment.info.StartPodDeactivationFragment"
|
||||
android:label="StartPodDeactivationFragment">
|
||||
<action
|
||||
android:id="@+id/action_startPodDeactivationFragment_to_deactivatePodFragment"
|
||||
app:destination="@id/deactivatePodFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/deactivatePodFragment"
|
||||
android:name="info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.fragment.action.DeactivatePodFragment"
|
||||
android:label="DeactivatePodFragment">
|
||||
<action
|
||||
android:id="@+id/action_deactivatePodFragment_to_podDeactivatedFragment"
|
||||
app:destination="@id/podDeactivatedFragment" />
|
||||
<action
|
||||
android:id="@+id/action_deactivatePodFragment_to_podDiscardedFragment"
|
||||
app:destination="@id/podDiscardedFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/podDeactivatedFragment"
|
||||
android:name="info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.fragment.info.PodDeactivatedFragment"
|
||||
android:label="PodDeactivatedFragment" />
|
||||
<fragment
|
||||
android:id="@+id/podDiscardedFragment"
|
||||
android:name="info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.fragment.info.PodDiscardedFragment"
|
||||
android:label="PodDiscardedFragment" />
|
||||
</navigation>
|
39
omnipod-common/src/main/res/values/colors.xml
Normal file
39
omnipod-common/src/main/res/values/colors.xml
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Button icons - general -->
|
||||
<color name="pod_icon_outline">#9E9E9E</color>
|
||||
|
||||
<!-- Omnipod Wizard -->
|
||||
<color name="omnipod_wizard_progress_bar">#0099CC</color>
|
||||
<color name="omnipod_wizard_finish_button">#ff669900</color>
|
||||
<color name="icon_omnipod_wizard_success">#77DD77</color>
|
||||
|
||||
<!-- Omnipod tab - Button icons -->
|
||||
<color name="ic_omnipod_overview_acknowledge_alerts">#FF4444</color>
|
||||
<color name="ic_omnipod_overview_acknowledge_alerts_outline">@color/pod_icon_outline</color>
|
||||
<color name="ic_omnipod_overview_pod_management">#4CAF50</color>
|
||||
<color name="ic_omnipod_overview_pod_management_graph">@color/pod_icon_outline</color>
|
||||
<color name="ic_omnipod_overview_pod_management_outline">@color/pod_icon_outline</color>
|
||||
<color name="ic_omnipod_overview_refresh_pod_status">#42A5F5</color>
|
||||
<color name="ic_omnipod_overview_refresh_pod_status_outline">@color/pod_icon_outline</color>
|
||||
<color name="ic_omnipod_overview_resume_delivery">#67E86A</color>
|
||||
<color name="ic_omnipod_overview_resume_delivery_outline">@color/pod_icon_outline</color>
|
||||
<color name="ic_omnipod_overview_set_time">#B39DDB</color>
|
||||
<color name="ic_omnipod_overview_set_time_outline">@color/pod_icon_outline</color>
|
||||
<color name="ic_omnipod_overview_suspend_delivery">#ffbf00</color>
|
||||
<color name="ic_omnipod_overview_suspend_delivery_outline">@color/pod_icon_outline</color>
|
||||
|
||||
<!-- Pod Management - Button icons -->
|
||||
<color name="ic_pod_management_activate_pod">#67E86A</color>
|
||||
<color name="ic_pod_management_activate_pod_outline">@color/pod_icon_outline</color>
|
||||
<color name="ic_pod_management_deactivate_pod">#FF4444</color>
|
||||
<color name="ic_pod_management_deactivate_pod_outline">@color/pod_icon_outline</color>
|
||||
<color name="ic_pod_management_discard_pod">#85F803</color>
|
||||
<color name="ic_pod_management_discard_pod_outline">@color/pod_icon_outline</color>
|
||||
<color name="ic_pod_management_play_test_beep">#ffbf00</color>
|
||||
<color name="ic_pod_management_play_test_beep_outline">@color/pod_icon_outline</color>
|
||||
<color name="ic_pod_management_pulse_log">#4DD0E1</color>
|
||||
<color name="ic_pod_management_pulse_log_outline">@color/pod_icon_outline</color>
|
||||
<color name="ic_pod_management_pod_history">#FB8C00</color>
|
||||
<color name="ic_pod_management_pod_history_outline">@color/pod_icon_outline</color>
|
||||
</resources>
|
219
omnipod-common/src/main/res/values/strings.xml
Normal file
219
omnipod-common/src/main/res/values/strings.xml
Normal file
|
@ -0,0 +1,219 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Omnipod - Keys -->
|
||||
<string name="key_omnipod_common_bolus_beeps_enabled" translatable="false">AAPS.Omnipod.bolus_beeps_enabled</string>
|
||||
<string name="key_omnipod_common_basal_beeps_enabled" translatable="false">AAPS.Omnipod.basal_beeps_enabled</string>
|
||||
<string name="key_omnipod_common_smb_beeps_enabled" translatable="false">AAPS.Omnipod.smb_beeps_enabled</string>
|
||||
<string name="key_omnipod_common_tbr_beeps_enabled" translatable="false">AAPS.Omnipod.tbr_beeps_enabled</string>
|
||||
<string name="key_omnipod_common_suspend_delivery_button_enabled" translatable="false">AAPS.Omnipod.suspend_delivery_button_enabled</string>
|
||||
<string name="key_omnipod_common_time_change_event_enabled" translatable="false">AAPS.Omnipod.time_change_enabled</string>
|
||||
<string name="key_omnipod_common_expiration_reminder_enabled" translatable="false">AAPS.Omnipod.expiration_reminder_enabled</string>
|
||||
<string name="key_omnipod_common_expiration_reminder_hours_before_shutdown" translatable="false">AAPS.Omnipod.expiration_reminder_hours_before_shutdown</string>
|
||||
<string name="key_omnipod_common_low_reservoir_alert_enabled" translatable="false">AAPS.Omnipod.low_reservoir_alert_enabled</string>
|
||||
<string name="key_omnipod_common_low_reservoir_alert_units" translatable="false">AAPS.Omnipod.low_reservoir_alert_units</string>
|
||||
<string name="key_omnipod_common_automatically_silence_alerts_enabled" translatable="false">AAPS.Omnipod.automatically_acknowledge_alerts_enabled</string>
|
||||
|
||||
<!-- Omnipod - Pod Management -->
|
||||
<string name="omnipod_common_pod_management_title">Pod Management</string>
|
||||
<string name="omnipod_common_pod_management_heading_actions">Actions</string>
|
||||
<string name="omnipod_common_pod_management_heading_tools">Tools</string>
|
||||
<string name="omnipod_common_pod_management_button_activate_pod">Activate Pod</string>
|
||||
<string name="omnipod_common_pod_management_button_deactivate_pod">Deactivate Pod</string>
|
||||
<string name="omnipod_common_pod_management_button_discard_pod">Discard Pod</string>
|
||||
<string name="omnipod_common_pod_management_discard_pod_confirmation">If you discard the Pod, you will not be able to communicate with it anymore. You should only do this when all communication with the Pod persistently fails. If you can still communicate with the Pod, please use the <b>Deactivate Pod</b> option.\n\nIf you wish to proceed, please make sure to remove the Pod from your body!</string>
|
||||
<string name="omnipod_common_pod_management_button_play_test_beep">Play Test Beep</string>
|
||||
<string name="omnipod_common_pod_management_button_playing_test_beep">Playing Test Beep…</string>
|
||||
<string name="omnipod_common_pod_management_button_pod_history">Pod History</string>
|
||||
|
||||
<!-- Omnipod - Error -->
|
||||
<string name="omnipod_common_error_pod_not_attached">No active Pod</string>
|
||||
<string name="omnipod_common_error_set_basal_failed">Setting basal profile failed.</string>
|
||||
<string name="omnipod_common_error_bolus_did_not_succeed">Bolus did not succeed.</string>
|
||||
<string name="omnipod_common_error_failed_to_set_profile_empty_profile">Failed to set basal profile: received an empty profile. Make sure to activate your basal profile.</string>
|
||||
<string name="omnipod_common_error_set_initial_basal_schedule_no_profile">No basal profile is active. Make sure to activate your basal profile.</string>
|
||||
<string name="omnipod_common_error_unsupported_custom_command">Unsupported custom command: %1$s</string>
|
||||
<string name="omnipod_common_error_failed_to_refresh_status">Failed to refresh status</string>
|
||||
<string name="omnipod_common_error_failed_to_refresh_status_on_startup">Failed to refresh status on startup</string>
|
||||
<string name="omnipod_common_error_failed_to_silence_alerts">Failed to silence alerts</string>
|
||||
<string name="omnipod_common_error_failed_to_suspend_delivery">Failed to suspend delivery</string>
|
||||
<string name="omnipod_common_error_failed_to_set_time">Failed to set time</string>
|
||||
<string name="omnipod_common_error_failed_to_resume_delivery">Failed to resume delivery</string>
|
||||
<string name="omnipod_common_error_failed_to_initialize_pod">Failed to initialize the Pod</string>
|
||||
<string name="omnipod_common_error_failed_to_insert_cannula">Failed to insert cannula</string>
|
||||
<string name="omnipod_common_error_pod_fault_activation_time_exceeded">The Pod\'s activation time has been exceeded. This Pod can no longer be activated.</string>
|
||||
<string name="omnipod_common_error_failed_to_verify_activation_progress">Failed to verify activation progress. Please retry.</string>
|
||||
<string name="omnipod_common_error_pod_suspended">Pod suspended</string>
|
||||
<string name="omnipod_common_error_failed_to_play_test_beep">Failed to play test beep</string>
|
||||
<string name="omnipod_common_error_time_out_of_sync">The time on the Pod is out of sync. Please update the time in the Omnipod tab.</string>
|
||||
<string name="omnipod_common_error_unexpected_exception">An unexpected error occurred. Please report! (%1$s: %2$s).</string>
|
||||
|
||||
<!-- Omnipod - Confirmation -->
|
||||
<string name="omnipod_common_confirmation">Confirmation</string>
|
||||
<string name="omnipod_common_confirmation_time_or_timezone_change">Time and/or time zone changed on the Pod.</string>
|
||||
<string name="omnipod_common_confirmation_expiration_alerts_updated">Alert configuration has been updated in the Pod.</string>
|
||||
<string name="omnipod_common_confirmation_time_on_pod_updated">The time on the Pod has been updated.</string>
|
||||
<string name="omnipod_common_confirmation_suspended_delivery">All insulin delivery has been suspended.</string>
|
||||
<string name="omnipod_common_confirmation_silenced_alerts">Active alerts have been silenced.</string>
|
||||
<string name="omnipod_common_confirmation_delivery_resumed">Insulin delivery has been resumed.</string>
|
||||
|
||||
<!-- Omnipod - Overview -->
|
||||
<string name="omnipod_common_overview_button_set_time">Set time</string>
|
||||
<string name="omnipod_common_overview_button_suspend_delivery">Suspend</string>
|
||||
<string name="omnipod_common_overview_button_resume_delivery">Resume Delivery</string>
|
||||
<string name="omnipod_common_overview_button_pod_management">Pod Mgmt</string>
|
||||
<string name="omnipod_common_overview_button_silence_alerts">Silence Alerts</string>
|
||||
<string name="omnipod_common_overview_pod_status">Pod Status</string>
|
||||
<string name="omnipod_common_overview_total_delivered">Total Delivered</string>
|
||||
<string name="omnipod_common_overview_total_delivered_value">%1$.2f U</string>
|
||||
<string name="omnipod_common_overview_pod_unique_id">Unique ID</string>
|
||||
<string name="omnipod_common_overview_lot_number">LOT Number</string>
|
||||
<string name="omnipod_common_overview_pod_sequence_number">Sequence Number</string>
|
||||
<string name="omnipod_common_overview_pod_expiry_date">Pod Expires</string>
|
||||
<string name="omnipod_common_overview_last_connection">Last Connection</string>
|
||||
<string name="omnipod_common_overview_last_bolus">Last Bolus</string>
|
||||
<string name="omnipod_common_overview_temp_basal_rate">Temp Basal Rate</string>
|
||||
<string name="omnipod_common_overview_base_basal_rate">Base Basal Rate</string>
|
||||
<string name="omnipod_common_overview_reservoir">Reservoir</string>
|
||||
<string name="omnipod_common_overview_pod_active_alerts">Active Pod Alerts</string>
|
||||
<string name="omnipod_common_overview_firmware_version">Firmware Version</string>
|
||||
<string name="omnipod_common_overview_time_on_pod">Time on Pod</string>
|
||||
<string name="omnipod_common_overview_temp_basal_value">%1$.2fU/h @%2$s (%3$d/%4$d minutes)</string>
|
||||
<string name="omnipod_common_overview_reservoir_value">%1$.2f U left</string>
|
||||
<string name="omnipod_common_overview_reservoir_value_over50">Over 50 U left</string>
|
||||
<string name="omnipod_common_overview_errors">Errors</string>
|
||||
<string name="omnipod_common_overview_last_bolus_value" translatable="false">%1$.2f %2$s (%3$s)</string>
|
||||
|
||||
<!-- Omnipod - Wizard Base -->
|
||||
<string name="omnipod_common_wizard_button_cancel">Cancel</string>
|
||||
<string name="omnipod_common_wizard_button_finish">Finish</string>
|
||||
<string name="omnipod_common_wizard_button_next">Next</string>
|
||||
<string name="omnipod_common_wizard_button_retry">Retry</string>
|
||||
<string name="omnipod_common_wizard_button_deactivate_pod">Deactivate Pod</string>
|
||||
<string name="omnipod_common_wizard_button_discard_pod">Discard Pod</string>
|
||||
<string name="omnipod_common_wizard_exit_confirmation_text">You haven\'t completed all steps yet. Are you sure you want to exit?</string>
|
||||
<string name="omnipod_common_wizard_exit_confirmation_title">Exit</string>
|
||||
|
||||
<!-- Omnipod - Pod Activation Wizard -->
|
||||
<string name="omnipod_common_pod_activation_wizard_start_pod_activation_title">Fill Pod</string>
|
||||
<string name="omnipod_common_pod_activation_wizard_initialize_pod_title">Initialize Pod</string>
|
||||
<string name="omnipod_common_pod_activation_wizard_attach_pod_title">Attach Pod</string>
|
||||
<string name="omnipod_common_pod_activation_wizard_attach_pod_text">Prepare the infusion site. Remove the Pod\'s needle cap and adhesive backing and attach the Pod to the infusion site.\n\nIf the cannula sticks out, please press <b>Cancel</b> and discard your Pod.\n\nPress <b>Next</b> to insert the cannula and begin basal delivery.</string>
|
||||
<string name="omnipod_common_pod_activation_wizard_attach_pod_confirm_insert_cannula_text">When you press <b>OK</b>, the cannula will be inserted. Make sure that you have attached the Pod to the infusion site.</string>
|
||||
<string name="omnipod_common_pod_activation_wizard_insert_cannula_title">Insert Cannula</string>
|
||||
<string name="omnipod_common_pod_activation_wizard_insert_cannula_text">Trying to set initial basal schedule and insert the cannula.\n\nWhen the cannula has successfully been inserted, you can press <b>Next</b>.</string>
|
||||
<string name="omnipod_common_pod_activation_wizard_pod_activated_title">Pod Activated</string>
|
||||
<string name="omnipod_common_pod_activation_wizard_pod_activated_text">The new Pod is now active.\n\nYour basal schedule has been programmed and the cannula has been inserted.\n\nPlease verify that the cannula has been inserted correctly and change your Pod if you think it has not.</string>
|
||||
|
||||
<!-- Omnipod - Pod Deactivation Wizard -->
|
||||
<string name="omnipod_common_pod_deactivation_wizard_start_pod_deactivation_title">Deactivate Pod</string>
|
||||
<string name="omnipod_common_pod_deactivation_wizard_start_pod_deactivation_text">Press <b>Next</b> to deactivate the Pod.\n\n<b>Note:</b> This will suspend all insulin delivery and deactivate the Pod.</string>
|
||||
<string name="omnipod_common_pod_deactivation_wizard_deactivating_pod_title">Deactivating Pod</string>
|
||||
<string name="omnipod_common_pod_deactivation_wizard_deactivating_pod_text">Deactivating the Pod.\n\nWhen deactivation has completed successfully, you can press <b>Next</b>.</string>
|
||||
<string name="omnipod_common_pod_deactivation_wizard_pod_deactivated_title">Pod Deactivated</string>
|
||||
<string name="omnipod_common_pod_deactivation_wizard_pod_deactivated_text">Your Pod has been deactivated.\n\nPlease remove the Pod from your body and recycle it.</string>
|
||||
<string name="omnipod_common_pod_deactivation_wizard_pod_discarded_title">Pod Discarded</string>
|
||||
<string name="omnipod_common_pod_deactivation_wizard_pod_discarded_text">The Pod state has been discarded. Insulin delivery has not been suspended because the Pod has not been properly deactivated!\n\nPlease remove the Pod from your body and recycle it.</string>
|
||||
<string name="omnipod_common_pod_deactivation_wizard_discard_pod_confirmation">If you discard the Pod, you will not be able to communicate with it anymore. You should only do this when all communication with the Pod persistently fails. Are you sure you want to discard the Pod?</string>
|
||||
<string name="omnipod_common_pod_deactivation_wizard_discard_pod">Discard Pod</string>
|
||||
|
||||
<!-- Omnipod - Preferences -->
|
||||
<string name="omnipod_common_preferences_bolus_beeps_enabled">Bolus beeps enabled</string>
|
||||
<string name="omnipod_common_preferences_basal_beeps_enabled">Basal beeps enabled</string>
|
||||
<string name="omnipod_common_preferences_smb_beeps_enabled">SMB beeps enabled</string>
|
||||
<string name="omnipod_common_preferences_tbr_beeps_enabled">TBR beeps enabled</string>
|
||||
<string name="omnipod_common_preferences_suspend_delivery_button_enabled">Show Suspend Delivery button in Omnipod tab</string>
|
||||
<string name="omnipod_common_preferences_time_change_enabled">DST/Time zone detection enabled</string>
|
||||
<string name="omnipod_common_preferences_expiration_reminder_enabled">Expiration reminder enabled</string>
|
||||
<string name="omnipod_common_preferences_expiration_reminder_hours_before_shutdown">Hours before shutdown</string>
|
||||
<string name="omnipod_common_preferences_low_reservoir_alert_enabled">Low reservoir alert enabled</string>
|
||||
<string name="omnipod_common_preferences_low_reservoir_alert_units">Number of units</string>
|
||||
<string name="omnipod_common_preferences_automatically_silence_alerts">Automatically silence Pod alerts</string>
|
||||
<string name="omnipod_common_preferences_category_other">Other</string>
|
||||
<string name="omnipod_common_preferences_category_alerts">Alerts</string>
|
||||
<string name="omnipod_common_preferences_category_confirmation_beeps">Confirmation Beeps</string>
|
||||
|
||||
<!-- Omnipod - Pod Status -->
|
||||
<string name="omnipod_common_pod_status_no_active_pod">No Active Pod</string>
|
||||
<string name="omnipod_common_pod_status_waiting_for_activation">Setup in progress (waiting for Pod activation)</string>
|
||||
<string name="omnipod_common_pod_status_waiting_for_cannula_insertion">Setup in progress (waiting for cannula insertion)</string>
|
||||
<string name="omnipod_common_pod_status_running">Running</string>
|
||||
<string name="omnipod_common_pod_status_suspended">Suspended</string>
|
||||
<string name="omnipod_common_pod_status_pod_fault">Pod Fault</string>
|
||||
<string name="omnipod_common_pod_status_activation_time_exceeded">Activation time exceeded</string>
|
||||
<string name="omnipod_common_pod_status_inactive">Inactive</string>
|
||||
<string name="omnipod_common_pod_status_pod_fault_description">Pod Fault: %1$03d %2$s</string>
|
||||
|
||||
<!-- Omnipod - Commands -->
|
||||
<string name="omnipod_common_cmd_deactivate_pod">Deactivate Pod</string>
|
||||
<string name="omnipod_common_cmd_discard_pod">Discard Pod</string>
|
||||
<string name="omnipod_common_cmd_set_bolus">Set Bolus</string>
|
||||
<string name="omnipod_common_cmd_cancel_bolus">Cancel Bolus</string>
|
||||
<string name="omnipod_common_cmd_set_tbr">Set Temporary Basal</string>
|
||||
<string name="omnipod_common_cmd_cancel_tbr_by_driver">Cancel Temporary Basal (internally by driver)</string>
|
||||
<string name="omnipod_common_cmd_cancel_tbr">Cancel Temporary Basal</string>
|
||||
<string name="omnipod_common_cmd_set_basal_schedule">Set Basal Schedule</string>
|
||||
<string name="omnipod_common_cmd_get_pod_status">Get Pod Status</string>
|
||||
<string name="omnipod_common_cmd_get_pod_info">Get Pod Info</string>
|
||||
<string name="omnipod_common_cmd_set_time">Set Time</string>
|
||||
<string name="omnipod_common_cmd_configure_alerts">Configure Alerts</string>
|
||||
<string name="omnipod_common_cmd_silence_alerts">Silence Alerts</string>
|
||||
<string name="omnipod_common_cmd_suspend_delivery">Suspend Delivery</string>
|
||||
<string name="omnipod_common_cmd_resume_delivery">Resume Delivery</string>
|
||||
<string name="omnipod_common_cmd_unknown_entry">Unknown Entry</string>
|
||||
<string name="omnipod_common_cmd_initialize_pod">Initialize Pod</string>
|
||||
<string name="omnipod_common_cmd_insert_cannula">Insert Cannula</string>
|
||||
<string name="omnipod_common_cmd_read_pulse_log">Read Pulse Log</string>
|
||||
<string name="omnipod_common_cmd_set_fake_suspended_tbr">Set fake temporary basal because the Pod is suspended</string>
|
||||
<string name="omnipod_common_cmd_cancel_fake_suspended_tbr">Cancel fake temporary basal that was created because the Pod was suspended</string>
|
||||
<string name="omnipod_common_cmd_split_tbr">Split temporary basal because of uncertain failure in cancellation</string>
|
||||
<string name="omnipod_common_cmd_beep_config">Beep Config</string>
|
||||
<string name="omnipod_common_cmd_play_test_beep">Play Test Beep</string>
|
||||
|
||||
<!-- Omnipod - Alerts -->
|
||||
<string name="omnipod_common_alert_finish_pairing_reminder">Finish pairing reminder</string>
|
||||
<string name="omnipod_common_alert_finish_setup_reminder_reminder">Finish setup reminder</string>
|
||||
<string name="omnipod_common_alert_expiration">Pod will expire soon</string>
|
||||
<string name="omnipod_common_alert_expiration_advisory">Pod will expire soon</string>
|
||||
<string name="omnipod_common_alert_shutdown_imminent">Shutdown is imminent</string>
|
||||
<string name="omnipod_common_alert_low_reservoir">Low Reservoir</string>
|
||||
<string name="omnipod_common_alert_unknown_alert">Unknown Alert</string>
|
||||
|
||||
<!-- Omnipod - Short status -->
|
||||
<string name="omnipod_common_short_status_no_active_pod">No Active Pod</string>
|
||||
<string name="omnipod_common_short_status_last_connection">LastConn: %1$d min ago</string>
|
||||
<string name="omnipod_common_short_status_last_bolus">LastBolus: %1$s @ %2$s</string>
|
||||
<string name="omnipod_common_short_status_temp_basal">Temp: %1$s</string>
|
||||
<string name="omnipod_common_short_status_extended_bolus">Extended: %1$s</string>
|
||||
<string name="omnipod_common_short_status_reservoir">Reserv: %1$sU</string>
|
||||
|
||||
<!-- Omnipod - Other -->
|
||||
<string name="omnipod_common_yes">Yes</string>
|
||||
<string name="omnipod_common_no">No</string>
|
||||
<string name="omnipod_common_ok">OK</string>
|
||||
<string name="omnipod_common_cancel">Cancel</string>
|
||||
<string name="omnipod_common_warning">Warning</string>
|
||||
<string name="omnipod_common_two_strings_concatenated_by_colon" translatable="false">%1$s: %2$s</string>
|
||||
|
||||
<!-- Omnipod - Times -->
|
||||
<string name="omnipod_common_time_with_timezone" translatable="false">%1$s (%2$s)</string>
|
||||
<string name="omnipod_common_moments_ago">Moments ago</string>
|
||||
<string name="omnipod_common_less_than_a_minute_ago">Less than a minute ago</string>
|
||||
<string name="omnipod_common_composite_time">%1$s and %2$s</string>
|
||||
<string name="omnipod_common_time_ago">%1$s ago</string>
|
||||
<plurals name="omnipod_common_minutes">
|
||||
<item quantity="one">%1$d minute</item>
|
||||
<item quantity="other">%1$d minutes</item>
|
||||
</plurals>
|
||||
<plurals name="omnipod_common_hours">
|
||||
<item quantity="one">%1$d hour</item>
|
||||
<item quantity="other">%1$d hours</item>
|
||||
</plurals>
|
||||
<plurals name="omnipod_common_days">
|
||||
<item quantity="one">%1$d day</item>
|
||||
<item quantity="other">%1$d days</item>
|
||||
</plurals>
|
||||
<plurals name="omnipod_common_pod_alerts">
|
||||
<item quantity="one">Pod Alert: %1$s</item>
|
||||
<item quantity="other">Pod Alerts: %1$s</item>
|
||||
</plurals>
|
||||
</resources>
|
|
@ -16,4 +16,5 @@ android {
|
|||
|
||||
dependencies {
|
||||
implementation project(':core')
|
||||
implementation project(':omnipod-common')
|
||||
}
|
|
@ -1,4 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="info.nightscout.androidaps.plugins.pump.omnipod.dash">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="info.nightscout.androidaps.plugins.pump.omnipod.dash">
|
||||
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
</manifest>
|
|
@ -1,5 +1,207 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash;
|
||||
|
||||
public class OmnipodDashPumpPlugin {
|
||||
// TODO
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import dagger.android.HasAndroidInjector;
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
import info.nightscout.androidaps.interfaces.CommandQueueProvider;
|
||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||
import info.nightscout.androidaps.interfaces.PluginType;
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.interfaces.PumpPluginBase;
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.logging.LTag;
|
||||
import info.nightscout.androidaps.plugins.common.ManufacturerType;
|
||||
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.defs.PumpType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.OmnipodDashOverviewFragment;
|
||||
import info.nightscout.androidaps.queue.commands.CustomCommand;
|
||||
import info.nightscout.androidaps.utils.TimeChangeType;
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
||||
|
||||
@Singleton
|
||||
public class OmnipodDashPumpPlugin extends PumpPluginBase implements PumpInterface {
|
||||
private static final PumpDescription PUMP_DESCRIPTION = new PumpDescription(PumpType.Omnipod_Dash);
|
||||
|
||||
private final AAPSLogger aapsLogger;
|
||||
private final ResourceHelper resourceHelper;
|
||||
private final CommandQueueProvider commandQueue;
|
||||
|
||||
@Inject
|
||||
public OmnipodDashPumpPlugin(HasAndroidInjector injector, AAPSLogger aapsLogger, ResourceHelper resourceHelper, CommandQueueProvider commandQueue) {
|
||||
super(new PluginDescription() //
|
||||
.mainType(PluginType.PUMP) //
|
||||
.fragmentClass(OmnipodDashOverviewFragment.class.getName()) //
|
||||
.pluginIcon(R.drawable.ic_pod_128)
|
||||
.pluginName(R.string.omnipod_dash_name) //
|
||||
.shortName(R.string.omnipod_dash_name_short) //
|
||||
.preferencesId(R.xml.omnipod_dash_preferences) //
|
||||
.description(R.string.omnipod_dash_pump_description), injector, aapsLogger, resourceHelper, commandQueue);
|
||||
this.aapsLogger = aapsLogger;
|
||||
this.resourceHelper = resourceHelper;
|
||||
this.commandQueue = commandQueue;
|
||||
}
|
||||
|
||||
@Override public boolean isInitialized() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean isSuspended() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean isBusy() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean isConnected() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean isConnecting() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean isHandshakeInProgress() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public void finishHandshaking() {
|
||||
|
||||
}
|
||||
|
||||
@Override public void connect(@NotNull String reason) {
|
||||
|
||||
}
|
||||
|
||||
@Override public void disconnect(@NotNull String reason) {
|
||||
|
||||
}
|
||||
|
||||
@Override public void stopConnecting() {
|
||||
|
||||
}
|
||||
|
||||
@Override public void getPumpStatus(@NotNull String reason) {
|
||||
|
||||
}
|
||||
|
||||
@NotNull @Override public PumpEnactResult setNewBasalProfile(@NotNull Profile profile) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public boolean isThisProfileSet(@NotNull Profile profile) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public long lastDataTime() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override public double getBaseBasalRate() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override public double getReservoirLevel() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override public int getBatteryLevel() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@NotNull @Override public PumpEnactResult deliverTreatment(@NotNull DetailedBolusInfo detailedBolusInfo) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public void stopBolusDelivering() {
|
||||
|
||||
}
|
||||
|
||||
@NotNull @Override public PumpEnactResult setTempBasalAbsolute(double absoluteRate, int durationInMinutes, @NotNull Profile profile, boolean enforceNew) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull @Override public PumpEnactResult setTempBasalPercent(int percent, int durationInMinutes, @NotNull Profile profile, boolean enforceNew) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull @Override public PumpEnactResult setExtendedBolus(double insulin, int durationInMinutes) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull @Override public PumpEnactResult cancelTempBasal(boolean enforceNew) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull @Override public PumpEnactResult cancelExtendedBolus() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull @Override public JSONObject getJSONStatus(@NotNull Profile profile, @NotNull String profileName, @NotNull String version) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull @Override public ManufacturerType manufacturer() {
|
||||
return getPumpDescription().pumpType.getManufacturer();
|
||||
}
|
||||
|
||||
@NotNull @Override public PumpType model() {
|
||||
return getPumpDescription().pumpType;
|
||||
}
|
||||
|
||||
@NotNull @Override public String serialNumber() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull @Override public PumpDescription getPumpDescription() {
|
||||
return PUMP_DESCRIPTION;
|
||||
}
|
||||
|
||||
@NotNull @Override public String shortStatus(boolean veryShort) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public boolean isFakingTempsByExtendedBoluses() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull @Override public PumpEnactResult loadTDDs() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public boolean canHandleDST() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CustomAction> getCustomActions() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeCustomAction(@NotNull CustomActionType customActionType) {
|
||||
aapsLogger.warn(LTag.PUMP, "Unsupported custom action: " + customActionType);
|
||||
}
|
||||
|
||||
@Nullable @Override public PumpEnactResult executeCustomCommand(@NotNull CustomCommand customCommand) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public void timezoneOrDSTChanged(@NotNull TimeChangeType timeChangeType) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.dagger
|
||||
|
||||
import dagger.Module
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
abstract class OmnipodDashModule {
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod;
|
||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver;
|
||||
|
||||
public class OmnipodDashManager {
|
||||
public interface OmnipodDashManager {
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm;
|
||||
|
||||
public interface OmnipodDashCommunicationManager {
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.CrcUtil;
|
||||
|
||||
abstract class CommandBase implements Command {
|
||||
static final short HEADER_LENGTH = 6;
|
||||
|
||||
final CommandType commandType;
|
||||
final int address;
|
||||
final short sequenceNumber;
|
||||
final boolean unknown;
|
||||
|
||||
CommandBase(CommandType commandType, int address, short sequenceNumber, boolean unknown) {
|
||||
this.commandType = commandType;
|
||||
this.address = address;
|
||||
this.sequenceNumber = sequenceNumber;
|
||||
this.unknown = unknown;
|
||||
}
|
||||
|
||||
@Override public CommandType getCommandType() {
|
||||
return commandType;
|
||||
}
|
||||
|
||||
public int getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public short getSequenceNumber() {
|
||||
return sequenceNumber;
|
||||
}
|
||||
|
||||
public boolean isUnknown() {
|
||||
return unknown;
|
||||
}
|
||||
|
||||
static byte[] formatCommand(byte[] command) {
|
||||
List<Byte> temp = new ArrayList<>();
|
||||
|
||||
byte[] prefix = "S0.0=".getBytes(StandardCharsets.UTF_8);
|
||||
for (byte b : prefix) {
|
||||
temp.add(b);
|
||||
}
|
||||
|
||||
byte[] length = ByteBuffer.allocate(2).putShort((short) command.length).array();
|
||||
for (int i = 0; i < 2; i++) {
|
||||
temp.add(length[i]);
|
||||
}
|
||||
|
||||
// Append command
|
||||
for (byte b : command) {
|
||||
temp.add(b);
|
||||
}
|
||||
|
||||
byte[] suffix = ",G0.0".getBytes(StandardCharsets.UTF_8);
|
||||
for (byte b : suffix) {
|
||||
temp.add(b);
|
||||
}
|
||||
|
||||
byte[] out = new byte[((short) temp.size())];
|
||||
for (int i2 = 0; i2 < temp.size(); i2++) {
|
||||
out[i2] = temp.get(i2);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static byte[] appendCrc(byte[] command) {
|
||||
return ByteBuffer.allocate(command.length + 2) //
|
||||
.put(command) //
|
||||
.putShort(CrcUtil.createCrc(command)) //
|
||||
.array();
|
||||
}
|
||||
|
||||
static byte[] encodeHeader(int address, short sequenceNumber, short length, boolean unknown) {
|
||||
return ByteBuffer.allocate(6) //
|
||||
.putInt(address) //
|
||||
.putShort((short) (((sequenceNumber & 0x0f) << 10) | length | ((unknown ? 1 : 0) << 15))) //
|
||||
.array();
|
||||
}
|
||||
}
|
|
@ -2,29 +2,40 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class DeactivateCommand extends CommandBase {
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.CommandType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.NonceEnabledCommand;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.builder.NonceEnabledCommandBuilder;
|
||||
|
||||
public final class DeactivateCommand extends NonceEnabledCommand {
|
||||
private static final short LENGTH = 6;
|
||||
private static final byte BODY_LENGTH = 4;
|
||||
|
||||
DeactivateCommand(int address, short sequenceNumber, boolean unknown) {
|
||||
super(CommandType.DEACTIVATE, address, sequenceNumber, unknown);
|
||||
DeactivateCommand(int uniqueId, short sequenceNumber, boolean multiCommandFlag, int nonce) {
|
||||
super(CommandType.DEACTIVATE, uniqueId, sequenceNumber, multiCommandFlag, nonce);
|
||||
}
|
||||
|
||||
@Override public byte[] getEncoded() {
|
||||
return appendCrc(ByteBuffer.allocate(LENGTH + HEADER_LENGTH) //
|
||||
.put(encodeHeader(address, sequenceNumber, LENGTH, unknown)) //
|
||||
.put(encodeHeader(uniqueId, sequenceNumber, LENGTH, multiCommandFlag)) //
|
||||
.put(commandType.getValue()) //
|
||||
.put(BODY_LENGTH) //
|
||||
.putInt(1229869870) // FIXME ?? was: byte array of int 777211465 converted to little endian
|
||||
.putInt(nonce) //
|
||||
.array());
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return "DeactivateCommand{" +
|
||||
"commandType=" + commandType +
|
||||
", address=" + address +
|
||||
"nonce=" + nonce +
|
||||
", commandType=" + commandType +
|
||||
", uniqueId=" + uniqueId +
|
||||
", sequenceNumber=" + sequenceNumber +
|
||||
", unknown=" + unknown +
|
||||
", multiCommandFlag=" + multiCommandFlag +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static final class Builder extends NonceEnabledCommandBuilder<Builder, DeactivateCommand> {
|
||||
@Override protected final DeactivateCommand buildCommand() {
|
||||
return new DeactivateCommand(uniqueId, sequenceNumber, multiCommandFlag, nonce);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,34 +2,41 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class GetVersionCommand extends CommandBase {
|
||||
private static final int DEFAULT_ADDRESS = -1;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.CommandType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.HeaderEnabledCommand;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.builder.HeaderEnabledCommandBuilder;
|
||||
|
||||
public final class GetVersionCommand extends HeaderEnabledCommand {
|
||||
public static final int DEFAULT_UNIQUE_ID = -1; // FIXME move
|
||||
|
||||
private static final short LENGTH = 6;
|
||||
private static final byte BODY_LENGTH = 4;
|
||||
|
||||
public GetVersionCommand(short sequenceNumber, boolean unknown) {
|
||||
this(DEFAULT_ADDRESS, sequenceNumber, unknown);
|
||||
}
|
||||
|
||||
public GetVersionCommand(int address, short sequenceNumber, boolean unknown) {
|
||||
super(CommandType.GET_VERSION, address, sequenceNumber, unknown);
|
||||
GetVersionCommand(int uniqueId, short sequenceNumber, boolean multiCommandFlag) {
|
||||
super(CommandType.GET_VERSION, uniqueId, sequenceNumber, multiCommandFlag);
|
||||
}
|
||||
|
||||
@Override public byte[] getEncoded() {
|
||||
return appendCrc(ByteBuffer.allocate(LENGTH + HEADER_LENGTH) //
|
||||
.put(encodeHeader(address, sequenceNumber, LENGTH, unknown)) //
|
||||
.put(encodeHeader(uniqueId, sequenceNumber, LENGTH, multiCommandFlag)) //
|
||||
.put(commandType.getValue()) //
|
||||
.put(BODY_LENGTH) //
|
||||
.putInt(address) //
|
||||
.putInt(uniqueId) //
|
||||
.array());
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return "GetVersionCommand{" +
|
||||
"commandType=" + commandType +
|
||||
", address=" + address +
|
||||
", uniqueId=" + uniqueId +
|
||||
", sequenceNumber=" + sequenceNumber +
|
||||
", unknown=" + unknown +
|
||||
", multiCommandFlag=" + multiCommandFlag +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static final class Builder extends HeaderEnabledCommandBuilder<Builder, GetVersionCommand> {
|
||||
@Override protected final GetVersionCommand buildCommand() {
|
||||
return new GetVersionCommand(uniqueId, sequenceNumber, multiCommandFlag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,22 +4,25 @@ import java.nio.ByteBuffer;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.CommandType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.NonceEnabledCommand;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.builder.NonceEnabledCommandBuilder;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertConfiguration;
|
||||
|
||||
public class ProgramAlertsCommand extends CommandBase {
|
||||
public final class ProgramAlertsCommand extends NonceEnabledCommand {
|
||||
private final List<AlertConfiguration> alertConfigurations;
|
||||
|
||||
ProgramAlertsCommand(int address, short sequenceNumber, boolean unknown, List<AlertConfiguration> alertConfigurations) {
|
||||
super(CommandType.PROGRAM_ALERTS, address, sequenceNumber, unknown);
|
||||
ProgramAlertsCommand(int uniqueId, short sequenceNumber, boolean multiCommandFlag, List<AlertConfiguration> alertConfigurations, int nonce) {
|
||||
super(CommandType.PROGRAM_ALERTS, uniqueId, sequenceNumber, multiCommandFlag, nonce);
|
||||
this.alertConfigurations = new ArrayList<>(alertConfigurations);
|
||||
}
|
||||
|
||||
@Override public byte[] getEncoded() {
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocate(getLength() + HEADER_LENGTH) //
|
||||
.put(encodeHeader(address, sequenceNumber, getLength(), unknown)) //
|
||||
.put(encodeHeader(uniqueId, sequenceNumber, getLength(), multiCommandFlag)) //
|
||||
.put(commandType.getValue()) //
|
||||
.put(getBodyLength()) //
|
||||
.putInt(1229869870); // FIXME ?? was: byte array of int 777211465 converted to little endian
|
||||
.putInt(nonce);
|
||||
for (AlertConfiguration configuration : alertConfigurations) {
|
||||
byteBuffer.put(configuration.getEncoded());
|
||||
}
|
||||
|
@ -37,10 +40,27 @@ public class ProgramAlertsCommand extends CommandBase {
|
|||
@Override public String toString() {
|
||||
return "ProgramAlertsCommand{" +
|
||||
"alertConfigurations=" + alertConfigurations +
|
||||
", nonce=" + nonce +
|
||||
", commandType=" + commandType +
|
||||
", address=" + address +
|
||||
", uniqueId=" + uniqueId +
|
||||
", sequenceNumber=" + sequenceNumber +
|
||||
", unknown=" + unknown +
|
||||
", multiCommandFlag=" + multiCommandFlag +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static final class Builder extends NonceEnabledCommandBuilder<Builder, ProgramAlertsCommand> {
|
||||
private List<AlertConfiguration> alertConfigurations;
|
||||
|
||||
public Builder setAlertConfigurations(List<AlertConfiguration> alertConfigurations) {
|
||||
this.alertConfigurations = alertConfigurations;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override protected final ProgramAlertsCommand buildCommand() {
|
||||
if (this.alertConfigurations == null) {
|
||||
throw new IllegalArgumentException("alertConfigurations can not be null");
|
||||
}
|
||||
return new ProgramAlertsCommand(uniqueId, sequenceNumber, multiCommandFlag, alertConfigurations, nonce);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.CommandType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.HeaderEnabledCommand;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.builder.NonceEnabledCommandBuilder;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.insulin.program.BasalInsulinProgramElement;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.insulin.program.CurrentBasalInsulinProgramElement;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.insulin.program.CurrentSlot;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.insulin.program.ShortInsulinProgramElement;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.insulin.program.util.ProgramBasalUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BasalProgram;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ProgramReminder;
|
||||
|
||||
// Always preceded by 0x1a ProgramInsulinCommand
|
||||
public final class ProgramBasalCommand extends HeaderEnabledCommand {
|
||||
private final ProgramInsulinCommand interlockCommand;
|
||||
private final List<BasalInsulinProgramElement> insulinProgramElements;
|
||||
private final ProgramReminder programReminder;
|
||||
private final byte currentInsulinProgramElementIndex;
|
||||
private final short remainingTenthPulsesInCurrentInsulinProgramElement;
|
||||
private final int delayUntilNextTenthPulseInUsec;
|
||||
|
||||
ProgramBasalCommand(ProgramInsulinCommand interlockCommand, int uniqueId, short sequenceNumber, boolean multiCommandFlag, List<BasalInsulinProgramElement> insulinProgramElements, ProgramReminder programReminder, byte currentInsulinProgramElementIndex, short remainingTenthPulsesInCurrentInsulinProgramElement, int delayUntilNextTenthPulseInUsec) {
|
||||
super(CommandType.PROGRAM_BASAL, uniqueId, sequenceNumber, multiCommandFlag);
|
||||
|
||||
this.interlockCommand = interlockCommand;
|
||||
this.insulinProgramElements = new ArrayList<>(insulinProgramElements);
|
||||
this.programReminder = programReminder;
|
||||
this.currentInsulinProgramElementIndex = currentInsulinProgramElementIndex;
|
||||
this.remainingTenthPulsesInCurrentInsulinProgramElement = remainingTenthPulsesInCurrentInsulinProgramElement;
|
||||
this.delayUntilNextTenthPulseInUsec = delayUntilNextTenthPulseInUsec;
|
||||
}
|
||||
|
||||
short getLength() {
|
||||
return (short) (insulinProgramElements.size() * 6 + 10);
|
||||
}
|
||||
|
||||
byte getBodyLength() {
|
||||
return (byte) (insulinProgramElements.size() * 6 + 8);
|
||||
}
|
||||
|
||||
@Override public byte[] getEncoded() {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(getLength()) //
|
||||
.put(getCommandType().getValue()) //
|
||||
.put(getBodyLength()) //
|
||||
.put(programReminder.getEncoded()) //
|
||||
.put(currentInsulinProgramElementIndex) //
|
||||
.putShort(remainingTenthPulsesInCurrentInsulinProgramElement) //
|
||||
.putInt(delayUntilNextTenthPulseInUsec);
|
||||
for (BasalInsulinProgramElement insulinProgramElement : insulinProgramElements) {
|
||||
buffer.put(insulinProgramElement.getEncoded());
|
||||
}
|
||||
|
||||
byte[] basalCommand = buffer.array();
|
||||
byte[] interlockCommand = this.interlockCommand.getEncoded();
|
||||
byte[] header = encodeHeader(uniqueId, sequenceNumber, (short) (basalCommand.length + interlockCommand.length), multiCommandFlag);
|
||||
|
||||
return appendCrc(ByteBuffer.allocate(basalCommand.length + interlockCommand.length + header.length) //
|
||||
.put(header) //
|
||||
.put(interlockCommand) //
|
||||
.put(basalCommand) //
|
||||
.array());
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return "ProgramBasalCommand{" +
|
||||
"interlockCommand=" + interlockCommand +
|
||||
", insulinProgramElements=" + insulinProgramElements +
|
||||
", programReminder=" + programReminder +
|
||||
", currentInsulinProgramElementIndex=" + currentInsulinProgramElementIndex +
|
||||
", remainingTenthPulsesInCurrentInsulinProgramElement=" + remainingTenthPulsesInCurrentInsulinProgramElement +
|
||||
", delayUntilNextTenthPulseInUsec=" + delayUntilNextTenthPulseInUsec +
|
||||
", commandType=" + commandType +
|
||||
", uniqueId=" + uniqueId +
|
||||
", sequenceNumber=" + sequenceNumber +
|
||||
", multiCommandFlag=" + multiCommandFlag +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static final class Builder extends NonceEnabledCommandBuilder<Builder, ProgramBasalCommand> {
|
||||
private BasalProgram basalProgram;
|
||||
private ProgramReminder programReminder;
|
||||
private Date currentTime;
|
||||
|
||||
public Builder setBasalProgram(BasalProgram basalProgram) {
|
||||
this.basalProgram = basalProgram;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setProgramReminder(ProgramReminder programReminder) {
|
||||
this.programReminder = programReminder;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setCurrentTime(Date currentTime) {
|
||||
this.currentTime = currentTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override protected ProgramBasalCommand buildCommand() {
|
||||
if (basalProgram == null) {
|
||||
throw new IllegalArgumentException("basalProgram can not be null");
|
||||
}
|
||||
if (programReminder == null) {
|
||||
throw new IllegalArgumentException("programReminder can not be null");
|
||||
}
|
||||
if (currentTime == null) {
|
||||
throw new IllegalArgumentException("currentTime can not be null");
|
||||
}
|
||||
|
||||
short[] pulsesPerSlot = ProgramBasalUtil.mapBasalProgramToPulsesPerSlot(basalProgram);
|
||||
CurrentSlot currentSlot = ProgramBasalUtil.calculateCurrentSlot(pulsesPerSlot, currentTime);
|
||||
short checksum = ProgramBasalUtil.calculateChecksum(pulsesPerSlot, currentSlot);
|
||||
List<BasalInsulinProgramElement> longInsulinProgramElements = ProgramBasalUtil.mapTenthPulsesPerSlotToLongInsulinProgramElements(ProgramBasalUtil.mapBasalProgramToTenthPulsesPerSlot(basalProgram));
|
||||
List<ShortInsulinProgramElement> shortInsulinProgramElements = ProgramBasalUtil.mapPulsesPerSlotToShortInsulinProgramElements(pulsesPerSlot);
|
||||
CurrentBasalInsulinProgramElement currentBasalInsulinProgramElement = ProgramBasalUtil.calculateCurrentLongInsulinProgramElement(longInsulinProgramElements, currentTime);
|
||||
|
||||
ProgramInsulinCommand interlockCommand = new ProgramInsulinCommand(uniqueId, sequenceNumber, multiCommandFlag, nonce,
|
||||
shortInsulinProgramElements, checksum, currentSlot.getIndex(), currentSlot.getEighthSecondsRemaining(),
|
||||
currentSlot.getPulsesRemaining(), ProgramInsulinCommand.DeliveryType.BASAL);
|
||||
|
||||
return new ProgramBasalCommand(interlockCommand, uniqueId, sequenceNumber, multiCommandFlag,
|
||||
longInsulinProgramElements, programReminder, currentBasalInsulinProgramElement.getIndex(),
|
||||
currentBasalInsulinProgramElement.getRemainingTenthPulses(), currentBasalInsulinProgramElement.getDelayUntilNextTenthPulseInUsec());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Collections;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.CommandType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.HeaderEnabledCommand;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.builder.NonceEnabledCommandBuilder;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.insulin.program.BolusShortInsulinProgramElement;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ProgramReminder;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.MessageUtil;
|
||||
|
||||
// NOT SUPPORTED: extended bolus
|
||||
public final class ProgramBolusCommand extends HeaderEnabledCommand {
|
||||
private static final short LENGTH = 15;
|
||||
private static final byte BODY_LENGTH = 13;
|
||||
|
||||
private final ProgramInsulinCommand interlockCommand;
|
||||
private final ProgramReminder programReminder;
|
||||
private final short numberOfTenthPulses;
|
||||
private final int delayUntilFirstTenthPulseInUsec;
|
||||
|
||||
ProgramBolusCommand(ProgramInsulinCommand interlockCommand, int uniqueId, short sequenceNumber, boolean multiCommandFlag, ProgramReminder programReminder, short numberOfTenthPulses, int delayUntilFirstTenthPulseInUsec) {
|
||||
super(CommandType.PROGRAM_BOLUS, uniqueId, sequenceNumber, multiCommandFlag);
|
||||
this.interlockCommand = interlockCommand;
|
||||
this.programReminder = programReminder;
|
||||
this.numberOfTenthPulses = numberOfTenthPulses;
|
||||
this.delayUntilFirstTenthPulseInUsec = delayUntilFirstTenthPulseInUsec;
|
||||
}
|
||||
|
||||
@Override public byte[] getEncoded() {
|
||||
byte[] bolusCommand = ByteBuffer.allocate(LENGTH) //
|
||||
.put(commandType.getValue()) //
|
||||
.put(BODY_LENGTH) //
|
||||
.put(programReminder.getEncoded()) //
|
||||
.putShort(numberOfTenthPulses) //
|
||||
.putInt(delayUntilFirstTenthPulseInUsec) //
|
||||
.putShort((short) 0) // Extended bolus pulses
|
||||
.putInt(0) // Delay between tenth extended pulses in usec
|
||||
.array();
|
||||
|
||||
byte[] interlockCommand = this.interlockCommand.getEncoded();
|
||||
byte[] header = encodeHeader(uniqueId, sequenceNumber, (short) (bolusCommand.length + interlockCommand.length), multiCommandFlag);
|
||||
|
||||
return appendCrc(ByteBuffer.allocate(header.length + interlockCommand.length + bolusCommand.length) //
|
||||
.put(header) //
|
||||
.put(interlockCommand) //
|
||||
.put(bolusCommand) //
|
||||
.array());
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return "ProgramBolusCommand{" +
|
||||
"interlockCommand=" + interlockCommand +
|
||||
", programReminder=" + programReminder +
|
||||
", numberOfTenthPulses=" + numberOfTenthPulses +
|
||||
", delayUntilFirstTenthPulseInUsec=" + delayUntilFirstTenthPulseInUsec +
|
||||
", commandType=" + commandType +
|
||||
", uniqueId=" + uniqueId +
|
||||
", sequenceNumber=" + sequenceNumber +
|
||||
", multiCommandFlag=" + multiCommandFlag +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static final class Builder extends NonceEnabledCommandBuilder<Builder, ProgramBolusCommand> {
|
||||
private Double numberOfUnits;
|
||||
private Byte delayBetweenPulsesInEighthSeconds;
|
||||
private ProgramReminder programReminder;
|
||||
|
||||
public Builder setNumberOfUnits(double numberOfUnits) {
|
||||
if (numberOfUnits <= 0.0D) {
|
||||
throw new IllegalArgumentException("Number of units should be greater than zero");
|
||||
}
|
||||
if ((int) (numberOfUnits * 1000) % 50 != 0) {
|
||||
throw new IllegalArgumentException("Number of units must be dividable by 0.05");
|
||||
}
|
||||
this.numberOfUnits = ((int) (numberOfUnits * 100)) / 100.0d;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDelayBetweenPulsesInEighthSeconds(byte delayBetweenPulsesInEighthSeconds) {
|
||||
this.delayBetweenPulsesInEighthSeconds = delayBetweenPulsesInEighthSeconds;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setProgramReminder(ProgramReminder programReminder) {
|
||||
this.programReminder = programReminder;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override protected ProgramBolusCommand buildCommand() {
|
||||
if (numberOfUnits == null) {
|
||||
throw new IllegalArgumentException("numberOfUnits can not be null");
|
||||
}
|
||||
if (delayBetweenPulsesInEighthSeconds == null) {
|
||||
throw new IllegalArgumentException("delayBetweenPulsesInEighthSeconds can not be null");
|
||||
}
|
||||
if (programReminder == null) {
|
||||
throw new IllegalArgumentException("programReminder can not be null");
|
||||
}
|
||||
|
||||
short numberOfPulses = (short) Math.round(numberOfUnits * 20);
|
||||
short byte10And11 = (short) (numberOfPulses * delayBetweenPulsesInEighthSeconds);
|
||||
|
||||
ProgramInsulinCommand interlockCommand = new ProgramInsulinCommand(uniqueId, sequenceNumber, multiCommandFlag, nonce,
|
||||
Collections.singletonList(new BolusShortInsulinProgramElement(numberOfPulses)), calculateChecksum((byte) 0x01, byte10And11, numberOfPulses),
|
||||
(byte) 0x01, byte10And11, (short) numberOfPulses, ProgramInsulinCommand.DeliveryType.BOLUS);
|
||||
|
||||
int delayUntilFirstTenthPulseInUsec = delayBetweenPulsesInEighthSeconds / 8 * 100_000;
|
||||
|
||||
return new ProgramBolusCommand(interlockCommand, uniqueId, sequenceNumber, multiCommandFlag, programReminder, (short) (numberOfPulses * 10), delayUntilFirstTenthPulseInUsec);
|
||||
}
|
||||
}
|
||||
|
||||
private static short calculateChecksum(byte numberOfSlots, short byte10And11, short numberOfPulses) {
|
||||
return MessageUtil.calculateChecksum(ByteBuffer.allocate(7) //
|
||||
.put(numberOfSlots) //
|
||||
.putShort(byte10And11) //
|
||||
.putShort(numberOfPulses) //
|
||||
.putShort(numberOfPulses) //
|
||||
.array());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.CommandType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.NonceEnabledCommand;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.insulin.program.ShortInsulinProgramElement;
|
||||
|
||||
// Always followed by one of: 0x13, 0x16, 0x17
|
||||
final class ProgramInsulinCommand extends NonceEnabledCommand {
|
||||
private final List<ShortInsulinProgramElement> insulinProgramElements;
|
||||
private final short checksum;
|
||||
private final byte byte9;
|
||||
private final short byte10And11;
|
||||
private final short byte12And13;
|
||||
private final DeliveryType deliveryType;
|
||||
|
||||
ProgramInsulinCommand(int uniqueId, short sequenceNumber, boolean multiCommandFlag, int nonce, List<ShortInsulinProgramElement> insulinProgramElements, short checksum, byte byte9, short byte10And11, short byte12And13, DeliveryType deliveryType) {
|
||||
super(CommandType.PROGRAM_INSULIN, uniqueId, sequenceNumber, multiCommandFlag, nonce);
|
||||
this.insulinProgramElements = new ArrayList<>(insulinProgramElements);
|
||||
this.checksum = checksum;
|
||||
this.byte9 = byte9;
|
||||
this.byte10And11 = byte10And11;
|
||||
this.byte12And13 = byte12And13;
|
||||
this.deliveryType = deliveryType;
|
||||
}
|
||||
|
||||
public short getLength() {
|
||||
return (short) (insulinProgramElements.size() * 2 + 14);
|
||||
}
|
||||
|
||||
public byte getBodyLength() {
|
||||
return (byte) (insulinProgramElements.size() * 2 + 12);
|
||||
}
|
||||
|
||||
@Override public byte[] getEncoded() {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(this.getLength()) //
|
||||
.put(commandType.getValue()) //
|
||||
.put(getBodyLength()) //
|
||||
.putInt(nonce) //
|
||||
.put(deliveryType.getValue()) //
|
||||
.putShort(checksum) //
|
||||
.put(byte9) // BASAL: currentSlot // BOLUS: number of ShortInsulinProgramElements
|
||||
.putShort(byte10And11) // BASAL: remainingEighthSecondsInCurrentSlot // BOLUS: immediate pulses multiplied by delay between pulses in eighth seconds
|
||||
.putShort(byte12And13); // BASAL: remainingPulsesInCurrentSlot // BOLUS: immediate pulses
|
||||
|
||||
for (ShortInsulinProgramElement element : insulinProgramElements) {
|
||||
buffer.put(element.getEncoded());
|
||||
}
|
||||
|
||||
return buffer.array();
|
||||
}
|
||||
|
||||
enum DeliveryType {
|
||||
BASAL((byte) 0x00),
|
||||
TEMP_BASAL((byte) 0x01),
|
||||
BOLUS((byte) 0x02);
|
||||
|
||||
private final byte value;
|
||||
|
||||
DeliveryType(byte value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public byte getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public short calculateChecksum(byte[] bytes) {
|
||||
short sum = 0;
|
||||
for (byte b : bytes) {
|
||||
sum += (short) (b & 0xff);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return "ProgramInsulinCommand{" +
|
||||
"insulinProgramElements=" + insulinProgramElements +
|
||||
", checksum=" + checksum +
|
||||
", byte9=" + byte9 +
|
||||
", byte10And11=" + byte10And11 +
|
||||
", byte12And13=" + byte12And13 +
|
||||
", deliveryType=" + deliveryType +
|
||||
", nonce=" + nonce +
|
||||
", commandType=" + commandType +
|
||||
", uniqueId=" + uniqueId +
|
||||
", sequenceNumber=" + sequenceNumber +
|
||||
", multiCommandFlag=" + multiCommandFlag +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.CommandType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.HeaderEnabledCommand;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.builder.NonceEnabledCommandBuilder;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.insulin.program.BasalInsulinProgramElement;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.insulin.program.ShortInsulinProgramElement;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.insulin.program.util.ProgramBasalUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.insulin.program.util.ProgramTempBasalUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ProgramReminder;
|
||||
|
||||
// NOT SUPPORTED: percentage temp basal
|
||||
public final class ProgramTempBasalCommand extends HeaderEnabledCommand {
|
||||
private final ProgramInsulinCommand interlockCommand;
|
||||
private final ProgramReminder programReminder;
|
||||
private final List<BasalInsulinProgramElement> insulinProgramElements;
|
||||
|
||||
protected ProgramTempBasalCommand(ProgramInsulinCommand interlockCommand, int uniqueId, short sequenceNumber, boolean multiCommandFlag,
|
||||
ProgramReminder programReminder, List<BasalInsulinProgramElement> insulinProgramElements) {
|
||||
super(CommandType.PROGRAM_TEMP_BASAL, uniqueId, sequenceNumber, multiCommandFlag);
|
||||
this.interlockCommand = interlockCommand;
|
||||
this.programReminder = programReminder;
|
||||
this.insulinProgramElements = new ArrayList<>(insulinProgramElements);
|
||||
}
|
||||
|
||||
public byte getBodyLength() {
|
||||
return (byte) (insulinProgramElements.size() * 6 + 8);
|
||||
}
|
||||
|
||||
public short getLength() {
|
||||
return (short) (getBodyLength() + 2);
|
||||
}
|
||||
|
||||
@Override public byte[] getEncoded() {
|
||||
BasalInsulinProgramElement firstProgramElement = insulinProgramElements.get(0);
|
||||
|
||||
short remainingTenthPulsesInFirstElement;
|
||||
int delayUntilNextTenthPulseInUsec;
|
||||
|
||||
if (firstProgramElement.getTotalTenthPulses() == 0) {
|
||||
remainingTenthPulsesInFirstElement = firstProgramElement.getNumberOfSlots();
|
||||
delayUntilNextTenthPulseInUsec = ProgramBasalUtil.MAX_DELAY_BETWEEN_TENTH_PULSES_IN_USEC_AND_USECS_IN_BASAL_SLOT;
|
||||
} else {
|
||||
remainingTenthPulsesInFirstElement = firstProgramElement.getTotalTenthPulses();
|
||||
delayUntilNextTenthPulseInUsec = (int) ((long) firstProgramElement.getNumberOfSlots() * 1_800.0d / remainingTenthPulsesInFirstElement * 1_000_000);
|
||||
}
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocate(getLength()) //
|
||||
.put(commandType.getValue()) //
|
||||
.put(getBodyLength()) //
|
||||
.put(programReminder.getEncoded()) //
|
||||
.put((byte) 0x00) // Current slot index
|
||||
.putShort(remainingTenthPulsesInFirstElement) //
|
||||
.putInt(delayUntilNextTenthPulseInUsec);
|
||||
|
||||
for (BasalInsulinProgramElement element : insulinProgramElements) {
|
||||
buffer.put(element.getEncoded());
|
||||
}
|
||||
|
||||
byte[] tempBasalCommand = buffer.array();
|
||||
byte[] interlockCommand = this.interlockCommand.getEncoded();
|
||||
byte[] header = encodeHeader(uniqueId, sequenceNumber, (short) (tempBasalCommand.length + interlockCommand.length), multiCommandFlag);
|
||||
|
||||
return appendCrc(ByteBuffer.allocate(header.length + interlockCommand.length + tempBasalCommand.length) //
|
||||
.put(header) //
|
||||
.put(interlockCommand) //
|
||||
.put(tempBasalCommand) //
|
||||
.array());
|
||||
}
|
||||
|
||||
public static class Builder extends NonceEnabledCommandBuilder<Builder, ProgramTempBasalCommand> {
|
||||
private ProgramReminder programReminder;
|
||||
private Double rateInUnitsPerHour;
|
||||
private Short durationInMinutes;
|
||||
|
||||
public Builder setProgramReminder(ProgramReminder programReminder) {
|
||||
this.programReminder = programReminder;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setRateInUnitsPerHour(double rateInUnitsPerHour) {
|
||||
this.rateInUnitsPerHour = rateInUnitsPerHour;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDurationInMinutes(short durationInMinutes) {
|
||||
if (durationInMinutes % 30 != 0) {
|
||||
throw new IllegalArgumentException("durationInMinutes must be dividable by 30");
|
||||
}
|
||||
this.durationInMinutes = durationInMinutes;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override protected ProgramTempBasalCommand buildCommand() {
|
||||
if (programReminder == null) {
|
||||
throw new IllegalArgumentException("programReminder can not be null");
|
||||
}
|
||||
if (rateInUnitsPerHour == null) {
|
||||
throw new IllegalArgumentException("rateInUnitsPerHour can not be null");
|
||||
}
|
||||
if (durationInMinutes == null) {
|
||||
throw new IllegalArgumentException("durationInMinutes can not be null");
|
||||
}
|
||||
|
||||
byte durationInSlots = (byte) (durationInMinutes / 30);
|
||||
short[] pulsesPerSlot = ProgramTempBasalUtil.mapTempBasalToPulsesPerSlot(durationInSlots, rateInUnitsPerHour);
|
||||
short[] tenthPulsesPerSlot = ProgramTempBasalUtil.mapTempBasalToTenthPulsesPerSlot(durationInSlots, rateInUnitsPerHour);
|
||||
|
||||
List<ShortInsulinProgramElement> shortInsulinProgramElements = ProgramTempBasalUtil.mapPulsesPerSlotToShortInsulinProgramElements(pulsesPerSlot);
|
||||
List<BasalInsulinProgramElement> insulinProgramElements = ProgramTempBasalUtil.mapTenthPulsesPerSlotToLongInsulinProgramElements(tenthPulsesPerSlot);
|
||||
|
||||
ProgramInsulinCommand interlockCommand = new ProgramInsulinCommand(uniqueId, sequenceNumber, multiCommandFlag, nonce, shortInsulinProgramElements,
|
||||
ProgramTempBasalUtil.calculateChecksum(durationInSlots, pulsesPerSlot[0], pulsesPerSlot), durationInSlots,
|
||||
(short) 0x3840, pulsesPerSlot[0], ProgramInsulinCommand.DeliveryType.TEMP_BASAL);
|
||||
|
||||
return new ProgramTempBasalCommand(interlockCommand, uniqueId, sequenceNumber, multiCommandFlag, programReminder, insulinProgramElements);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,8 +4,12 @@ import java.nio.ByteBuffer;
|
|||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
public class SetUniqueIdCommand extends CommandBase {
|
||||
private static final int DEFAULT_ADDRESS = -1;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.CommandType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.HeaderEnabledCommand;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.builder.HeaderEnabledCommandBuilder;
|
||||
|
||||
public final class SetUniqueIdCommand extends HeaderEnabledCommand {
|
||||
private static final int DEFAULT_UNIQUE_ID = -1;
|
||||
private static final short LENGTH = 21;
|
||||
private static final byte BODY_LENGTH = 19;
|
||||
|
||||
|
@ -13,8 +17,8 @@ public class SetUniqueIdCommand extends CommandBase {
|
|||
private final int podSequenceNumber;
|
||||
private final Date initializationTime;
|
||||
|
||||
SetUniqueIdCommand(int address, short sequenceNumber, int lotNumber, int podSequenceNumber, Date initializationTime, boolean unknown) {
|
||||
super(CommandType.SET_UNIQUE_ID, address, sequenceNumber, unknown);
|
||||
SetUniqueIdCommand(int uniqueId, short sequenceNumber, boolean multiCommandFlag, int lotNumber, int podSequenceNumber, Date initializationTime) {
|
||||
super(CommandType.SET_UNIQUE_ID, uniqueId, sequenceNumber, multiCommandFlag);
|
||||
this.lotNumber = lotNumber;
|
||||
this.podSequenceNumber = podSequenceNumber;
|
||||
this.initializationTime = initializationTime;
|
||||
|
@ -22,10 +26,10 @@ public class SetUniqueIdCommand extends CommandBase {
|
|||
|
||||
@Override public byte[] getEncoded() {
|
||||
return appendCrc(ByteBuffer.allocate(LENGTH + HEADER_LENGTH) //
|
||||
.put(encodeHeader(DEFAULT_ADDRESS, sequenceNumber, LENGTH, unknown)) //
|
||||
.put(encodeHeader(DEFAULT_UNIQUE_ID, sequenceNumber, LENGTH, multiCommandFlag)) //
|
||||
.put(commandType.getValue()) //
|
||||
.put(BODY_LENGTH) //
|
||||
.putInt(address) //
|
||||
.putInt(uniqueId) //
|
||||
.put((byte) 0x14) // FIXME ??
|
||||
.put((byte) 0x04) // FIXME ??
|
||||
.put(encodeInitializationTime(initializationTime)) //
|
||||
|
@ -53,9 +57,43 @@ public class SetUniqueIdCommand extends CommandBase {
|
|||
", podSequenceNumber=" + podSequenceNumber +
|
||||
", initializationTime=" + initializationTime +
|
||||
", commandType=" + commandType +
|
||||
", address=" + address +
|
||||
", uniqueId=" + uniqueId +
|
||||
", sequenceNumber=" + sequenceNumber +
|
||||
", unknown=" + unknown +
|
||||
", multiCommandFlag=" + multiCommandFlag +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static final class Builder extends HeaderEnabledCommandBuilder<Builder, SetUniqueIdCommand> {
|
||||
private Integer lotNumber;
|
||||
private Integer podSequenceNumber;
|
||||
private Date initializationTime;
|
||||
|
||||
public Builder setLotNumber(int lotNumber) {
|
||||
this.lotNumber = lotNumber;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setPodSequenceNumber(int podSequenceNumber) {
|
||||
this.podSequenceNumber = podSequenceNumber;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setInitializationTime(Date initializationTime) {
|
||||
this.initializationTime = initializationTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override protected final SetUniqueIdCommand buildCommand() {
|
||||
if (lotNumber == null) {
|
||||
throw new IllegalArgumentException("lotNumber can not be null");
|
||||
}
|
||||
if (podSequenceNumber == null) {
|
||||
throw new IllegalArgumentException("podSequenceNumber can not be null");
|
||||
}
|
||||
if (initializationTime == null) {
|
||||
throw new IllegalArgumentException("initializationTime can not be null");
|
||||
}
|
||||
return new SetUniqueIdCommand(uniqueId, sequenceNumber, multiCommandFlag, lotNumber, podSequenceNumber, initializationTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,28 +3,44 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command;
|
|||
import java.nio.ByteBuffer;
|
||||
import java.util.BitSet;
|
||||
|
||||
public class SilenceAlertsCommand extends CommandBase {
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.CommandType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.NonceEnabledCommand;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.builder.NonceEnabledCommandBuilder;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.Encodable;
|
||||
|
||||
public final class SilenceAlertsCommand extends NonceEnabledCommand {
|
||||
private static final short LENGTH = (short) 7;
|
||||
private static final byte BODY_LENGTH = (byte) 5;
|
||||
|
||||
private final SilenceAlertCommandParameters parameters;
|
||||
|
||||
public SilenceAlertsCommand(int address, short sequenceNumber, boolean unknown, SilenceAlertCommandParameters parameters) {
|
||||
super(CommandType.SILENCE_ALERTS, address, sequenceNumber, unknown);
|
||||
SilenceAlertsCommand(int uniqueId, short sequenceNumber, boolean multiCommandFlag, SilenceAlertCommandParameters parameters, int nonce) {
|
||||
super(CommandType.SILENCE_ALERTS, uniqueId, sequenceNumber, multiCommandFlag, nonce);
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
@Override public byte[] getEncoded() {
|
||||
return appendCrc(ByteBuffer.allocate(LENGTH + HEADER_LENGTH) //
|
||||
.put(encodeHeader(address, sequenceNumber, LENGTH, unknown)) //
|
||||
.put(encodeHeader(uniqueId, sequenceNumber, LENGTH, multiCommandFlag)) //
|
||||
.put(commandType.getValue()) //
|
||||
.put(BODY_LENGTH) //
|
||||
.putInt(1229869870) // FIXME ?? was: byte array of int 777211465 converted to little endian
|
||||
.putInt(nonce) //
|
||||
.put(parameters.getEncoded()) //
|
||||
.array());
|
||||
}
|
||||
|
||||
public static final class SilenceAlertCommandParameters {
|
||||
@Override public String toString() {
|
||||
return "SilenceAlertsCommand{" +
|
||||
"parameters=" + parameters +
|
||||
", nonce=" + nonce +
|
||||
", commandType=" + commandType +
|
||||
", uniqueId=" + uniqueId +
|
||||
", sequenceNumber=" + sequenceNumber +
|
||||
", multiCommandFlag=" + multiCommandFlag +
|
||||
'}';
|
||||
}
|
||||
|
||||
private static final class SilenceAlertCommandParameters implements Encodable {
|
||||
private final boolean silenceAutoOffAlert;
|
||||
private final boolean silenceMultiCommandAlert;
|
||||
private final boolean silenceExpirationImminentAlert;
|
||||
|
@ -34,7 +50,7 @@ public class SilenceAlertsCommand extends CommandBase {
|
|||
private final boolean silenceSuspendEndedAlert;
|
||||
private final boolean silencePodExpirationAlert;
|
||||
|
||||
public SilenceAlertCommandParameters(boolean silenceAutoOffAlert, boolean silenceMultiCommandAlert, boolean silenceExpirationImminentAlert, boolean silenceUserSetExpirationAlert, boolean silenceLowReservoirAlert, boolean silenceSuspendInProgressAlert, boolean silenceSuspendEndedAlert, boolean silencePodExpirationAlert) {
|
||||
private SilenceAlertCommandParameters(boolean silenceAutoOffAlert, boolean silenceMultiCommandAlert, boolean silenceExpirationImminentAlert, boolean silenceUserSetExpirationAlert, boolean silenceLowReservoirAlert, boolean silenceSuspendInProgressAlert, boolean silenceSuspendEndedAlert, boolean silencePodExpirationAlert) {
|
||||
this.silenceAutoOffAlert = silenceAutoOffAlert;
|
||||
this.silenceMultiCommandAlert = silenceMultiCommandAlert;
|
||||
this.silenceExpirationImminentAlert = silenceExpirationImminentAlert;
|
||||
|
@ -45,6 +61,7 @@ public class SilenceAlertsCommand extends CommandBase {
|
|||
this.silencePodExpirationAlert = silencePodExpirationAlert;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
BitSet bitSet = new BitSet(8);
|
||||
bitSet.set(0, this.silenceAutoOffAlert);
|
||||
|
@ -58,4 +75,59 @@ public class SilenceAlertsCommand extends CommandBase {
|
|||
return bitSet.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder extends NonceEnabledCommandBuilder<Builder, SilenceAlertsCommand> {
|
||||
private boolean silenceAutoOffAlert;
|
||||
private boolean silenceMultiCommandAlert;
|
||||
private boolean silenceExpirationImminentAlert;
|
||||
private boolean silenceUserSetExpirationAlert;
|
||||
private boolean silenceLowReservoirAlert;
|
||||
private boolean silenceSuspendInProgressAlert;
|
||||
private boolean silenceSuspendEndedAlert;
|
||||
private boolean silencePodExpirationAlert;
|
||||
|
||||
public Builder setSilenceAutoOffAlert(boolean silenceAutoOffAlert) {
|
||||
this.silenceAutoOffAlert = silenceAutoOffAlert;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setSilenceMultiCommandAlert(boolean silenceMultiCommandAlert) {
|
||||
this.silenceMultiCommandAlert = silenceMultiCommandAlert;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setSilenceExpirationImminentAlert(boolean silenceExpirationImminentAlert) {
|
||||
this.silenceExpirationImminentAlert = silenceExpirationImminentAlert;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setSilenceUserSetExpirationAlert(boolean silenceUserSetExpirationAlert) {
|
||||
this.silenceUserSetExpirationAlert = silenceUserSetExpirationAlert;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setSilenceLowReservoirAlert(boolean silenceLowReservoirAlert) {
|
||||
this.silenceLowReservoirAlert = silenceLowReservoirAlert;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setSilenceSuspendInProgressAlert(boolean silenceSuspendInProgressAlert) {
|
||||
this.silenceSuspendInProgressAlert = silenceSuspendInProgressAlert;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setSilenceSuspendEndedAlert(boolean silenceSuspendEndedAlert) {
|
||||
this.silenceSuspendEndedAlert = silenceSuspendEndedAlert;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setSilencePodExpirationAlert(boolean silencePodExpirationAlert) {
|
||||
this.silencePodExpirationAlert = silencePodExpirationAlert;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override protected final SilenceAlertsCommand buildCommand() {
|
||||
return new SilenceAlertsCommand(uniqueId, sequenceNumber, multiCommandFlag, new SilenceAlertCommandParameters(silenceAutoOffAlert, silenceMultiCommandAlert, silenceExpirationImminentAlert, silenceUserSetExpirationAlert, silenceLowReservoirAlert, silenceSuspendInProgressAlert, silenceSuspendEndedAlert, silencePodExpirationAlert), nonce);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,32 +3,48 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command;
|
|||
import java.nio.ByteBuffer;
|
||||
import java.util.BitSet;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.CommandType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.NonceEnabledCommand;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.builder.NonceEnabledCommandBuilder;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.Encodable;
|
||||
|
||||
public class StopDeliveryCommand extends CommandBase {
|
||||
public final class StopDeliveryCommand extends NonceEnabledCommand {
|
||||
private static final short LENGTH = 7;
|
||||
private static final byte BODY_LENGTH = 5;
|
||||
|
||||
private final DeliveryType deliveryType;
|
||||
private final BeepType beepType;
|
||||
|
||||
public StopDeliveryCommand(int address, short sequenceNumber, boolean unknown, DeliveryType deliveryType, BeepType beepType) {
|
||||
super(CommandType.STOP_DELIVERY, address, sequenceNumber, unknown);
|
||||
StopDeliveryCommand(int uniqueId, short sequenceNumber, boolean multiCommandFlag, DeliveryType deliveryType, BeepType beepType, int nonce) {
|
||||
super(CommandType.STOP_DELIVERY, uniqueId, sequenceNumber, multiCommandFlag, nonce);
|
||||
this.deliveryType = deliveryType;
|
||||
this.beepType = beepType;
|
||||
}
|
||||
|
||||
@Override public byte[] getEncoded() {
|
||||
return appendCrc(ByteBuffer.allocate(LENGTH + HEADER_LENGTH) //
|
||||
.put(encodeHeader(address, sequenceNumber, LENGTH, unknown)) //
|
||||
.put(encodeHeader(uniqueId, sequenceNumber, LENGTH, multiCommandFlag)) //
|
||||
.put(commandType.getValue()) //
|
||||
.put(BODY_LENGTH) //
|
||||
.putInt(1229869870) // FIXME ?? was: byte array of int 777211465 converted to little endian
|
||||
.put((byte) ((beepType.getValue() << 4) | deliveryType.getEncoded())) //
|
||||
.putInt(nonce) //
|
||||
.put((byte) ((beepType.getValue() << 4) | deliveryType.getEncoded()[0])) //
|
||||
.array());
|
||||
}
|
||||
|
||||
public enum DeliveryType {
|
||||
@Override public String toString() {
|
||||
return "StopDeliveryCommand{" +
|
||||
"deliveryType=" + deliveryType +
|
||||
", beepType=" + beepType +
|
||||
", nonce=" + nonce +
|
||||
", commandType=" + commandType +
|
||||
", uniqueId=" + uniqueId +
|
||||
", sequenceNumber=" + sequenceNumber +
|
||||
", multiCommandFlag=" + multiCommandFlag +
|
||||
'}';
|
||||
}
|
||||
|
||||
public enum DeliveryType implements Encodable {
|
||||
BASAL(true, false, false),
|
||||
TEMP_BASAL(false, true, false),
|
||||
BOLUS(false, false, true),
|
||||
|
@ -44,12 +60,38 @@ public class StopDeliveryCommand extends CommandBase {
|
|||
this.bolus = bolus;
|
||||
}
|
||||
|
||||
public byte getEncoded() {
|
||||
@Override public byte[] getEncoded() {
|
||||
BitSet bitSet = new BitSet(8);
|
||||
bitSet.set(0, this.basal);
|
||||
bitSet.set(1, this.tempBasal);
|
||||
bitSet.set(2, this.bolus);
|
||||
return bitSet.toByteArray()[0];
|
||||
return bitSet.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Builder extends NonceEnabledCommandBuilder<Builder, StopDeliveryCommand> {
|
||||
private DeliveryType deliveryType;
|
||||
private BeepType beepType = BeepType.LONG_SINGLE_BEEP;
|
||||
|
||||
public Builder setDeliveryType(DeliveryType deliveryType) {
|
||||
this.deliveryType = deliveryType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setBeepType(BeepType beepType) {
|
||||
this.beepType = beepType;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override protected final StopDeliveryCommand buildCommand() {
|
||||
if (deliveryType == null) {
|
||||
throw new IllegalArgumentException("deliveryType can not be null");
|
||||
}
|
||||
if (beepType == null) {
|
||||
throw new IllegalArgumentException("beepType can not be null");
|
||||
}
|
||||
return new StopDeliveryCommand(uniqueId, sequenceNumber, multiCommandFlag, deliveryType, beepType, nonce);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.Encodable;
|
||||
|
||||
public interface Command extends Encodable {
|
||||
CommandType getCommandType();
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command;
|
||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base;
|
||||
|
||||
public enum CommandType {
|
||||
SET_UNIQUE_ID((byte) 0x03),
|
||||
GET_VERSION((byte) 0x07),
|
||||
GET_STATUS((byte) 0x0e),
|
||||
SILENCE_ALERTS((byte) 0x11),
|
||||
PROGRAM_BASAL((byte) 0x13),
|
||||
PROGRAM_TEMP_BASAL((byte) 0x16),
|
||||
BOLUS((byte) 0x17),
|
||||
PROGRAM_BASAL((byte) 0x13), // Always preceded by 0x1a
|
||||
PROGRAM_TEMP_BASAL((byte) 0x16), // Always preceded by 0x1a
|
||||
PROGRAM_BOLUS((byte) 0x17), // Always preceded by 0x1a
|
||||
PROGRAM_ALERTS((byte) 0x19),
|
||||
DELIVERY_INTERLOCK((byte) 0x1a),
|
||||
PROGRAM_INSULIN((byte) 0x1a), // Always followed by one of: 0x13, 0x16, 0x17
|
||||
DEACTIVATE((byte) 0x1c),
|
||||
PROGRAM_BEEPS((byte) 0x1e),
|
||||
STOP_DELIVERY((byte) 0x1f);
|
|
@ -0,0 +1,40 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.MessageUtil;
|
||||
|
||||
public abstract class HeaderEnabledCommand implements Command {
|
||||
protected static final short HEADER_LENGTH = 6;
|
||||
|
||||
protected final CommandType commandType;
|
||||
protected final int uniqueId;
|
||||
protected final short sequenceNumber;
|
||||
protected final boolean multiCommandFlag;
|
||||
|
||||
protected HeaderEnabledCommand(CommandType commandType, int uniqueId, short sequenceNumber, boolean multiCommandFlag) {
|
||||
this.commandType = commandType;
|
||||
this.uniqueId = uniqueId;
|
||||
this.sequenceNumber = sequenceNumber;
|
||||
this.multiCommandFlag = multiCommandFlag;
|
||||
}
|
||||
|
||||
@Override public CommandType getCommandType() {
|
||||
return commandType;
|
||||
}
|
||||
|
||||
protected static byte[] appendCrc(byte[] command) {
|
||||
return ByteBuffer.allocate(command.length + 2) //
|
||||
.put(command) //
|
||||
.putShort(MessageUtil.createCrc(command)) //
|
||||
.array();
|
||||
}
|
||||
|
||||
protected static byte[] encodeHeader(int uniqueId, short sequenceNumber, short length, boolean multiCommandFlag) {
|
||||
return ByteBuffer.allocate(6) //
|
||||
.putInt(uniqueId) //
|
||||
.putShort((short) (((sequenceNumber & 0x0f) << 10) | length | ((multiCommandFlag ? 1 : 0) << 15))) //
|
||||
.array();
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue