This commit is contained in:
Milos Kozak 2022-05-04 22:20:49 +02:00
commit 6b41050516
44 changed files with 1141 additions and 684 deletions

View file

@ -109,7 +109,7 @@ android {
defaultConfig { defaultConfig {
multiDexEnabled true multiDexEnabled true
versionCode 1500 versionCode 1500
version "3.0.0.1-dev-i" version "3.0.0.2-dev-i"
buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "VERSION", '"' + version + '"'
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"' buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"' buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"'

View file

@ -602,6 +602,7 @@ class LoopPlugin @Inject constructor(
private fun applySMBRequest(request: APSResult, callback: Callback?) { private fun applySMBRequest(request: APSResult, callback: Callback?) {
if (!request.bolusRequested()) { if (!request.bolusRequested()) {
aapsLogger.debug(LTag.APS, "No SMB requested")
return return
} }
val pump = activePlugin.activePump val pump = activePlugin.activePump

View file

@ -21,6 +21,7 @@ import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.UserEntry import info.nightscout.androidaps.database.entities.UserEntry
import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.diaconn.events.EventDiaconnG8PumpLogReset
import info.nightscout.androidaps.events.EventAppExit import info.nightscout.androidaps.events.EventAppExit
import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.ImportExportPrefs import info.nightscout.androidaps.interfaces.ImportExportPrefs
@ -339,6 +340,7 @@ class ImportExportPrefsImpl @Inject constructor(
} }
private fun restartAppAfterImport(context: Context) { private fun restartAppAfterImport(context: Context) {
rxBus.send(EventDiaconnG8PumpLogReset())
sp.putBoolean(R.string.key_setupwizard_processed, true) sp.putBoolean(R.string.key_setupwizard_processed, true)
OKDialog.show(context, rh.gs(R.string.setting_imported), rh.gs(R.string.restartingapp)) { OKDialog.show(context, rh.gs(R.string.setting_imported), rh.gs(R.string.restartingapp)) {
uel.log(Action.IMPORT_SETTINGS, Sources.Maintenance) uel.log(Action.IMPORT_SETTINGS, Sources.Maintenance)

View file

@ -101,7 +101,7 @@ abstract class InsulinOrefBasePlugin(
return comment return comment
} }
abstract val peak: Int override abstract val peak: Int
abstract fun commentStandardText(): String abstract fun commentStandardText(): String
companion object { companion object {

View file

@ -17,6 +17,7 @@ interface SkinInterface {
val mainGraphHeight: Int // in dp val mainGraphHeight: Int // in dp
val secondaryGraphHeight: Int // in dp val secondaryGraphHeight: Int // in dp
// no pre processing by default
fun preProcessLandscapeActionsLayout(dm: DisplayMetrics, binding: ActionsFragmentBinding) { fun preProcessLandscapeActionsLayout(dm: DisplayMetrics, binding: ActionsFragmentBinding) {
} }

View file

@ -4,6 +4,6 @@
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24"> android:viewportHeight="24">
<path <path
android:pathData="M20.964,12.509V2.983l-2.932,2.932c-4.317,-3.412 -9.981,-3.694 -13.245,-0.43c-3.581,3.581 -2.909,10.058 1.5,14.467c0.427,0.427 0.877,0.807 1.338,1.163c-0.548,-0.841 -1.031,-1.781 -1.411,-2.812C4.438,13.481 5.49,8.653 8.565,7.519c1.867,-0.688 4.047,0.152 5.872,1.99l-3,3H20.964z" android:pathData="M20.156,12.76V4.35l-2.588,2.588c-3.811,-3.012 -8.811,-3.261 -11.692,-0.38C2.715,9.719 3.307,15.437 7.2,19.33c0.377,0.377 0.774,0.713 1.181,1.027c-0.483,-0.742 -0.91,-1.573 -1.245,-2.483c-1.569,-4.257 -0.64,-8.518 2.075,-9.519c1.648,-0.607 3.573,0.134 5.184,1.757l-2.648,2.648H20.156z"
android:fillColor="#739BE0"/> android:fillColor="#638CE1"/>
</vector> </vector>

View file

@ -302,6 +302,7 @@
android:paddingStart="10dp" android:paddingStart="10dp"
android:paddingEnd="10dp" android:paddingEnd="10dp"
android:text="@string/activate_profile" android:text="@string/activate_profile"
android:visibility="gone"
app:icon="@drawable/ic_local_activate" app:icon="@drawable/ic_local_activate"
app:iconTint="@color/ic_local_activate" /> app:iconTint="@color/ic_local_activate" />
@ -323,6 +324,7 @@
android:paddingStart="1dp" android:paddingStart="1dp"
android:paddingEnd="1dp" android:paddingEnd="1dp"
android:text="@string/reset" android:text="@string/reset"
android:visibility="gone"
app:icon="@drawable/ic_local_reset" app:icon="@drawable/ic_local_reset"
app:iconTint="@color/ic_local_reset" /> app:iconTint="@color/ic_local_reset" />
@ -338,6 +340,7 @@
android:paddingStart="1dp" android:paddingStart="1dp"
android:paddingEnd="1dp" android:paddingEnd="1dp"
android:text="@string/save" android:text="@string/save"
android:visibility="gone"
app:icon="@drawable/ic_local_save" app:icon="@drawable/ic_local_save"
app:iconTint="@color/ic_local_save" /> app:iconTint="@color/ic_local_save" />
</LinearLayout> </LinearLayout>

View file

@ -561,7 +561,6 @@
<string name="shortenergy">En</string> <string name="shortenergy">En</string>
<string name="shortprotein">Pr</string> <string name="shortprotein">Pr</string>
<string name="shortfat">Fat</string> <string name="shortfat">Fat</string>
<string name="active"><![CDATA[<Active>]]></string>
<string name="executingrightnow">Command is executed right now</string> <string name="executingrightnow">Command is executed right now</string>
<string name="missed_bg_readings">Missed BG readings</string> <string name="missed_bg_readings">Missed BG readings</string>
<string name="key_raise_notifications_as_android_notifications" translatable="false">raise_urgent_alarms_as_android_notification</string> <string name="key_raise_notifications_as_android_notifications" translatable="false">raise_urgent_alarms_as_android_notification</string>

View file

@ -59,7 +59,7 @@ buildscript {
plugins { plugins {
id "io.gitlab.arturbosch.detekt" version "1.20.0" id "io.gitlab.arturbosch.detekt" version "1.20.0"
id "org.jlleitschuh.gradle.ktlint" version "10.2.1" id "org.jlleitschuh.gradle.ktlint" version "10.3.0"
id 'org.barfuin.gradle.jacocolog' version '2.0.0' id 'org.barfuin.gradle.jacocolog' version '2.0.0'
id 'org.jetbrains.kotlin.android' version '1.6.21' apply false id 'org.jetbrains.kotlin.android' version '1.6.21' apply false
} }

View file

@ -70,7 +70,14 @@ public class RuffyScripter implements RuffyCommands {
private final IRTHandler mHandler = new IRTHandler.Stub() { private final IRTHandler mHandler = new IRTHandler.Stub() {
@Override @Override
public void log(String message) { public void log(String message) {
aapsLogger.debug(LTag.PUMP, "Ruffy says: " + message); // Ruffy is very verbose at this level, but the data provided isn't too helpful for
// debugging. For debugging Ruffy, it makes more sense to check logcat, where other
// possibly relevant (BT) events are also logged.
// Due to the amount of calls, logging this causes timing issues as reported in
// https://github.com/nightscout/AndroidAPS/issues/1619#issuecomment-1115811485
// This was caused by changing the log level from trace to debug so these messages
// where logged by default.
//aapsLogger.debug(LTag.PUMP, "Ruffy says: " + message);
} }
@Override @Override

View file

@ -30,7 +30,7 @@ interface DetermineBasalAdapterInterface {
uamAllowed: Boolean = false, uamAllowed: Boolean = false,
advancedFiltering: Boolean = false, advancedFiltering: Boolean = false,
isSaveCgmSource: Boolean = false isSaveCgmSource: Boolean = false
) {} )
operator fun invoke(): APSResult? operator fun invoke(): APSResult?
} }

View file

@ -27,6 +27,7 @@ interface Insulin : ConfigExportImport {
val friendlyName: String val friendlyName: String
val comment: String val comment: String
val dia: Double val dia: Double
val peak: Int
fun iobCalcForTreatment(bolus: Bolus, time: Long, dia: Double): Iob fun iobCalcForTreatment(bolus: Bolus, time: Long, dia: Double): Iob

View file

@ -271,7 +271,7 @@ class PumpSyncImplementation @Inject constructor(
.blockingGet() .blockingGet()
.also { result -> .also { result ->
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted TemporaryBasal $it") } result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted TemporaryBasal $it") }
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated TemporaryBasal $it") } result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated ${it.first} TemporaryBasal ${it.second}") }
return result.inserted.size > 0 return result.inserted.size > 0
} }
} }

View file

@ -316,7 +316,7 @@ enum class PumpType {
baseBasalMaxValue = 3.0, baseBasalMaxValue = 3.0,
baseBasalStep = 0.01, baseBasalStep = 0.01,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.DanaWithHistoryCapabilities, pumpCapability = PumpCapability.DiaconnCapabilities,
source = Sources.DiaconnG8, source = Sources.DiaconnG8,
useHardwareLink = true); useHardwareLink = true);

View file

@ -136,7 +136,7 @@ open class NumberPicker(context: Context, attrs: AttributeSet? = null) : LinearL
} }
fun updateA11yDescription() { fun updateA11yDescription() {
val description = if (mCustomContentDescription != null) mCustomContentDescription else "" val description = mCustomContentDescription ?: ""
binding.minusButton.contentDescription = context.getString(R.string.a11y_min_button_description, description, formatter?.format(this.step)) binding.minusButton.contentDescription = context.getString(R.string.a11y_min_button_description, description, formatter?.format(this.step))
binding.plusButton.contentDescription = context.getString(R.string.a11y_plus_button_description, description, formatter?.format(this.step)) binding.plusButton.contentDescription = context.getString(R.string.a11y_plus_button_description, description, formatter?.format(this.step))
} }

View file

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="64"
android:viewportHeight="64">
<path
android:pathData="M38.469,51.818c0,4.129 -7.132,7.565 -16.023,7.721S5.884,56.518 5.213,52.401c-0.671,-4.118 5.881,-7.794 14.722,-8.26s17.006,2.432 18.345,6.514L38.469,51.818zM31.797,34.218c0,4.897 -4.056,8.973 -9.112,9.157s-9.418,-3.583 -9.8,-8.466c-0.382,-4.883 3.345,-9.243 8.371,-9.797c5.028,-0.553 9.67,2.886 10.432,7.726C31.689,32.839 31.797,34.218 31.797,34.218z"
android:fillColor="?attr/colorControlNormal"/>
<path
android:pathData="M57.681,19.081c0.051,-0.386 0.077,-0.784 0.077,-1.208c0,-0.411 -0.026,-0.823 -0.09,-1.208l2.609,-2.031c0.231,-0.18 0.296,-0.527 0.154,-0.784l-2.468,-4.267C57.809,9.3 57.488,9.21 57.205,9.3l-3.072,1.234c-0.643,-0.488 -1.324,-0.9 -2.082,-1.208l-0.463,-3.265c-0.051,-0.308 -0.308,-0.527 -0.617,-0.527h-4.936c-0.308,0 -0.553,0.219 -0.604,0.527l-0.463,3.265c-0.758,0.308 -1.452,0.733 -2.082,1.208L39.815,9.3c-0.283,-0.103 -0.604,0 -0.758,0.283l-2.455,4.267c-0.154,0.27 -0.103,0.604 0.154,0.784l2.609,2.031c-0.064,0.386 -0.116,0.81 -0.116,1.208s0.026,0.823 0.09,1.208l-2.609,2.031c-0.231,0.18 -0.296,0.527 -0.154,0.784l2.468,4.267c0.154,0.283 0.476,0.373 0.758,0.283l3.072,-1.234c0.643,0.488 1.324,0.9 2.082,1.208l0.463,3.265c0.064,0.308 0.308,0.527 0.617,0.527h4.936c0.308,0 0.566,-0.219 0.604,-0.527l0.463,-3.265c0.758,-0.308 1.452,-0.72 2.082,-1.208l3.072,1.234c0.283,0.103 0.604,0 0.758,-0.283l2.468,-4.267c0.154,-0.283 0.09,-0.604 -0.154,-0.784L57.681,19.081zM48.503,22.5c-2.545,0 -4.627,-2.082 -4.627,-4.627s2.082,-4.627 4.627,-4.627c2.545,0 4.627,2.082 4.627,4.627S51.048,22.5 48.503,22.5z"
android:fillColor="?attr/colorControlNormal"/>
</vector>

View file

@ -7,24 +7,24 @@
android:pathData="M5.719,19.125L5.719,11.828" android:pathData="M5.719,19.125L5.719,11.828"
android:strokeWidth="2.2677" android:strokeWidth="2.2677"
android:fillColor="#00000000" android:fillColor="#00000000"
android:strokeColor="#FEAF05" android:strokeColor="?attr/statsColor"
android:strokeLineCap="round"/> android:strokeLineCap="round"/>
<path <path
android:pathData="M9.792,19.125L9.792,8.01" android:pathData="M9.792,19.125L9.792,8.01"
android:strokeWidth="2.2677" android:strokeWidth="2.2677"
android:fillColor="#00000000" android:fillColor="#00000000"
android:strokeColor="#FEAF05" android:strokeColor="?attr/statsColor"
android:strokeLineCap="round"/> android:strokeLineCap="round"/>
<path <path
android:pathData="M13.865,19.125L13.865,9.51" android:pathData="M13.865,19.125L13.865,9.51"
android:strokeWidth="2.2677" android:strokeWidth="2.2677"
android:fillColor="#00000000" android:fillColor="#00000000"
android:strokeColor="#FEAF05" android:strokeColor="?attr/statsColor"
android:strokeLineCap="round"/> android:strokeLineCap="round"/>
<path <path
android:pathData="M17.938,19.125L17.938,4.594" android:pathData="M17.938,19.125L17.938,4.594"
android:strokeWidth="2.2677" android:strokeWidth="2.2677"
android:fillColor="#00000000" android:fillColor="#00000000"
android:strokeColor="#FEAF05" android:strokeColor="?attr/statsColor"
android:strokeLineCap="round"/> android:strokeLineCap="round"/>
</vector> </vector>

View file

@ -65,6 +65,14 @@
<string name="key_pregnant" translatable="false">pregnant</string> <string name="key_pregnant" translatable="false">pregnant</string>
<string name="key_app_expiration" translatable="false">app_expiration</string> <string name="key_app_expiration" translatable="false">app_expiration</string>
<string name="key_use_dark_mode" translatable="false">use_dark_mode</string> <string name="key_use_dark_mode" translatable="false">use_dark_mode</string>
<string name="key_insulin_oref_peak" translatable="false">insulin_oref_peak</string>
<string name="key_autotune_auto" translatable="false">autotune_auto</string>
<string name="key_autotune_categorize_uam_as_basal" translatable="false">categorize_uam_as_basal</string>
<string name="key_autotune_default_tune_days" translatable="false">autotune_default_tune_days</string>
<string name="key_autotune_circadian_ic_isf" translatable="false">autotune_circadian_ic_isf</string>
<string name="key_autotune_additional_log" translatable="false">autotune_additional_log</string>
<string name="key_autotune_plugin" translatable="false">key_autotune_plugin</string>
<string name="key_autotune_last_run" translatable="false">key_autotune_last_run</string>
<!-- General--> <!-- General-->
<string name="refresh">Refresh</string> <string name="refresh">Refresh</string>
@ -107,6 +115,7 @@
<string name="carbs">Carbs</string> <string name="carbs">Carbs</string>
<string name="invalidprofile">Invalid profile !!!</string> <string name="invalidprofile">Invalid profile !!!</string>
<string name="noprofileset">NO PROFILE SET</string> <string name="noprofileset">NO PROFILE SET</string>
<string name="active"><![CDATA[<Active>]]></string>
<string name="date">Date</string> <string name="date">Date</string>
<string name="units_label">Units</string> <string name="units_label">Units</string>
<string name="dia_label">DIA</string> <string name="dia_label">DIA</string>
@ -536,6 +545,58 @@
<string name="a11y_file">file</string> <string name="a11y_file">file</string>
<string name="a11y_user">user</string> <string name="a11y_user">user</string>
<!-- Autotune -->
<string name="autotune">Autotune</string>
<string name="autotune_description">Help for potential adjustments of profile (ISF, carb ratio, and basal rates)</string>
<string name="autotune_shortname">AT</string>
<string name="autotune_settings">Autotune settings</string>
<string name="autotune_auto_title">Automation Switch Profile</string>
<string name="autotune_auto_summary">If enabled, Autotune will automatically update and switch to input profile after calculation from an automation rule.</string>
<string name="autotune_categorize_uam_as_basal_title">Categorize UAM as basal</string>
<string name="autotune_categorize_uam_as_basal_summary">Enable only if you have reliably entered all carbs eaten, with this option sudden rises seen by Autotune will be used to recommend changes to the basal rate.</string>
<string name="autotune_default_tune_days_title">Number of days of data</string>
<string name="autotune_circadian_ic_isf_title">Apply average result in circadian IC/ISF</string>
<string name="autotune_circadian_ic_isf_summary">Autotune will not tune circadian variations, this option only apply the average tuning of IC and ISF to your circadian input profile</string>
<string name="autotune_additional_log_title">Include more log information for debugging</string>
<string name="autotune_additional_log_summary">Switch on only if requested by dev to send more log information to help debugging Autotune plugin</string>
<string name="autotune_default_tune_days_summary">Default number of days of data to be processed by Autotune (up to xx)</string>
<string name="autotune_tunedprofile_name">Tuned</string>
<string name="autotune_profile">Profile :</string>
<string name="autotune_tune_days">Tune days :</string>
<string name="autotune_last_run">Last run :</string>
<string name="autotune_warning">Warning :</string>
<string name="autotune_select_profile">Select profile to tune</string>
<string name="autotune_ic_warning">Autotune works with only one IC value, your profile has %1$d values. Average value is %2$.2fg/U</string>
<string name="autotune_isf_warning">Autotune works with only one ISF value, your profile has %1$d values. Average value is %2$.1f%3$s/U</string>
<string name="autotune_error">Error in input data, try to reduce the number of days</string>
<string name="autotune_warning_during_run">Autotune calculation started, please be patient</string>
<string name="autotune_warning_after_run">Check the results carefully before using it!</string>
<string name="autotune_partial_result">Partial result day %1$d / %2$d tuned</string>
<string name="autotune_result">Result: %1$s</string>
<string name="autotune_param">Param</string>
<string name="autotune_percent">%</string>
<string name="autotune_missing">Missing</string>
<string name="autotune_profile_name">Autotune profile %1$s</string>
<string name="autotune_run">Run Autotune</string>
<string name="autotune_check_input_profile_button">Check input profile</string>
<string name="autotune_compare_profile">Compare profiles</string>
<string name="autotune_copy_localprofile_button">Copy to local profile</string>
<string name="autotune_update_input_profile_button">Update input profile</string>
<string name="autotune_revert_input_profile_button">Revert input profile</string>
<string name="autotune_copy_local_profile_message">Create a new local profile from this Autotune Profile?</string>
<string name="autotune_update_local_profile_message">Update %1$s profile with Autotune Profile?</string>
<string name="autotune_revert_local_profile_message">Revert %1$s profile with Input Profile?</string>
<string name="autotune_profile_invalid">Profile invalid</string>
<string name="autotune_log_title" translatable="false">|Param|Profile|Tuned|%/Miss.\n</string>
<string name="autotune_log_separator" translatable="false">+------------------------------------------\n</string>
<string name="autotune_log_isf" translatable="false">| %1$4.4s |\t%2$3.3f |\t%3$3.3f |\n</string>
<string name="autotune_log_ic" translatable="false">| %1$4.4s |\t%2$3.3f |\t%3$3.3f |\n</string>
<string name="autotune_log_basal" translatable="false">|\t%1$02.0f\t| %2$3.3f |%3$3.3f\t| %5$.0f%% / %4$d\n</string>
<string name="autotune_log_sum_basal" translatable="false">|\t∑\t|\t%1$3.1f |\t%2$3.1f |\n</string>
<string name="autotune_run_without_autoswitch">Autotune runned without profile switch</string>
<string name="autotune_run_with_autoswitch">Autotune runned and profile automatically switched</string>
<string name="autotune_run_with_error">Error during last Autotune run</string>
<plurals name="days"> <plurals name="days">
<item quantity="one">%1$d day</item> <item quantity="one">%1$d day</item>
<item quantity="other">%1$d days</item> <item quantity="other">%1$d days</item>

View file

@ -2,6 +2,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="info.nightscout.androidaps.dana.DanaFragment" tools:context="info.nightscout.androidaps.dana.DanaFragment"
android:orientation="vertical"> android:orientation="vertical">
@ -658,50 +659,58 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:orientation="horizontal">
<com.google.android.material.button.MaterialButton <info.nightscout.androidaps.utils.ui.SingleClickButton
android:id="@+id/view_profile" android:id="@+id/view_profile"
style="@style/ButtonSmallFontStyle" style="@style/ButtonSmallFontStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1" android:layout_weight="1"
android:layout_marginEnd="-2dp"
android:drawableTop="@drawable/ic_danarprofile" android:drawableTop="@drawable/ic_danarprofile"
android:paddingStart="0dp" android:text="@string/viewprofile"
android:paddingEnd="0dp" android:maxLines="2"
android:text="@string/viewprofile" /> android:ellipsize="end"
app:iconPadding="-4dp"/>
<com.google.android.material.button.MaterialButton <info.nightscout.androidaps.utils.ui.SingleClickButton
android:id="@+id/history" android:id="@+id/history"
style="@style/ButtonSmallFontStyle" style="@style/ButtonSmallFontStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1" android:layout_weight="1"
android:layout_marginEnd="-2dp"
android:drawableTop="@drawable/ic_pump_history" android:drawableTop="@drawable/ic_pump_history"
android:paddingStart="0dp"
android:paddingEnd="0dp"
android:text="@string/pumphistory" android:text="@string/pumphistory"
android:maxLines="2"
android:ellipsize="end"
app:iconPadding="-4dp"
tools:ignore="TooManyViews" /> tools:ignore="TooManyViews" />
<com.google.android.material.button.MaterialButton <info.nightscout.androidaps.utils.ui.SingleClickButton
android:id="@+id/stats" android:id="@+id/stats"
style="@style/ButtonSmallFontStyle" style="@style/ButtonSmallFontStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1" android:layout_weight="1"
android:layout_marginEnd="-2dp"
android:drawableTop="@drawable/ic_danarstats" android:drawableTop="@drawable/ic_danarstats"
android:paddingStart="0dp" android:text="@string/stats"
android:paddingEnd="0dp" android:maxLines="2"
android:text="@string/stats" /> android:ellipsize="end"
app:iconPadding="-4dp"/>
<com.google.android.material.button.MaterialButton <info.nightscout.androidaps.utils.ui.SingleClickButton
android:id="@+id/user_options" android:id="@+id/user_options"
style="@style/ButtonSmallFontStyle" style="@style/ButtonSmallFontStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1" android:layout_weight="1"
android:layout_marginEnd="-2dp"
android:drawableTop="@drawable/ic_danar_useropt" android:drawableTop="@drawable/ic_danar_useropt"
android:paddingStart="0dp" android:text="@string/danar_useroptions"
android:paddingEnd="0dp" android:maxLines="2"
android:text="@string/danar_useroptions" /> android:ellipsize="end"
app:iconPadding="-4dp"/>
</LinearLayout> </LinearLayout>

View file

@ -122,7 +122,7 @@ open class MessageBase(injector: HasAndroidInjector) {
} }
} }
open fun handleMessageNotReceived() {} open fun handleMessageNotReceived() {} // do nothing by default
val command: Int val command: Int
get() = byteFromRawBuff(buffer, 5) or (byteFromRawBuff(buffer, 4) shl 8) get() = byteFromRawBuff(buffer, 5) or (byteFromRawBuff(buffer, 4) shl 8)

View file

@ -29,7 +29,7 @@ class SyncPumpTemporaryBasalTransaction(
existing.duration = temporaryBasal.duration existing.duration = temporaryBasal.duration
existing.type = type ?: existing.type existing.type = type ?: existing.type
database.temporaryBasalDao.updateExistingEntry(existing) database.temporaryBasalDao.updateExistingEntry(existing)
result.updated.add(existing) result.updated.add(Pair(Reason.EXISTING_ID, existing))
} }
} else { } else {
val running = database.temporaryBasalDao.getTemporaryBasalActiveAt(temporaryBasal.timestamp).blockingGet() val running = database.temporaryBasalDao.getTemporaryBasalActiveAt(temporaryBasal.timestamp).blockingGet()
@ -37,7 +37,7 @@ class SyncPumpTemporaryBasalTransaction(
running.end = temporaryBasal.timestamp running.end = temporaryBasal.timestamp
running.interfaceIDs.endId = temporaryBasal.interfaceIDs.pumpId running.interfaceIDs.endId = temporaryBasal.interfaceIDs.pumpId
database.temporaryBasalDao.updateExistingEntry(running) database.temporaryBasalDao.updateExistingEntry(running)
result.updated.add(running) result.updated.add(Pair(Reason.ACTIVE, running))
} }
database.temporaryBasalDao.insertNewEntry(temporaryBasal) database.temporaryBasalDao.insertNewEntry(temporaryBasal)
result.inserted.add(temporaryBasal) result.inserted.add(temporaryBasal)
@ -45,9 +45,12 @@ class SyncPumpTemporaryBasalTransaction(
return result return result
} }
enum class Reason {
EXISTING_ID, ACTIVE
}
class TransactionResult { class TransactionResult {
val inserted = mutableListOf<TemporaryBasal>() val inserted = mutableListOf<TemporaryBasal>()
val updated = mutableListOf<TemporaryBasal>() val updated = mutableListOf<Pair<Reason,TemporaryBasal>>()
} }
} }

View file

@ -2,11 +2,11 @@
"formatVersion": 1, "formatVersion": 1,
"database": { "database": {
"version": 1, "version": 1,
"identityHash": "698b023da2f9efdc0351236c43eb20b6", "identityHash": "d604d25c3edbdf18cc5a39121cf5a779",
"entities": [ "entities": [
{ {
"tableName": "diaconnHistory", "tableName": "diaconnHistory",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`timestamp` INTEGER NOT NULL, `code` INTEGER NOT NULL, `value` REAL NOT NULL, `bolusType` TEXT NOT NULL, `stringValue` TEXT NOT NULL, `duration` INTEGER NOT NULL, `dailyBasal` REAL NOT NULL, `dailyBolus` REAL NOT NULL, `alarm` TEXT NOT NULL, PRIMARY KEY(`timestamp`))", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`timestamp` INTEGER NOT NULL, `code` INTEGER NOT NULL, `value` REAL NOT NULL, `bolusType` TEXT NOT NULL, `stringValue` TEXT NOT NULL, `duration` INTEGER NOT NULL, `dailyBasal` REAL NOT NULL, `dailyBolus` REAL NOT NULL, `alarm` TEXT NOT NULL, `lognum` INTEGER NOT NULL, `wrappingCount` INTEGER NOT NULL, `pumpUid` TEXT NOT NULL, PRIMARY KEY(`timestamp`))",
"fields": [ "fields": [
{ {
"fieldPath": "timestamp", "fieldPath": "timestamp",
@ -61,6 +61,24 @@
"columnName": "alarm", "columnName": "alarm",
"affinity": "TEXT", "affinity": "TEXT",
"notNull": true "notNull": true
},
{
"fieldPath": "lognum",
"columnName": "lognum",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "wrappingCount",
"columnName": "wrappingCount",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "pumpUid",
"columnName": "pumpUid",
"affinity": "TEXT",
"notNull": true
} }
], ],
"primaryKey": { "primaryKey": {
@ -77,6 +95,7 @@
"code", "code",
"timestamp" "timestamp"
], ],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_diaconnHistory_code_timestamp` ON `${TABLE_NAME}` (`code`, `timestamp`)" "createSql": "CREATE INDEX IF NOT EXISTS `index_diaconnHistory_code_timestamp` ON `${TABLE_NAME}` (`code`, `timestamp`)"
} }
], ],
@ -86,7 +105,7 @@
"views": [], "views": [],
"setupQueries": [ "setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '698b023da2f9efdc0351236c43eb20b6')" "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd604d25c3edbdf18cc5a39121cf5a779')"
] ]
} }
} }

View file

@ -187,6 +187,13 @@ class DiaconnG8Pump @Inject constructor(
var lgsTime:Int = 0 // LGS Setting time (0~255 min) var lgsTime:Int = 0 // LGS Setting time (0~255 min)
var lgsElapsedTime:Int = 0 // LGS Passed Time (0~255 min) var lgsElapsedTime:Int = 0 // LGS Passed Time (0~255 min)
val pumpUid: String
get() = "$country-$productType-$makeYear-${makeMonth.toString().padStart(2,'0')}-${makeDay.toString().padStart(2, '0')}-${lotNo.toString().padStart(3,'0')}-${serialNo.toString().padStart(5,'0')}"
val pumpVersion: String
get() = "$majorVersion.$minorVersion"
fun buildDiaconnG8ProfileRecord(nsProfile: Profile): Array<Double> { fun buildDiaconnG8ProfileRecord(nsProfile: Profile): Array<Double> {
val record = Array(24) { 0.0 } val record = Array(24) { 0.0 }
for (hour in 0..23) { for (hour in 0..23) {
@ -247,6 +254,7 @@ class DiaconnG8Pump @Inject constructor(
var apslastLogNum = 0 // 앱에서 처리한 마지막 로그 번호. var apslastLogNum = 0 // 앱에서 처리한 마지막 로그 번호.
var apsWrappingCount = 0 // 앱에서 처리한 마지막 로그 번호. var apsWrappingCount = 0 // 앱에서 처리한 마지막 로그 번호.
var isProgressPumpLogSync = false // 로그 동기화 진행 여부 var isProgressPumpLogSync = false // 로그 동기화 진행 여부
var isPlatformUploadStarted = false // 플랫폼 로그 동기화 진행 여부
// 6. bolus speed status. // 6. bolus speed status.
var speed = 0 // 주입 속도(1 ~ 8) var speed = 0 // 주입 속도(1 ~ 8)

View file

@ -0,0 +1,25 @@
package info.nightscout.androidaps.diaconn.api
import com.google.gson.annotations.SerializedName
data class LastNoResponse(val ok: Boolean, val info:Info )
data class Info(val pumplog_no: Long)
data class ApiResponse(val ok: Boolean)
data class PumpLogDto(
@SerializedName("app_uid") val app_uid: String,
@SerializedName("app_version") val app_version: String,
@SerializedName("pump_uid") val pump_uid: String,
@SerializedName("pump_version") val pump_version: String,
@SerializedName("incarnation_num") val incarnation_num: Int,
@SerializedName("pumplog_info") val pumplog_info: List<PumpLog>
)
data class PumpLog(
@SerializedName("pumplog_no") val pumplog_no: Long,
@SerializedName("pumplog_wrapping_count") val pumplog_wrapping_count: Int,
@SerializedName("pumplog_data") val pumplog_data: String,
@SerializedName("act_type") val act_type: String
)

View file

@ -0,0 +1,24 @@
package info.nightscout.androidaps.diaconn.api
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.Headers
import retrofit2.http.POST
import retrofit2.http.Query
interface DiaconnApiService {
@Headers("api-key: ${DiaconnLogUploader.UPLOAD_API_KEY}")
@GET("v1/pumplog/last_no")
fun getPumpLastNo(
@Query("pump_uid") pump_uid: String,
@Query("pump_version") pump_version: String,
@Query("incarnation_num") incarnation_num: Int): Call<LastNoResponse>
@Headers("api-key: ${DiaconnLogUploader.UPLOAD_API_KEY}")
@POST("v1/pumplog/save")
fun uploadPumpLogs(@Body pumpLogDto: PumpLogDto): Call<ApiResponse>
}

View file

@ -0,0 +1,31 @@
package info.nightscout.androidaps.diaconn.api
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class DiaconnLogUploader @Inject constructor (
private val aapsLogger: AAPSLogger,
) {
companion object {
private const val BASE_URL = "https://api.diaconn.com/aaps/"
const val UPLOAD_API_KEY = "D7B3DA9FA8229D5253F3D75E1E2B1BA4"
}
private var retrofit: Retrofit? = null
fun getRetrofitInstance(): Retrofit? {
aapsLogger.debug(LTag.PUMPCOMM, "diaconn pump logs upload instance")
if (retrofit == null) {
retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
return retrofit
}
}

View file

@ -15,5 +15,8 @@ data class DiaconnHistoryRecord(
var duration: Int = 0, var duration: Int = 0,
var dailyBasal: Double = 0.0, var dailyBasal: Double = 0.0,
var dailyBolus: Double = 0.0, var dailyBolus: Double = 0.0,
var alarm: String = "" var alarm: String = "",
var lognum: Int = 0,
var wrappingCount: Int = 0,
var pumpUid: String = ""
) )

View file

@ -14,4 +14,7 @@ abstract class DiaconnHistoryRecordDao {
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun createOrUpdate(diaconnHistoryRecord: DiaconnHistoryRecord) abstract fun createOrUpdate(diaconnHistoryRecord: DiaconnHistoryRecord)
@Query( "SELECT * from $TABLE_DIACONN_HISTORY WHERE pumpUid = :pumpUid ORDER BY timestamp DESC LIMIT 1" )
abstract fun getLastRecord(pumpUid: String): DiaconnHistoryRecord?
} }

View file

@ -6,7 +6,8 @@ import dagger.Module
DiaconnG8ActivitiesModule::class, DiaconnG8ActivitiesModule::class,
DiaconnG8ServiceModule::class, DiaconnG8ServiceModule::class,
DiaconnG8PacketModule::class, DiaconnG8PacketModule::class,
DiaconnHistoryModule::class DiaconnHistoryModule::class,
DiaconnLogUploaderModule::class
]) ])
open class DiaconnG8Module open class DiaconnG8Module

View file

@ -0,0 +1,12 @@
package info.nightscout.androidaps.diaconn.di
import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.diaconn.api.DiaconnLogUploader
import info.nightscout.androidaps.diaconn.service.DiaconnG8Service
@Module
@Suppress("unused")
abstract class DiaconnLogUploaderModule {
@ContributesAndroidInjector abstract fun contributesDiaconnLogUploader(): DiaconnLogUploader
}

View file

@ -0,0 +1,5 @@
package info.nightscout.androidaps.diaconn.events
import info.nightscout.androidaps.events.Event
class EventDiaconnG8PumpLogReset : Event()

View file

@ -14,7 +14,11 @@ import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.diaconn.DiaconnG8Plugin import info.nightscout.androidaps.diaconn.DiaconnG8Plugin
import info.nightscout.androidaps.diaconn.DiaconnG8Pump import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.diaconn.R import info.nightscout.androidaps.diaconn.R
import info.nightscout.androidaps.diaconn.api.DiaconnApiService
import info.nightscout.androidaps.diaconn.api.DiaconnLogUploader
import info.nightscout.androidaps.diaconn.database.DiaconnHistoryRecordDao
import info.nightscout.androidaps.diaconn.events.EventDiaconnG8NewStatus import info.nightscout.androidaps.diaconn.events.EventDiaconnG8NewStatus
import info.nightscout.androidaps.diaconn.events.EventDiaconnG8PumpLogReset
import info.nightscout.androidaps.diaconn.packet.* import info.nightscout.androidaps.diaconn.packet.*
import info.nightscout.androidaps.diaconn.pumplog.PumplogUtil import info.nightscout.androidaps.diaconn.pumplog.PumplogUtil
import info.nightscout.androidaps.dialogs.BolusProgressDialog import info.nightscout.androidaps.dialogs.BolusProgressDialog
@ -50,6 +54,7 @@ import java.util.concurrent.TimeUnit
import javax.inject.Inject import javax.inject.Inject
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.ceil import kotlin.math.ceil
import kotlin.math.floor
import kotlin.math.min import kotlin.math.min
class DiaconnG8Service : DaggerService() { class DiaconnG8Service : DaggerService() {
@ -73,6 +78,8 @@ class DiaconnG8Service : DaggerService() {
@Inject lateinit var pumpSync: PumpSync @Inject lateinit var pumpSync: PumpSync
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@Inject lateinit var aapsSchedulers: AapsSchedulers @Inject lateinit var aapsSchedulers: AapsSchedulers
@Inject lateinit var diaconnLogUploader: DiaconnLogUploader
@Inject lateinit var diaconnHistoryRecordDao: DiaconnHistoryRecordDao
private val disposable = CompositeDisposable() private val disposable = CompositeDisposable()
private val mBinder: IBinder = LocalBinder() private val mBinder: IBinder = LocalBinder()
@ -129,7 +136,7 @@ class DiaconnG8Service : DaggerService() {
} }
private fun sendMessage(message: DiaconnG8Packet) { private fun sendMessage(message: DiaconnG8Packet) {
bleCommonService.sendMessage(message, 500) bleCommonService.sendMessage(message, 2000)
} }
fun readPumpStatus() { fun readPumpStatus() {
@ -232,6 +239,7 @@ class DiaconnG8Service : DaggerService() {
} }
fun loadHistory(): PumpEnactResult { fun loadHistory(): PumpEnactResult {
if (!diaconnG8Plugin.isInitialized()) { if (!diaconnG8Plugin.isInitialized()) {
val result = PumpEnactResult(injector).success(false) val result = PumpEnactResult(injector).success(false)
result.comment = "pump not initialized" result.comment = "pump not initialized"
@ -245,6 +253,16 @@ class DiaconnG8Service : DaggerService() {
} }
val result = PumpEnactResult(injector) val result = PumpEnactResult(injector)
var apsLastLogNum = 9999
var apsWrappingCount = -1
// get saved last loginfo
val diaconnHistoryRecord = diaconnHistoryRecordDao.getLastRecord(diaconnG8Pump.pumpUid)
aapsLogger.error(LTag.PUMPCOMM, "diaconnHistoryRecord :: $diaconnHistoryRecord")
if(diaconnHistoryRecord != null) {
apsLastLogNum = diaconnHistoryRecord.lognum
apsWrappingCount = diaconnHistoryRecord.wrappingCount
}
// pump log status // pump log status
val pumpLastNum = diaconnG8Pump.pumpLastLogNum val pumpLastNum = diaconnG8Pump.pumpLastLogNum
@ -252,74 +270,107 @@ class DiaconnG8Service : DaggerService() {
val apsIncarnationNum = sp.getInt(rh.gs(R.string.apsIncarnationNo), 65536) val apsIncarnationNum = sp.getInt(rh.gs(R.string.apsIncarnationNo), 65536)
// aps last log num // aps last log num
val pumpSerialNo = sp.getInt(rh.gs(R.string.pumpserialno), 0) val pumpSerialNo = sp.getInt(rh.gs(R.string.pumpserialno), 0)
var apsWrappingCount = sp.getInt(rh.gs(R.string.apsWrappingCount), 0)
var apsLastLogNum = sp.getInt(rh.gs(R.string.apslastLogNum), 0)
// if first install app // if first install app
if (apsWrappingCount == 0 && apsLastLogNum == 0) { if (apsWrappingCount == -1 && apsLastLogNum == 9999 ) {
pumpLogDefaultSetting() apsWrappingCount = pumpWrappingCount
apsLastLogNum = if (pumpLastNum - 1 < 0) 0 else pumpLastNum -2
} }
// if pump reset
if (apsIncarnationNum != diaconnG8Pump.pumpIncarnationNum) {
pumpLogDefaultSetting()
sp.putInt(rh.gs(R.string.apsIncarnationNo), diaconnG8Pump.pumpIncarnationNum)
}
// if another pump // if another pump
if (pumpSerialNo != diaconnG8Pump.serialNo) { if (pumpSerialNo != diaconnG8Pump.serialNo) {
pumpLogDefaultSetting() apsWrappingCount = pumpWrappingCount
apsLastLogNum = if (pumpLastNum - 1 < 0) 0 else pumpLastNum -2
sp.putInt(rh.gs(R.string.pumpserialno), diaconnG8Pump.serialNo) sp.putInt(rh.gs(R.string.pumpserialno), diaconnG8Pump.serialNo)
} }
// if pump reset
apsWrappingCount = sp.getInt(rh.gs(R.string.apsWrappingCount), 0) if (apsIncarnationNum != diaconnG8Pump.pumpIncarnationNum) {
apsLastLogNum = sp.getInt(rh.gs(R.string.apslastLogNum), 0) apsWrappingCount = pumpWrappingCount
apsLastLogNum = if (pumpLastNum - 1 < 0) 0 else pumpLastNum -2
val apsLastNum = apsWrappingCount * 10000 + apsLastLogNum sp.putInt(R.string.apsIncarnationNo, apsIncarnationNum)
if ((pumpWrappingCount * 10000 + pumpLastNum) < apsLastLogNum) {
pumpLogDefaultSetting()
}
val start: Int? // log sync startNo
val end: Int? // log sync endNo
if (((pumpWrappingCount * 10000 + pumpLastNum) - apsLastNum) > 10000) {
start = pumpLastNum
end = 10000
} else if (pumpWrappingCount > apsWrappingCount && apsLastLogNum < 9999) {
start = apsLastLogNum + 1
end = 10000
} else if (pumpWrappingCount > apsWrappingCount && apsLastLogNum >= 9999) {
start = 0
end = pumpLastNum
} else {
start = apsLastLogNum + 1
end = pumpLastNum
} }
aapsLogger.debug(LTag.PUMPCOMM, "apsWrappingCount : $apsWrappingCount, apsLastLogNum : $apsLastLogNum")
// pump log loop size // pump log loop size
val pumpLogPageSize = 11 val pumpLogPageSize = 11
val loopCount: Int = ceil(((end - start) / 11.0)).toInt() val (start, end, loopSize) = getLogLoopCount(apsLastLogNum, apsWrappingCount, pumpLastNum, pumpWrappingCount, false)
aapsLogger.debug(LTag.PUMPCOMM, "loopinfo start : $start, end : $end, loopSize : $loopSize")
// log sync start! // log sync start!
if (loopCount > 0) { if (loopSize > 0) {
diaconnG8Pump.isProgressPumpLogSync = true for (i in 0 until loopSize) {
for (i in 0 until loopCount) {
val startLogNo: Int = start + i * pumpLogPageSize val startLogNo: Int = start + i * pumpLogPageSize
val endLogNo: Int = startLogNo + min(end - startLogNo, pumpLogPageSize) val endLogNo: Int = startLogNo + min(end - startLogNo, pumpLogPageSize)
val msg = BigLogInquirePacket(injector, startLogNo, endLogNo, 100) val msg = BigLogInquirePacket(injector, startLogNo, endLogNo, 100)
sendMessage(msg) sendMessage(msg, 500)
}
diaconnG8Pump.historyDoneReceived = true
while (!diaconnG8Pump.historyDoneReceived && bleCommonService.isConnected) {
SystemClock.sleep(100)
} }
result.success(true) result.success(true)
diaconnG8Pump.lastConnection = System.currentTimeMillis() diaconnG8Pump.lastConnection = System.currentTimeMillis()
} }
// upload pump log to Diaconn Cloud
if (sp.getBoolean(R.string.key_diaconn_g8_cloudsend, true)) {
SystemClock.sleep(1000)
try {
// getting last uploaded log number
val retrofit = diaconnLogUploader.getRetrofitInstance()
val api = retrofit?.create(DiaconnApiService::class.java)
val response = api?.getPumpLastNo(diaconnG8Pump.pumpUid, diaconnG8Pump.pumpVersion, diaconnG8Pump.pumpIncarnationNum)?.execute()
if(response?.body()?.ok == true) {
aapsLogger.debug(LTag.PUMPCOMM, "pumplog_no = ${response.body()?.info?.pumplog_no}")
val platformLastNo = response.body()?.info?.pumplog_no!!
val platformWrappingCount: Int = floor(platformLastNo / 10000.0).toInt()
val platformLogNo: Int = if (platformLastNo.toInt() == -1) {
9999
} else {
(platformLastNo % 10000).toInt()
}
aapsLogger.debug(LTag.PUMPCOMM, "platformLogNo: $platformLogNo, platformWrappingCount: $platformWrappingCount")
// 페이지 사이즈로 처리할 때 루핑 횟수 계산
val (platformStart, platformEnd, platformLoopSize) = getLogLoopCount(platformLogNo, platformWrappingCount, pumpLastNum, pumpWrappingCount, true)
if(platformLoopSize > 0) {
diaconnG8Pump.isPlatformUploadStarted = true
for (i in 0 until platformLoopSize) {
rxBus.send(EventPumpStatusChanged("클라우드동기화 진행 중 : $i / $platformLoopSize"))
val startLogNo: Int = platformStart + i * pumpLogPageSize
val endLogNo: Int = startLogNo + min(platformEnd - startLogNo, pumpLogPageSize)
val msg = BigLogInquirePacket(injector, startLogNo, endLogNo, 100)
sendMessage(msg, 500)
}
SystemClock.sleep(1000)
diaconnG8Pump.isPlatformUploadStarted = false
}
}
} catch (e:Exception) {
aapsLogger.error("Unhandled exception", e)
}
}
return result return result
} }
private fun getLogLoopCount(lastLogNum: Int, wrappingCount: Int, pumpLastNum: Int, pumpWrappingCount: Int, isPlatform: Boolean): Triple<Int, Int, Int> {
val start: Int// log sync start number
val end: Int // log sync end number1311
aapsLogger.debug(LTag.PUMPCOMM, "lastLogNum : $lastLogNum, wrappingCount : $wrappingCount , pumpLastNum: $pumpLastNum, pumpWrappingCount : $pumpWrappingCount")
if ((pumpWrappingCount * 10000 + pumpLastNum - lastLogNum > 10000 && isPlatform)) {
start = pumpLastNum
end = 10000
} else if (pumpWrappingCount > wrappingCount && lastLogNum < 9999) {
start = (lastLogNum + 1)
end = 10000
} else if (pumpWrappingCount > wrappingCount && lastLogNum >= 9999 && isPlatform) {
start = 0 // 처음부터 시작
end = pumpLastNum
} else {
start = (lastLogNum + 1)
end = pumpLastNum
}
val size = ceil((end - start) / 11.0).toInt()
//
return Triple(start, end, size)
}
fun setUserSettings(): PumpEnactResult { fun setUserSettings(): PumpEnactResult {
val result = PumpEnactResult(injector) val result = PumpEnactResult(injector)
@ -336,7 +387,7 @@ class DiaconnG8Service : DaggerService() {
if (diaconnG8Pump.otpNumber == 0) { if (diaconnG8Pump.otpNumber == 0) {
aapsLogger.error(LTag.PUMPCOMM, "otp is not received yet") aapsLogger.error(LTag.PUMPCOMM, "otp is not received yet")
result.success(false) result.success(false)
result.comment("펌프와 연결 상태를 확인해주세요.") result.comment("")
return result return result
} }
sendMessage(AppConfirmSettingPacket(injector, msg.msgType, diaconnG8Pump.otpNumber)) sendMessage(AppConfirmSettingPacket(injector, msg.msgType, diaconnG8Pump.otpNumber))
@ -348,6 +399,13 @@ class DiaconnG8Service : DaggerService() {
fun bolus(insulin: Double, carbs: Int, carbTime: Long, t: EventOverviewBolusProgress.Treatment): Boolean { fun bolus(insulin: Double, carbs: Int, carbTime: Long, t: EventOverviewBolusProgress.Treatment): Boolean {
if (!isConnected) return false if (!isConnected) return false
if (BolusProgressDialog.stopPressed) return false if (BolusProgressDialog.stopPressed) return false
// Only Carbs
if (carbs > 0 && insulin == 0.0) {
pumpSync.syncCarbsWithTimestamp(carbTime, carbs.toDouble(), null, PumpType.DIACONN_G8, diaconnG8Pump.serialNo.toString())
return true
}
rxBus.send(EventPumpStatusChanged(rh.gs(R.string.startingbolus))) rxBus.send(EventPumpStatusChanged(rh.gs(R.string.startingbolus)))
// bolus speed setting // bolus speed setting
@ -614,9 +672,9 @@ class DiaconnG8Service : DaggerService() {
(basalList[23] * 100).toInt() (basalList[23] * 100).toInt()
) )
// setting basal pattern 1,2,3,4 // setting basal pattern 1,2,3,4
sendMessage(requestReqPacket1) sendMessage(requestReqPacket1, 500)
sendMessage(requestReqPacket2) sendMessage(requestReqPacket2, 500)
sendMessage(requestReqPacket3) sendMessage(requestReqPacket3, 500)
sendMessage(requestReqPacket4) sendMessage(requestReqPacket4)
// otp process // otp process
@ -634,13 +692,6 @@ class DiaconnG8Service : DaggerService() {
return requestReqPacket4.success() return requestReqPacket4.success()
} }
private fun pumpLogDefaultSetting() {
val apsWrappingCount = diaconnG8Pump.pumpWrappingCount
val apsLastLogNum = if (diaconnG8Pump.pumpLastLogNum - 1 < 0) 0 else diaconnG8Pump.pumpLastLogNum - 1
sp.putInt(rh.gs(R.string.apslastLogNum), apsLastLogNum)
sp.putInt(rh.gs(R.string.apsWrappingCount), apsWrappingCount)
}
private fun processConfirm(msgType: Byte): Boolean { private fun processConfirm(msgType: Byte): Boolean {
// pump confirm // pump confirm
if (diaconnG8Pump.otpNumber == 0) { if (diaconnG8Pump.otpNumber == 0) {
@ -658,7 +709,7 @@ class DiaconnG8Service : DaggerService() {
return false return false
} }
sendMessage(AppConfirmSettingPacket(injector, msgType, diaconnG8Pump.otpNumber), 2000) sendMessage(AppConfirmSettingPacket(injector, msgType, diaconnG8Pump.otpNumber))
diaconnG8Pump.otpNumber = 0 diaconnG8Pump.otpNumber = 0
return true return true
} }

View file

@ -89,6 +89,8 @@
<string name="diaconn_g8_logcanulachange_title">바늘 교체</string> <string name="diaconn_g8_logcanulachange_title">바늘 교체</string>
<string name="diaconn_g8_logcanulachange_summary">로그 동기화 시 케어포털 \"위치 교체\" 정보 자동 업로드</string> <string name="diaconn_g8_logcanulachange_summary">로그 동기화 시 케어포털 \"위치 교체\" 정보 자동 업로드</string>
<string name="diaconn_g8_logbatterychange_summary">로그 동기화 시 케어포털 \"베터리 교체\" 정보 자동 업로드</string> <string name="diaconn_g8_logbatterychange_summary">로그 동기화 시 케어포털 \"베터리 교체\" 정보 자동 업로드</string>
<string name="diaconn_g8_cloudsend_summary">펌프 로그정보를 \"디아콘 클라우드\"로 자동 업로드</string>
<string name="diaconn_g8_cloudsend_title">디아콘 클라우드 전송</string>
<string name="diaconn_g8_logbatterychange_title">베터리 교체</string> <string name="diaconn_g8_logbatterychange_title">베터리 교체</string>
<string name="diaconn_g8_logsyncinprogress">로그 동기화 진행 중</string> <string name="diaconn_g8_logsyncinprogress">로그 동기화 진행 중</string>
<string name="diaconn_g8_loginsulinshorage">인슐린 부족 경고</string> <string name="diaconn_g8_loginsulinshorage">인슐린 부족 경고</string>

View file

@ -10,6 +10,7 @@
<string name="key_diaconn_g8_logbatterychange" translatable="false">diaconn_g8_logbatterychanges</string> <string name="key_diaconn_g8_logbatterychange" translatable="false">diaconn_g8_logbatterychanges</string>
<string name="key_diaconn_g8_loginsulinchange" translatable="false">diaconn_g8_loginsulinchange</string> <string name="key_diaconn_g8_loginsulinchange" translatable="false">diaconn_g8_loginsulinchange</string>
<string name="key_diaconn_g8_logneedlechange" translatable="false">diaconn_g8_logneedlechange</string> <string name="key_diaconn_g8_logneedlechange" translatable="false">diaconn_g8_logneedlechange</string>
<string name="key_diaconn_g8_cloudsend" translatable="false">diaconn_g8_cloudsend</string>
<string name="resetpairing" >Reset Pairing</string> <string name="resetpairing" >Reset Pairing</string>
<string name="diaconn_nodeviceavailable" >No Device available</string> <string name="diaconn_nodeviceavailable" >No Device available</string>
@ -166,5 +167,7 @@
<string name="diaconn_g8_errorcode_34">LGS status is OFF, OFF Command is declined.</string> <string name="diaconn_g8_errorcode_34">LGS status is OFF, OFF Command is declined.</string>
<string name="diaconn_g8_errorcode_35">Tempbasal start is rejected when tempbasal is running</string> <string name="diaconn_g8_errorcode_35">Tempbasal start is rejected when tempbasal is running</string>
<string name="diaconn_g8_errorcode_36">Tempbasal stop is rejected when tempbasal is not running</string> <string name="diaconn_g8_errorcode_36">Tempbasal stop is rejected when tempbasal is not running</string>
<string name="diaconn_g8_cloudsend_summary">Send pump logs to the Diaconn Cloud.</string>
<string name="diaconn_g8_cloudsend_title">Diaconn Cloud Sync</string>
<string name="key_diaconn_g8_appuid" translatable="false">diaconn_g8_appuid</string>
</resources> </resources>

View file

@ -45,6 +45,12 @@
android:summary="@string/diaconn_g8_logbatterychange_summary" android:summary="@string/diaconn_g8_logbatterychange_summary"
android:title="@string/diaconn_g8_logbatterychange_title" /> android:title="@string/diaconn_g8_logbatterychange_title" />
<SwitchPreference
android:defaultValue="true"
android:key="@string/key_diaconn_g8_cloudsend"
android:summary="@string/diaconn_g8_cloudsend_summary"
android:title="@string/diaconn_g8_cloudsend_title" />
</PreferenceCategory> </PreferenceCategory>
</androidx.preference.PreferenceScreen> </androidx.preference.PreferenceScreen>

20
icons/autotune.svg Normal file
View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="64px" height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">
<g id="Autotune">
<path fill="#FFFFFF" d="M38.469,51.818c0,4.129-7.132,7.565-16.023,7.721S5.884,56.518,5.213,52.401
c-0.671-4.118,5.881-7.794,14.722-8.26s17.006,2.432,18.345,6.514L38.469,51.818z M31.797,34.218c0,4.897-4.056,8.973-9.112,9.157
s-9.418-3.583-9.8-8.466c-0.382-4.883,3.345-9.243,8.371-9.797c5.028-0.553,9.67,2.886,10.432,7.726
C31.689,32.839,31.797,34.218,31.797,34.218z"/>
<path fill="#FFFFFF" d="M57.681,19.081c0.051-0.386,0.077-0.784,0.077-1.208c0-0.411-0.026-0.823-0.09-1.208l2.609-2.031
c0.231-0.18,0.296-0.527,0.154-0.784l-2.468-4.267C57.809,9.3,57.488,9.21,57.205,9.3l-3.072,1.234
c-0.643-0.488-1.324-0.9-2.082-1.208l-0.463-3.265c-0.051-0.308-0.308-0.527-0.617-0.527h-4.936c-0.308,0-0.553,0.219-0.604,0.527
l-0.463,3.265c-0.758,0.308-1.452,0.733-2.082,1.208L39.815,9.3c-0.283-0.103-0.604,0-0.758,0.283l-2.455,4.267
c-0.154,0.27-0.103,0.604,0.154,0.784l2.609,2.031c-0.064,0.386-0.116,0.81-0.116,1.208s0.026,0.823,0.09,1.208l-2.609,2.031
c-0.231,0.18-0.296,0.527-0.154,0.784l2.468,4.267c0.154,0.283,0.476,0.373,0.758,0.283l3.072-1.234
c0.643,0.488,1.324,0.9,2.082,1.208l0.463,3.265c0.064,0.308,0.308,0.527,0.617,0.527h4.936c0.308,0,0.566-0.219,0.604-0.527
l0.463-3.265c0.758-0.308,1.452-0.72,2.082-1.208l3.072,1.234c0.283,0.103,0.604,0,0.758-0.283l2.468-4.267
c0.154-0.283,0.09-0.604-0.154-0.784L57.681,19.081z M48.503,22.5c-2.545,0-4.627-2.082-4.627-4.627s2.082-4.627,4.627-4.627
c2.545,0,4.627,2.082,4.627,4.627S51.048,22.5,48.503,22.5z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

9
icons/clone_48.svg Normal file
View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="24px"
height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g id="Clone_x5F_48">
<path fill="#638CE1" d="M20.156,12.76V4.35l-2.588,2.588c-3.811-3.012-8.811-3.261-11.692-0.38C2.715,9.719,3.307,15.437,7.2,19.33
c0.377,0.377,0.774,0.713,1.181,1.027c-0.483-0.742-0.91-1.573-1.245-2.483c-1.569-4.257-0.64-8.518,2.075-9.519
c1.648-0.607,3.573,0.134,5.184,1.757l-2.648,2.648H20.156z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 594 B

View file

@ -58,7 +58,7 @@ public class InsightPairingActivity extends NoSplashAppCompatActivity implements
private RecyclerView deviceList; private RecyclerView deviceList;
private final DeviceAdapter deviceAdapter = new DeviceAdapter(); private final DeviceAdapter deviceAdapter = new DeviceAdapter();
private final int PERMISSION_REQUEST_BLUETOOTH = 30242; private static final int PERMISSION_REQUEST_BLUETOOTH = 30242;
private InsightConnectionService service; private InsightConnectionService service;

View file

@ -1364,16 +1364,17 @@ class OmnipodDashPumpPlugin @Inject constructor(
private fun handleCommandConfirmation(confirmation: CommandConfirmed) { private fun handleCommandConfirmation(confirmation: CommandConfirmed) {
val command = confirmation.command val command = confirmation.command
val historyEntry = history.getById(command.historyId) val historyEntry = history.getById(command.historyId)
aapsLogger.debug(LTag.PUMPCOMM, "handling command confirmation: $confirmation") aapsLogger.debug(LTag.PUMPCOMM, "handling command confirmation: $confirmation ${historyEntry.commandType}")
when (historyEntry.commandType) { when (historyEntry.commandType) {
OmnipodCommandType.CANCEL_TEMPORARY_BASAL -> { OmnipodCommandType.CANCEL_TEMPORARY_BASAL -> {
if (confirmation.success) { if (confirmation.success) {
pumpSync.syncStopTemporaryBasalWithPumpId( val ret = pumpSync.syncStopTemporaryBasalWithPumpId(
historyEntry.createdAt, historyEntry.createdAt,
historyEntry.pumpId(), historyEntry.pumpId(),
PumpType.OMNIPOD_DASH, PumpType.OMNIPOD_DASH,
serialNumber() serialNumber()
) )
aapsLogger.info(LTag.PUMP, "syncStopTemporaryBasalWithPumpId ret=$ret")
podStateManager.tempBasal = null podStateManager.tempBasal = null
} }
rxBus.send(EventDismissNotification(Notification.OMNIPOD_TBR_ALERTS)) rxBus.send(EventDismissNotification(Notification.OMNIPOD_TBR_ALERTS))