Merge remote-tracking branch 'origin/dev' into rs

This commit is contained in:
Milos Kozak 2020-04-29 00:07:25 +02:00
commit 90f08279d3
190 changed files with 4062 additions and 3048 deletions

View file

@ -123,6 +123,7 @@ tasks.matching { it instanceof Test }.all {
android { android {
compileSdkVersion 28 compileSdkVersion 28
ndkVersion "21.1.6352462"
defaultConfig { defaultConfig {
minSdkVersion 23 minSdkVersion 23

View file

@ -20,7 +20,6 @@ import androidx.test.rule.GrantPermissionRule
import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
@ -28,7 +27,6 @@ import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
import info.nightscout.androidaps.plugins.source.RandomBgPlugin import info.nightscout.androidaps.plugins.source.RandomBgPlugin
import info.nightscout.androidaps.setupwizard.SetupWizardActivity import info.nightscout.androidaps.setupwizard.SetupWizardActivity
import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.SP
import info.nightscout.androidaps.utils.extensions.isRunningTest import info.nightscout.androidaps.utils.extensions.isRunningTest
import org.hamcrest.CoreMatchers.allOf import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.Description import org.hamcrest.Description
@ -60,7 +58,7 @@ class SetupWizardActivityTest {
@Before @Before
fun clear() { fun clear() {
SP.clear() sp.clear()
} }
/* /*
@ -77,7 +75,7 @@ adb shell settings put global animator_duration_scale 0 &
@Test @Test
fun setupWizardActivityTest() { fun setupWizardActivityTest() {
SP.clear() sp.clear()
Assert.assertTrue(isRunningTest()) Assert.assertTrue(isRunningTest())
// Welcome page // Welcome page
onView(withId(R.id.next_button)).perform(click()) onView(withId(R.id.next_button)).perform(click())

View file

@ -23,10 +23,8 @@ import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.drawerlayout.widget.DrawerLayout import androidx.viewpager2.widget.ViewPager2
import androidx.viewpager.widget.ViewPager import com.google.android.material.tabs.TabLayoutMediator
import com.google.android.material.navigation.NavigationView
import com.google.android.material.tabs.TabLayout
import com.joanzapata.iconify.Iconify import com.joanzapata.iconify.Iconify
import com.joanzapata.iconify.fonts.FontAwesomeModule import com.joanzapata.iconify.fonts.FontAwesomeModule
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
@ -47,10 +45,10 @@ import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionChec
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.setupwizard.SetupWizardActivity import info.nightscout.androidaps.setupwizard.SetupWizardActivity
import info.nightscout.androidaps.tabs.TabPageAdapter import info.nightscout.androidaps.utils.tabs.TabPageAdapter
import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.androidaps.utils.AndroidPermission
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.LocaleHelper.update import info.nightscout.androidaps.utils.LocaleHelper
import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.extensions.isRunningRealPumpTest import info.nightscout.androidaps.utils.extensions.isRunningRealPumpTest
@ -86,50 +84,44 @@ class MainActivity : NoSplashAppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
Iconify.with(FontAwesomeModule()) Iconify.with(FontAwesomeModule())
update(applicationContext) LocaleHelper.update(applicationContext)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
supportActionBar?.setDisplayShowTitleEnabled(false) supportActionBar?.setDisplayShowTitleEnabled(false)
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setHomeButtonEnabled(true) supportActionBar?.setHomeButtonEnabled(true)
actionBarDrawerToggle = ActionBarDrawerToggle(this, drawer_layout, R.string.open_navigation, R.string.close_navigation).also { actionBarDrawerToggle = ActionBarDrawerToggle(this, main_drawer_layout, R.string.open_navigation, R.string.close_navigation).also {
drawer_layout.addDrawerListener(it) main_drawer_layout.addDrawerListener(it)
it.syncState() it.syncState()
} }
// initialize screen wake lock // initialize screen wake lock
processPreferenceChange(EventPreferenceChange(resourceHelper.gs(R.string.key_keep_screen_on))) processPreferenceChange(EventPreferenceChange(resourceHelper.gs(R.string.key_keep_screen_on)))
pager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { main_pager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageScrollStateChanged(state: Int) {}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
override fun onPageSelected(position: Int) { override fun onPageSelected(position: Int) {
checkPluginPreferences(pager) checkPluginPreferences(main_pager)
} }
override fun onPageScrollStateChanged(state: Int) {}
}) })
//Check here if loop plugin is disabled. Else check via constraints //Check here if loop plugin is disabled. Else check via constraints
if (!loopPlugin.isEnabled(PluginType.LOOP)) versionCheckerUtils.triggerCheckVersion() if (!loopPlugin.isEnabled(PluginType.LOOP)) versionCheckerUtils.triggerCheckVersion()
fabricPrivacy.setUserStats() fabricPrivacy.setUserStats()
setupTabs()
setupViews() setupViews()
disposable.add(rxBus disposable.add(rxBus
.toObservable(EventRebuildTabs::class.java) .toObservable(EventRebuildTabs::class.java)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ .subscribe({
update(applicationContext)
if (it.recreate) recreate() if (it.recreate) recreate()
else { else setupViews()
setupTabs()
setupViews()
}
setWakeLock() setWakeLock()
}) { fabricPrivacy.logException(it) } }) { fabricPrivacy::logException }
) )
disposable.add(rxBus disposable.add(rxBus
.toObservable(EventPreferenceChange::class.java) .toObservable(EventPreferenceChange::class.java)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ processPreferenceChange(it) }) { fabricPrivacy.logException(it) } .subscribe({ processPreferenceChange(it) }) { fabricPrivacy::logException }
) )
if (!sp.getBoolean(R.string.key_setupwizard_processed, false) && !isRunningRealPumpTest()) { if (!sp.getBoolean(R.string.key_setupwizard_processed, false) && !isRunningRealPumpTest()) {
val intent = Intent(this, SetupWizardActivity::class.java) val intent = Intent(this, SetupWizardActivity::class.java)
@ -144,7 +136,7 @@ class MainActivity : NoSplashAppCompatActivity() {
} }
} }
private fun checkPluginPreferences(viewPager: ViewPager) { private fun checkPluginPreferences(viewPager: ViewPager2) {
pluginPreferencesMenuItem?.isEnabled = (viewPager.adapter as TabPageAdapter).getPluginAt(viewPager.currentItem).preferencesId != -1 pluginPreferencesMenuItem?.isEnabled = (viewPager.adapter as TabPageAdapter).getPluginAt(viewPager.currentItem).preferencesId != -1
} }
@ -179,50 +171,46 @@ class MainActivity : NoSplashAppCompatActivity() {
} }
private fun setupViews() { private fun setupViews() {
val pageAdapter = TabPageAdapter(supportFragmentManager, this) // Menu
val navigationView = findViewById<NavigationView>(R.id.navigation_view) val pageAdapter = TabPageAdapter(this)
navigationView.setNavigationItemSelectedListener { true } main_navigation_view.setNavigationItemSelectedListener { true }
val menu = navigationView.menu.also { it.clear() } val menu = main_navigation_view.menu.also { it.clear() }
for (p in activePlugin.pluginsList) { for (p in activePlugin.pluginsList) {
pageAdapter.registerNewFragment(p) pageAdapter.registerNewFragment(p)
if (p.hasFragment() && !p.isFragmentVisible() && p.isEnabled(p.pluginDescription.type) && !p.pluginDescription.neverVisible) { if (p.isEnabled() && p.hasFragment() && !p.isFragmentVisible() && !p.pluginDescription.neverVisible) {
val menuItem = menu.add(p.name) val menuItem = menu.add(p.name)
menuItem.isCheckable = true menuItem.isCheckable = true
menuItem.setOnMenuItemClickListener { menuItem.setOnMenuItemClickListener {
val intent = Intent(this, SingleFragmentActivity::class.java) val intent = Intent(this, SingleFragmentActivity::class.java)
intent.putExtra("plugin", activePlugin.pluginsList.indexOf(p)) intent.putExtra("plugin", activePlugin.pluginsList.indexOf(p))
startActivity(intent) startActivity(intent)
(findViewById<View>(R.id.drawer_layout) as DrawerLayout).closeDrawers() main_drawer_layout.closeDrawers()
true true
} }
} }
} }
val mPager = findViewById<ViewPager>(R.id.pager) main_pager.adapter = pageAdapter
mPager.adapter = pageAdapter checkPluginPreferences(main_pager)
//if (switchToLast)
// mPager.setCurrentItem(pageAdapter.getCount() - 1, false);
checkPluginPreferences(mPager)
}
private fun setupTabs() { // Tabs
val viewPager = findViewById<ViewPager>(R.id.pager)
val normalTabs = findViewById<TabLayout>(R.id.tabs_normal)
normalTabs.setupWithViewPager(viewPager, true)
val compactTabs = findViewById<TabLayout>(R.id.tabs_compact)
compactTabs.setupWithViewPager(viewPager, true)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
if (sp.getBoolean(R.string.key_short_tabtitles, false)) { if (sp.getBoolean(R.string.key_short_tabtitles, false)) {
normalTabs.visibility = View.GONE tabs_normal.visibility = View.GONE
compactTabs.visibility = View.VISIBLE tabs_compact.visibility = View.VISIBLE
toolbar.layoutParams = LinearLayout.LayoutParams(Toolbar.LayoutParams.MATCH_PARENT, resources.getDimension(R.dimen.compact_height).toInt()) toolbar.layoutParams = LinearLayout.LayoutParams(Toolbar.LayoutParams.MATCH_PARENT, resources.getDimension(R.dimen.compact_height).toInt())
TabLayoutMediator(tabs_compact, main_pager) { tab, position ->
tab.text = (main_pager.adapter as TabPageAdapter).getPluginAt(position).nameShort
}.attach()
} else { } else {
normalTabs.visibility = View.VISIBLE tabs_normal.visibility = View.VISIBLE
compactTabs.visibility = View.GONE tabs_compact.visibility = View.GONE
val typedValue = TypedValue() val typedValue = TypedValue()
if (theme.resolveAttribute(R.attr.actionBarSize, typedValue, true)) { if (theme.resolveAttribute(R.attr.actionBarSize, typedValue, true)) {
toolbar.layoutParams = LinearLayout.LayoutParams(Toolbar.LayoutParams.MATCH_PARENT, toolbar.layoutParams = LinearLayout.LayoutParams(Toolbar.LayoutParams.MATCH_PARENT,
TypedValue.complexToDimensionPixelSize(typedValue.data, resources.displayMetrics)) TypedValue.complexToDimensionPixelSize(typedValue.data, resources.displayMetrics))
} }
TabLayoutMediator(tabs_normal, main_pager) { tab, position ->
tab.text = (main_pager.adapter as TabPageAdapter).getPluginAt(position).name
}.attach()
} }
} }
@ -260,7 +248,7 @@ class MainActivity : NoSplashAppCompatActivity() {
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_main, menu) menuInflater.inflate(R.menu.menu_main, menu)
pluginPreferencesMenuItem = menu.findItem(R.id.nav_plugin_preferences) pluginPreferencesMenuItem = menu.findItem(R.id.nav_plugin_preferences)
checkPluginPreferences(findViewById(R.id.pager)) checkPluginPreferences(main_pager)
return true return true
} }
@ -314,8 +302,7 @@ class MainActivity : NoSplashAppCompatActivity() {
} }
R.id.nav_plugin_preferences -> { R.id.nav_plugin_preferences -> {
val viewPager = findViewById<ViewPager>(R.id.pager) val plugin = (main_pager.adapter as TabPageAdapter).getPluginAt(main_pager.currentItem)
val plugin = (viewPager.adapter as TabPageAdapter).getPluginAt(viewPager.currentItem)
protectionCheck.queryProtection(this, ProtectionCheck.Protection.PREFERENCES, Runnable { protectionCheck.queryProtection(this, ProtectionCheck.Protection.PREFERENCES, Runnable {
val i = Intent(this, PreferencesActivity::class.java) val i = Intent(this, PreferencesActivity::class.java)
i.putExtra("id", plugin.preferencesId) i.putExtra("id", plugin.preferencesId)

View file

@ -186,7 +186,6 @@ public class MainApp extends DaggerApplication {
filter = new IntentFilter(); filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_CHANGED); filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_DATE_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
registerReceiver(new TimeDateOrTZChangeReceiver(), filter); registerReceiver(new TimeDateOrTZChangeReceiver(), filter);
@ -218,16 +217,6 @@ public class MainApp extends DaggerApplication {
return sResources.getString(id, args); return sResources.getString(id, args);
} }
@Deprecated
public static int gc(@ColorRes int id) {
return ContextCompat.getColor(instance(), id);
}
@Deprecated
public static Resources resources() {
return sResources;
}
@Deprecated @Deprecated
public static MainApp instance() { public static MainApp instance() {
return sInstance; return sInstance;

View file

@ -275,13 +275,13 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
} else if (pref.text != null) { } else if (pref.text != null) {
pref.dialogMessage = pref.dialogMessage pref.dialogMessage = pref.dialogMessage
pref.setSummary(pref.text) pref.setSummary(pref.text)
} else {
for (plugin in pluginStore.plugins) {
plugin.updatePreferenceSummary(pref)
}
} }
} }
for (plugin in pluginStore.plugins) {
pref?.let { pref-> pref.getKey()?.let { plugin.updatePreferenceSummary(pref) }}
}
val hmacPasswords = arrayOf( val hmacPasswords = arrayOf(
resourceHelper.gs(R.string.key_bolus_password), resourceHelper.gs(R.string.key_bolus_password),
resourceHelper.gs(R.string.key_master_password), resourceHelper.gs(R.string.key_master_password),

View file

@ -29,6 +29,7 @@ import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.MidnightTime; import info.nightscout.androidaps.utils.MidnightTime;
import info.nightscout.androidaps.utils.Round;
import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.resources.ResourceHelper;
public class Profile { public class Profile {
@ -496,6 +497,18 @@ public class Profile {
public int timeAsSeconds; public int timeAsSeconds;
public double value; public double value;
public boolean equals(Object otherObject) {
if (!(otherObject instanceof ProfileValue)) {
return false;
}
ProfileValue otherProfileValue = (ProfileValue) otherObject;
return (timeAsSeconds == otherProfileValue.timeAsSeconds) && Round.isSame(value, otherProfileValue.value);
}
} }
public synchronized ProfileValue[] getBasalValues() { public synchronized ProfileValue[] getBasalValues() {
@ -818,4 +831,26 @@ public class Profile {
} }
return new Profile(injector, o); return new Profile(injector, o);
} }
public boolean areProfileBasalPatternsSame(Profile otherProfile) {
if (!Round.isSame(this.baseBasalSum(), otherProfile.baseBasalSum()))
return false;
ProfileValue[] basalValues = this.getBasalValues();
ProfileValue[] otherBasalValues = otherProfile.getBasalValues();
if (basalValues.length != otherBasalValues.length)
return false;
for (int i = 0; i < basalValues.length; i++) {
if (!basalValues[i].equals(otherBasalValues[i])) {
return false;
}
}
return true;
}
} }

View file

@ -42,6 +42,7 @@ public class CareportalEvent implements DataPointWithLabelInterface, Interval {
@Inject ProfileFunction profileFunction; @Inject ProfileFunction profileFunction;
@Inject ResourceHelper resourceHelper; @Inject ResourceHelper resourceHelper;
@Inject AAPSLogger aapsLogger; @Inject AAPSLogger aapsLogger;
@Inject Translator translator;
@DatabaseField(id = true) @DatabaseField(id = true)
public long date; public long date;
@ -227,7 +228,7 @@ public class CareportalEvent implements DataPointWithLabelInterface, Interval {
} catch (JSONException e) { } catch (JSONException e) {
aapsLogger.error("Unhandled exception", e); aapsLogger.error("Unhandled exception", e);
} }
return Translator.translate(eventType); return translator.translate(eventType);
} }
public String getNotes() { public String getNotes() {

View file

@ -3,15 +3,12 @@ package info.nightscout.androidaps.db;
import com.j256.ormlite.field.DatabaseField; import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable; import com.j256.ormlite.table.DatabaseTable;
import org.slf4j.Logger; import java.util.Locale;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil; import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
/** /**
* Created by mike on 20.09.2017. * Created by mike on 20.09.2017.
@ -20,7 +17,6 @@ import info.nightscout.androidaps.utils.DateUtil;
@DatabaseTable(tableName = DatabaseHelper.DATABASE_TDDS) @DatabaseTable(tableName = DatabaseHelper.DATABASE_TDDS)
public class TDD { public class TDD {
private static Logger log = StacktraceLoggerWrapper.getLogger(L.DATABASE);
@DatabaseField(id = true) @DatabaseField(id = true)
public long date; public long date;
@ -35,14 +31,15 @@ public class TDD {
public double total; public double total;
public double getTotal(){ public double getTotal() {
return (total > 0d) ? total:(bolus+basal); return (total > 0d) ? total : (bolus + basal);
} }
public TDD() { } public TDD() {
}
public TDD(long date, double bolus, double basal, double total){ public TDD(long date, double bolus, double basal, double total) {
this.date = date; this.date = date;
this.bolus = bolus; this.bolus = bolus;
this.basal = basal; this.basal = basal;
@ -61,11 +58,11 @@ public class TDD {
']'; ']';
} }
public String toText() { public String toText(ResourceHelper resourceHelper) {
return MainApp.gs(R.string.tddformat, DateUtil.dateStringShort(date), total, bolus, basal); return resourceHelper.gs(R.string.tddformat, DateUtil.dateStringShort(date), total, bolus, basal);
} }
public String toText(int days) { public String toText(ResourceHelper resourceHelper, int days) {
return MainApp.gs(R.string.tddformat, String.format("%d ", days) + MainApp.gs(R.string.days), total, bolus, basal); return resourceHelper.gs(R.string.tddformat, String.format(Locale.getDefault(), "%d ", days) + resourceHelper.gs(R.string.days), total, bolus, basal);
} }
} }

View file

@ -29,6 +29,16 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensData
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobOref1Thread import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobOref1Thread
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobThread import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobThread
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkCommunicationManager
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RFSpy
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkBLE
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.command.SendAndListen
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.command.SetPreamble
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RadioPacket
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RadioResponse
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.*
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager
import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUITask
import info.nightscout.androidaps.plugins.treatments.Treatment import info.nightscout.androidaps.plugins.treatments.Treatment
import info.nightscout.androidaps.queue.CommandQueue import info.nightscout.androidaps.queue.CommandQueue
import info.nightscout.androidaps.queue.commands.* import info.nightscout.androidaps.queue.commands.*
@ -185,6 +195,23 @@ interface AppComponent : AndroidInjector<MainApp> {
fun injectGraphData(graphData: GraphData) fun injectGraphData(graphData: GraphData)
//Medtronic
fun injectRileyLinkCommunicationManager(rileyLinkCommunicationManager: RileyLinkCommunicationManager)
fun injectMedtronicCommunicationManager(medtronicCommunicationManager: MedtronicCommunicationManager)
fun injectMedtronicUITask(medtronicUITask: MedtronicUITask)
fun injectServiceTask(serviceTask: ServiceTask)
fun injectPumpTask(pumpTask: PumpTask)
fun injectDiscoverGattServicesTask(discoverGattServicesTask: DiscoverGattServicesTask)
fun injectInitializePumpManagerTask(initializePumpManagerTask: InitializePumpManagerTask)
fun injectResetRileyLinkConfigurationTask(resetRileyLinkConfigurationTask: ResetRileyLinkConfigurationTask)
fun injectWakeAndTuneTask(wakeAndTuneTask: WakeAndTuneTask)
fun injectRadioResponse(radioResponse: RadioResponse)
fun injectRileyLinkBLE(rileyLinkBLE: RileyLinkBLE)
fun injectRFSpy(rfSpy: RFSpy)
fun injectSendAndListen(sendAndListen: SendAndListen)
fun injectSetPreamble(setPreamble: SetPreamble)
fun injectRadioPacket(radioPacket: RadioPacket)
@Component.Builder @Component.Builder
interface Builder { interface Builder {

View file

@ -46,6 +46,16 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensData
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobOref1Thread import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobOref1Thread
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobThread import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobThread
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkCommunicationManager
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RFSpy
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkBLE
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.command.SendAndListen
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.command.SetPreamble
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RadioPacket
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RadioResponse
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.*
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager
import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUITask
import info.nightscout.androidaps.plugins.treatments.Treatment import info.nightscout.androidaps.plugins.treatments.Treatment
import info.nightscout.androidaps.queue.CommandQueue import info.nightscout.androidaps.queue.CommandQueue
import info.nightscout.androidaps.queue.commands.* import info.nightscout.androidaps.queue.commands.*
@ -278,6 +288,23 @@ open class AppModule {
@Binds fun bindContext(mainApp: MainApp): Context @Binds fun bindContext(mainApp: MainApp): Context
@Binds fun bindInjector(mainApp: MainApp): HasAndroidInjector @Binds fun bindInjector(mainApp: MainApp): HasAndroidInjector
// Medtronic
@ContributesAndroidInjector fun rileyLinkCommunicationManagerProvider(): RileyLinkCommunicationManager
@ContributesAndroidInjector fun medtronicCommunicationManagerProvider(): MedtronicCommunicationManager
@ContributesAndroidInjector fun medtronicUITaskProvider(): MedtronicUITask
@ContributesAndroidInjector fun serviceTaskProvider(): ServiceTask
@ContributesAndroidInjector fun pumpTaskProvider(): PumpTask
@ContributesAndroidInjector fun discoverGattServicesTaskProvider(): DiscoverGattServicesTask
@ContributesAndroidInjector fun initializePumpManagerTaskProvider(): InitializePumpManagerTask
@ContributesAndroidInjector fun resetRileyLinkConfigurationTaskProvider(): ResetRileyLinkConfigurationTask
@ContributesAndroidInjector fun wakeAndTuneTaskProvider(): WakeAndTuneTask
@ContributesAndroidInjector fun radioResponseProvider(): RadioResponse
@ContributesAndroidInjector fun rileyLinkBLEProvider(): RileyLinkBLE
@ContributesAndroidInjector fun rfSpyProvider(): RFSpy
@ContributesAndroidInjector fun sendAndListenProvider(): SendAndListen
@ContributesAndroidInjector fun setPreambleProvider(): SetPreamble
@ContributesAndroidInjector fun radioPacketProvider(): RadioPacket
@Binds @Binds
fun bindActivePluginProvider(pluginStore: PluginStore): ActivePluginProvider fun bindActivePluginProvider(pluginStore: PluginStore): ActivePluginProvider

View file

@ -32,10 +32,13 @@ import info.nightscout.androidaps.plugins.insulin.InsulinFragment
import info.nightscout.androidaps.plugins.profile.local.LocalProfileFragment import info.nightscout.androidaps.plugins.profile.local.LocalProfileFragment
import info.nightscout.androidaps.plugins.profile.ns.NSProfileFragment import info.nightscout.androidaps.plugins.profile.ns.NSProfileFragment
import info.nightscout.androidaps.plugins.pump.combo.ComboFragment import info.nightscout.androidaps.plugins.pump.combo.ComboFragment
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusGeneralFragment
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusHistoryFragment
import info.nightscout.androidaps.plugins.pump.danaR.DanaRFragment import info.nightscout.androidaps.plugins.pump.danaR.DanaRFragment
import info.nightscout.androidaps.plugins.pump.danaRS.dialogs.PairingProgressDialog import info.nightscout.androidaps.plugins.pump.danaRS.dialogs.PairingProgressDialog
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightFragment import info.nightscout.androidaps.plugins.pump.insight.LocalInsightFragment
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicFragment import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicFragment
import info.nightscout.androidaps.plugins.pump.medtronic.dialog.RileyLinkStatusDeviceMedtronic
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpFragment import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpFragment
import info.nightscout.androidaps.plugins.source.BGSourceFragment import info.nightscout.androidaps.plugins.source.BGSourceFragment
import info.nightscout.androidaps.plugins.treatments.TreatmentsFragment import info.nightscout.androidaps.plugins.treatments.TreatmentsFragment
@ -115,4 +118,8 @@ abstract class FragmentsModule {
@ContributesAndroidInjector abstract fun contributesWizardInfoDialog(): WizardInfoDialog @ContributesAndroidInjector abstract fun contributesWizardInfoDialog(): WizardInfoDialog
@ContributesAndroidInjector abstract fun contributesPasswordCheck(): PasswordCheck @ContributesAndroidInjector abstract fun contributesPasswordCheck(): PasswordCheck
@ContributesAndroidInjector abstract fun contributesRileyLinkStatusGeneral(): RileyLinkStatusGeneralFragment
@ContributesAndroidInjector abstract fun contributesRileyLinkStatusHistoryFragment(): RileyLinkStatusHistoryFragment
@ContributesAndroidInjector abstract fun contributesRileyLinkStatusDeviceMedtronic(): RileyLinkStatusDeviceMedtronic
} }

View file

@ -214,7 +214,8 @@ abstract class PluginsModule {
@Binds @Binds
@AllConfigs @AllConfigs
@IntoSet @IntoMap
@IntKey(265)
abstract fun bindSafetyPlugin(plugin: SafetyPlugin): PluginBase abstract fun bindSafetyPlugin(plugin: SafetyPlugin): PluginBase
@Binds @Binds

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.dependencyInjection
import dagger.Module import dagger.Module
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkBluetoothStateReceiver import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkBluetoothStateReceiver
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkBroadcastReceiver
import info.nightscout.androidaps.receivers.* import info.nightscout.androidaps.receivers.*
@Module @Module
@ -17,4 +18,6 @@ abstract class ReceiversModule {
@ContributesAndroidInjector abstract fun contributesRileyLinkBluetoothStateReceiver(): RileyLinkBluetoothStateReceiver @ContributesAndroidInjector abstract fun contributesRileyLinkBluetoothStateReceiver(): RileyLinkBluetoothStateReceiver
@ContributesAndroidInjector abstract fun contributesSmsReceiver(): SmsReceiver @ContributesAndroidInjector abstract fun contributesSmsReceiver(): SmsReceiver
@ContributesAndroidInjector abstract fun contributesTimeDateOrTZChangeReceiver(): TimeDateOrTZChangeReceiver @ContributesAndroidInjector abstract fun contributesTimeDateOrTZChangeReceiver(): TimeDateOrTZChangeReceiver
@ContributesAndroidInjector abstract fun contributesRileyLinkBroadcastReceiver(): RileyLinkBroadcastReceiver
} }

View file

@ -36,6 +36,7 @@ class CareDialog : DialogFragmentWithDate() {
@Inject lateinit var mainApp: MainApp @Inject lateinit var mainApp: MainApp
@Inject lateinit var resourceHelper: ResourceHelper @Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var translator: Translator
enum class EventType { enum class EventType {
BGCHECK, BGCHECK,
@ -149,7 +150,7 @@ class CareDialog : DialogFragmentWithDate() {
actions_care_sensor.isChecked -> "Sensor" actions_care_sensor.isChecked -> "Sensor"
else -> "Manual" else -> "Manual"
} }
actions.add(resourceHelper.gs(R.string.careportal_newnstreatment_glucosetype) + ": " + Translator.translate(type)) actions.add(resourceHelper.gs(R.string.careportal_newnstreatment_glucosetype) + ": " + translator.translate(type))
actions.add(resourceHelper.gs(R.string.treatments_wizard_bg_label) + ": " + Profile.toCurrentUnitsString(profileFunction, actions_care_bg.value) + " " + resourceHelper.gs(unitResId)) actions.add(resourceHelper.gs(R.string.treatments_wizard_bg_label) + ": " + Profile.toCurrentUnitsString(profileFunction, actions_care_bg.value) + " " + resourceHelper.gs(unitResId))
json.put("glucose", actions_care_bg.value) json.put("glucose", actions_care_bg.value)
json.put("glucoseType", type) json.put("glucoseType", type)

View file

@ -1,3 +1,3 @@
package info.nightscout.androidaps.events package info.nightscout.androidaps.events
class EventChargingState(val isCharging: Boolean) : Event() class EventChargingState(val isCharging: Boolean, val batterLevel: Int) : Event()

View file

@ -60,6 +60,8 @@ public class PumpDescription {
public boolean supportsTDDs; public boolean supportsTDDs;
public boolean needsManualTDDLoad; public boolean needsManualTDDLoad;
public boolean hasFixedUnreachableAlert;
public boolean hasCustomUnreachableAlertCheck;
public void resetSettings() { public void resetSettings() {
isBolusCapable = true; isBolusCapable = true;
@ -92,6 +94,9 @@ public class PumpDescription {
supportsTDDs = false; supportsTDDs = false;
needsManualTDDLoad = true; needsManualTDDLoad = true;
hasFixedUnreachableAlert = false;
hasCustomUnreachableAlertCheck = false;
} }
public void setPumpDescription(PumpType pumpType) { public void setPumpDescription(PumpType pumpType) {
@ -139,6 +144,9 @@ public class PumpDescription {
needsManualTDDLoad = pumpCapability.hasCapability(PumpCapability.ManualTDDLoad); needsManualTDDLoad = pumpCapability.hasCapability(PumpCapability.ManualTDDLoad);
is30minBasalRatesCapable = pumpCapability.hasCapability(PumpCapability.BasalRate30min); is30minBasalRatesCapable = pumpCapability.hasCapability(PumpCapability.BasalRate30min);
hasFixedUnreachableAlert = pumpType.getHasFixedUnreachableAlert();
hasCustomUnreachableAlertCheck = pumpType.getHasCustomUnreachableAlertCheck();
} }
} }

View file

@ -14,6 +14,7 @@ import info.nightscout.androidaps.plugins.common.ManufacturerType;
import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction; import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction;
import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType; import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.utils.TimeChangeType;
/** /**
* Created by mike on 04.06.2016. * Created by mike on 04.06.2016.
@ -115,5 +116,10 @@ public interface PumpInterface {
* This method will be called when time or Timezone changes, and pump driver can then do a specific action (for * This method will be called when time or Timezone changes, and pump driver can then do a specific action (for
* example update clock on pump). * example update clock on pump).
*/ */
void timeDateOrTimeZoneChanged(); void timezoneOrDSTChanged(TimeChangeType timeChangeType);
/* Only used for pump types where hasCustomUnreachableAlertCheck=true */
default boolean isUnreachableAlertTimeoutExceeded(long alertTimeoutMilliseconds) {
return false;
}
} }

View file

@ -11,6 +11,7 @@ interface AAPSLogger {
fun debug(tag: LTag, message: String) fun debug(tag: LTag, message: String)
fun debug(tag: LTag, format: String, vararg arguments: Any?) fun debug(tag: LTag, format: String, vararg arguments: Any?)
fun warn(tag: LTag, message: String) fun warn(tag: LTag, message: String)
fun warn(tag: LTag, format: String, vararg arguments: Any?)
fun info(tag: LTag, message: String) fun info(tag: LTag, message: String)
fun info(tag: LTag, format: String, vararg arguments: Any?) fun info(tag: LTag, format: String, vararg arguments: Any?)
fun error(tag: LTag, message: String) fun error(tag: LTag, message: String)

View file

@ -28,6 +28,10 @@ class AAPSLoggerDebug : AAPSLogger {
Log.w(tag.tag, message) Log.w(tag.tag, message)
} }
override fun warn(tag: LTag, format: String, vararg arguments: Any?) {
Log.w(tag.tag, String.format(format, arguments))
}
override fun info(tag: LTag, message: String) { override fun info(tag: LTag, message: String) {
Log.i(tag.tag, message) Log.i(tag.tag, message)
} }

View file

@ -26,7 +26,7 @@ class AAPSLoggerProduction : AAPSLogger {
override fun debug(tag: LTag, format: String, vararg arguments: Any?) { override fun debug(tag: LTag, format: String, vararg arguments: Any?) {
if (L.isEnabled(tag.tag)) if (L.isEnabled(tag.tag))
LoggerFactory.getLogger(tag.tag).debug(stackLogMarker() + String.format(format, arguments)) LoggerFactory.getLogger(tag.tag).debug(stackLogMarker() + format, arguments)
} }
override fun warn(tag: LTag, message: String) { override fun warn(tag: LTag, message: String) {
@ -35,6 +35,10 @@ class AAPSLoggerProduction : AAPSLogger {
} }
} }
override fun warn(tag: LTag, format: String, vararg arguments: Any?) {
LoggerFactory.getLogger(tag.tag).warn(stackLogMarker() + format, arguments)
}
override fun info(tag: LTag, message: String) { override fun info(tag: LTag, message: String) {
if (L.isEnabled(tag.tag)) { if (L.isEnabled(tag.tag)) {
LoggerFactory.getLogger(tag.tag).info(stackLogMarker() + message) LoggerFactory.getLogger(tag.tag).info(stackLogMarker() + message)
@ -43,7 +47,7 @@ class AAPSLoggerProduction : AAPSLogger {
} }
override fun info(tag: LTag, format: String, vararg arguments: Any?) { override fun info(tag: LTag, format: String, vararg arguments: Any?) {
LoggerFactory.getLogger(tag.tag).info(stackLogMarker() + String.format(format, arguments)) LoggerFactory.getLogger(tag.tag).info(stackLogMarker() + format, arguments)
} }
override fun error(tag: LTag, message: String) { override fun error(tag: LTag, message: String) {
@ -61,7 +65,7 @@ class AAPSLoggerProduction : AAPSLogger {
} }
override fun error(format: String, vararg arguments: Any?) { override fun error(format: String, vararg arguments: Any?) {
LoggerFactory.getLogger(LTag.CORE.tag).error(stackLogMarker() + String.format(format, arguments)) LoggerFactory.getLogger(LTag.CORE.tag).error(stackLogMarker() + format, arguments)
} }
override fun error(tag: LTag, message: String, throwable: Throwable) { override fun error(tag: LTag, message: String, throwable: Throwable) {
@ -72,7 +76,7 @@ class AAPSLoggerProduction : AAPSLogger {
override fun error(tag: LTag, format: String, vararg arguments: Any?) { override fun error(tag: LTag, format: String, vararg arguments: Any?) {
if (L.isEnabled(tag.tag)) { if (L.isEnabled(tag.tag)) {
LoggerFactory.getLogger(tag.tag).error(stackLogMarker() + String.format(format, arguments)) LoggerFactory.getLogger(tag.tag).error(stackLogMarker() + format, arguments)
} }
} }
} }

View file

@ -26,6 +26,10 @@ class AAPSLoggerTest : AAPSLogger {
println("WARN: " + tag.tag + " " + message) println("WARN: " + tag.tag + " " + message)
} }
override fun warn(tag: LTag, format: String, vararg arguments: Any?) {
println("INFO: : " + tag.tag + " " + String.format(format, arguments))
}
override fun info(tag: LTag, message: String) { override fun info(tag: LTag, message: String) {
println("INFO: " + tag.tag + " " + message) println("INFO: " + tag.tag + " " + message)
} }

View file

@ -17,8 +17,6 @@ import org.jetbrains.annotations.Nullable;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import java.util.Date;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
@ -49,7 +47,6 @@ import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopSetLastRunGui; import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopSetLastRunGui;
import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopUpdateGui; import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopUpdateGui;
@ -65,6 +62,7 @@ import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.queue.commands.Command; import info.nightscout.androidaps.queue.commands.Command;
import info.nightscout.androidaps.receivers.ReceiverStatusStore;
import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.T; import info.nightscout.androidaps.utils.T;
@ -88,6 +86,8 @@ public class LoopPlugin extends PluginBase {
private final VirtualPumpPlugin virtualPumpPlugin; private final VirtualPumpPlugin virtualPumpPlugin;
private final Lazy<ActionStringHandler> actionStringHandler; private final Lazy<ActionStringHandler> actionStringHandler;
private final IobCobCalculatorPlugin iobCobCalculatorPlugin; private final IobCobCalculatorPlugin iobCobCalculatorPlugin;
private final ReceiverStatusStore receiverStatusStore;
private final FabricPrivacy fabricPrivacy;
private CompositeDisposable disposable = new CompositeDisposable(); private CompositeDisposable disposable = new CompositeDisposable();
@ -105,7 +105,7 @@ public class LoopPlugin extends PluginBase {
public PumpEnactResult tbrSetByPump = null; public PumpEnactResult tbrSetByPump = null;
public PumpEnactResult smbSetByPump = null; public PumpEnactResult smbSetByPump = null;
public String source = null; public String source = null;
public long lastAPSRun = DateUtil.now(); public long lastAPSRun = DateUtil.now();
public long lastTBREnact = 0; public long lastTBREnact = 0;
public long lastSMBEnact = 0; public long lastSMBEnact = 0;
public long lastTBRRequest = 0; public long lastTBRRequest = 0;
@ -130,7 +130,9 @@ public class LoopPlugin extends PluginBase {
TreatmentsPlugin treatmentsPlugin, TreatmentsPlugin treatmentsPlugin,
VirtualPumpPlugin virtualPumpPlugin, VirtualPumpPlugin virtualPumpPlugin,
Lazy<ActionStringHandler> actionStringHandler, // TODO Adrian use RxBus instead of Lazy Lazy<ActionStringHandler> actionStringHandler, // TODO Adrian use RxBus instead of Lazy
IobCobCalculatorPlugin iobCobCalculatorPlugin IobCobCalculatorPlugin iobCobCalculatorPlugin,
ReceiverStatusStore receiverStatusStore,
FabricPrivacy fabricPrivacy
) { ) {
super(new PluginDescription() super(new PluginDescription()
.mainType(PluginType.LOOP) .mainType(PluginType.LOOP)
@ -154,6 +156,8 @@ public class LoopPlugin extends PluginBase {
this.virtualPumpPlugin = virtualPumpPlugin; this.virtualPumpPlugin = virtualPumpPlugin;
this.actionStringHandler = actionStringHandler; this.actionStringHandler = actionStringHandler;
this.iobCobCalculatorPlugin = iobCobCalculatorPlugin; this.iobCobCalculatorPlugin = iobCobCalculatorPlugin;
this.receiverStatusStore = receiverStatusStore;
this.fabricPrivacy = fabricPrivacy;
loopSuspendedTill = sp.getLong("loopSuspendedTill", 0L); loopSuspendedTill = sp.getLong("loopSuspendedTill", 0L);
isSuperBolus = sp.getBoolean("isSuperBolus", false); isSuperBolus = sp.getBoolean("isSuperBolus", false);
@ -167,7 +171,7 @@ public class LoopPlugin extends PluginBase {
disposable.add(rxBus disposable.add(rxBus
.toObservable(EventTempTargetChange.class) .toObservable(EventTempTargetChange.class)
.observeOn(Schedulers.io()) .observeOn(Schedulers.io())
.subscribe(event -> invoke("EventTempTargetChange", true), exception -> FabricPrivacy.getInstance().logException(exception)) .subscribe(event -> invoke("EventTempTargetChange", true), fabricPrivacy::logException)
); );
/** /**
* This method is triggered once autosens calculation has completed, so the LoopPlugin * This method is triggered once autosens calculation has completed, so the LoopPlugin
@ -191,7 +195,7 @@ public class LoopPlugin extends PluginBase {
lastBgTriggeredRun = bgReading.date; lastBgTriggeredRun = bgReading.date;
invoke("AutosenseCalculation for " + bgReading, true); invoke("AutosenseCalculation for " + bgReading, true);
}, exception -> FabricPrivacy.getInstance().logException(exception)) }, fabricPrivacy::logException)
); );
} }
@ -391,7 +395,7 @@ public class LoopPlugin extends PluginBase {
lastRun.lastSMBEnact = 0; lastRun.lastSMBEnact = 0;
lastRun.lastSMBRequest = 0; lastRun.lastSMBRequest = 0;
NSUpload.uploadDeviceStatus(this, iobCobCalculatorPlugin, profileFunction, activePlugin.getActivePump()); NSUpload.uploadDeviceStatus(this, iobCobCalculatorPlugin, profileFunction, activePlugin.getActivePump(), receiverStatusStore);
if (isSuspended()) { if (isSuspended()) {
getAapsLogger().debug(LTag.APS, resourceHelper.gs(R.string.loopsuspended)); getAapsLogger().debug(LTag.APS, resourceHelper.gs(R.string.loopsuspended));
@ -418,7 +422,7 @@ public class LoopPlugin extends PluginBase {
if (resultAfterConstraints.bolusRequested) if (resultAfterConstraints.bolusRequested)
lastRun.smbSetByPump = waiting; lastRun.smbSetByPump = waiting;
rxBus.send(new EventLoopUpdateGui()); rxBus.send(new EventLoopUpdateGui());
FabricPrivacy.getInstance().logCustom("APSRequest"); fabricPrivacy.logCustom("APSRequest");
applyTBRRequest(resultAfterConstraints, profile, new Callback() { applyTBRRequest(resultAfterConstraints, profile, new Callback() {
@Override @Override
public void run() { public void run() {
@ -516,13 +520,13 @@ public class LoopPlugin extends PluginBase {
lastRun.lastTBRRequest = lastRun.lastAPSRun; lastRun.lastTBRRequest = lastRun.lastAPSRun;
lastRun.lastTBREnact = DateUtil.now(); lastRun.lastTBREnact = DateUtil.now();
lastRun.lastOpenModeAccept = DateUtil.now(); lastRun.lastOpenModeAccept = DateUtil.now();
NSUpload.uploadDeviceStatus(lp, iobCobCalculatorPlugin, profileFunction, activePlugin.getActivePump()); NSUpload.uploadDeviceStatus(lp, iobCobCalculatorPlugin, profileFunction, activePlugin.getActivePump(), receiverStatusStore);
sp.incInt(R.string.key_ObjectivesmanualEnacts); sp.incInt(R.string.key_ObjectivesmanualEnacts);
} }
rxBus.send(new EventAcceptOpenLoopChange()); rxBus.send(new EventAcceptOpenLoopChange());
} }
}); });
FabricPrivacy.getInstance().logCustom("AcceptTemp"); fabricPrivacy.logCustom("AcceptTemp");
} }
/** /**

View file

@ -52,6 +52,8 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
private final TreatmentsPlugin treatmentsPlugin; private final TreatmentsPlugin treatmentsPlugin;
private final IobCobCalculatorPlugin iobCobCalculatorPlugin; private final IobCobCalculatorPlugin iobCobCalculatorPlugin;
private final HardLimits hardLimits; private final HardLimits hardLimits;
private final Profiler profiler;
private final FabricPrivacy fabricPrivacy;
// last values // last values
DetermineBasalAdapterAMAJS lastDetermineBasalAdapterAMAJS = null; DetermineBasalAdapterAMAJS lastDetermineBasalAdapterAMAJS = null;
@ -71,7 +73,9 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
ActivePluginProvider activePlugin, ActivePluginProvider activePlugin,
TreatmentsPlugin treatmentsPlugin, TreatmentsPlugin treatmentsPlugin,
IobCobCalculatorPlugin iobCobCalculatorPlugin, IobCobCalculatorPlugin iobCobCalculatorPlugin,
HardLimits hardLimits HardLimits hardLimits,
Profiler profiler,
FabricPrivacy fabricPrivacy
) { ) {
super(new PluginDescription() super(new PluginDescription()
.mainType(PluginType.APS) .mainType(PluginType.APS)
@ -92,6 +96,8 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
this.treatmentsPlugin = treatmentsPlugin; this.treatmentsPlugin = treatmentsPlugin;
this.iobCobCalculatorPlugin = iobCobCalculatorPlugin; this.iobCobCalculatorPlugin = iobCobCalculatorPlugin;
this.hardLimits = hardLimits; this.hardLimits = hardLimits;
this.profiler = profiler;
this.fabricPrivacy = fabricPrivacy;
} }
@Override @Override
@ -161,11 +167,11 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
long startPart = System.currentTimeMillis(); long startPart = System.currentTimeMillis();
IobTotal[] iobArray = iobCobCalculatorPlugin.calculateIobArrayInDia(profile); IobTotal[] iobArray = iobCobCalculatorPlugin.calculateIobArrayInDia(profile);
Profiler.log(aapsLogger, LTag.APS, "calculateIobArrayInDia()", startPart); profiler.log(LTag.APS, "calculateIobArrayInDia()", startPart);
startPart = System.currentTimeMillis(); startPart = System.currentTimeMillis();
MealData mealData = iobCobCalculatorPlugin.getMealData(); MealData mealData = iobCobCalculatorPlugin.getMealData();
Profiler.log(aapsLogger, LTag.APS, "getMealData()", startPart); profiler.log(LTag.APS, "getMealData()", startPart);
double maxIob = constraintChecker.getMaxIOBAllowed().value(); double maxIob = constraintChecker.getMaxIOBAllowed().value();
@ -206,8 +212,8 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
lastAutosensResult = new AutosensResult(); lastAutosensResult = new AutosensResult();
lastAutosensResult.sensResult = "autosens disabled"; lastAutosensResult.sensResult = "autosens disabled";
} }
Profiler.log(aapsLogger, LTag.APS, "detectSensitivityandCarbAbsorption()", startPart); profiler.log(LTag.APS, "detectSensitivityandCarbAbsorption()", startPart);
Profiler.log(aapsLogger, LTag.APS, "AMA data gathering", start); profiler.log(LTag.APS, "AMA data gathering", start);
start = System.currentTimeMillis(); start = System.currentTimeMillis();
@ -217,13 +223,13 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
isTempTarget isTempTarget
); );
} catch (JSONException e) { } catch (JSONException e) {
FabricPrivacy.getInstance().logException(e); fabricPrivacy.logException(e);
return; return;
} }
DetermineBasalResultAMA determineBasalResultAMA = determineBasalAdapterAMAJS.invoke(); DetermineBasalResultAMA determineBasalResultAMA = determineBasalAdapterAMAJS.invoke();
Profiler.log(aapsLogger, LTag.APS, "AMA calculation", start); profiler.log(LTag.APS, "AMA calculation", start);
// Fix bug determine basal // Fix bug determine basal
if (determineBasalResultAMA == null) { if (determineBasalResultAMA == null) {
aapsLogger.error(LTag.APS, "SMB calculation returned null"); aapsLogger.error(LTag.APS, "SMB calculation returned null");

View file

@ -54,6 +54,8 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr
private final TreatmentsPlugin treatmentsPlugin; private final TreatmentsPlugin treatmentsPlugin;
private final IobCobCalculatorPlugin iobCobCalculatorPlugin; private final IobCobCalculatorPlugin iobCobCalculatorPlugin;
private final HardLimits hardLimits; private final HardLimits hardLimits;
private final Profiler profiler;
private final FabricPrivacy fabricPrivacy;
// last values // last values
DetermineBasalAdapterSMBJS lastDetermineBasalAdapterSMBJS = null; DetermineBasalAdapterSMBJS lastDetermineBasalAdapterSMBJS = null;
@ -73,7 +75,9 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr
ActivePluginProvider activePlugin, ActivePluginProvider activePlugin,
TreatmentsPlugin treatmentsPlugin, TreatmentsPlugin treatmentsPlugin,
IobCobCalculatorPlugin iobCobCalculatorPlugin, IobCobCalculatorPlugin iobCobCalculatorPlugin,
HardLimits hardLimits HardLimits hardLimits,
Profiler profiler,
FabricPrivacy fabricPrivacy
) { ) {
super(new PluginDescription() super(new PluginDescription()
.mainType(PluginType.APS) .mainType(PluginType.APS)
@ -94,6 +98,8 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr
this.treatmentsPlugin = treatmentsPlugin; this.treatmentsPlugin = treatmentsPlugin;
this.iobCobCalculatorPlugin = iobCobCalculatorPlugin; this.iobCobCalculatorPlugin = iobCobCalculatorPlugin;
this.hardLimits = hardLimits; this.hardLimits = hardLimits;
this.profiler = profiler;
this.fabricPrivacy = fabricPrivacy;
} }
@Override @Override
@ -168,7 +174,7 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr
long startPart = System.currentTimeMillis(); long startPart = System.currentTimeMillis();
MealData mealData = iobCobCalculatorPlugin.getMealData(); MealData mealData = iobCobCalculatorPlugin.getMealData();
Profiler.log(getAapsLogger(), LTag.APS, "getMealData()", startPart); profiler.log(LTag.APS, "getMealData()", startPart);
Constraint<Double> maxIOBAllowedConstraint = constraintChecker.getMaxIOBAllowed(); Constraint<Double> maxIOBAllowedConstraint = constraintChecker.getMaxIOBAllowed();
inputConstraints.copyReasons(maxIOBAllowedConstraint); inputConstraints.copyReasons(maxIOBAllowedConstraint);
@ -213,7 +219,7 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr
} }
IobTotal[] iobArray = iobCobCalculatorPlugin.calculateIobArrayForSMB(lastAutosensResult, SMBDefaults.exercise_mode, SMBDefaults.half_basal_exercise_target, isTempTarget); IobTotal[] iobArray = iobCobCalculatorPlugin.calculateIobArrayForSMB(lastAutosensResult, SMBDefaults.exercise_mode, SMBDefaults.half_basal_exercise_target, isTempTarget);
Profiler.log(getAapsLogger(), LTag.APS, "calculateIobArrayInDia()", startPart); profiler.log(LTag.APS, "calculateIobArrayInDia()", startPart);
startPart = System.currentTimeMillis(); startPart = System.currentTimeMillis();
Constraint<Boolean> smbAllowed = new Constraint<>(!tempBasalFallback); Constraint<Boolean> smbAllowed = new Constraint<>(!tempBasalFallback);
@ -228,8 +234,8 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr
constraintChecker.isUAMEnabled(uam); constraintChecker.isUAMEnabled(uam);
inputConstraints.copyReasons(uam); inputConstraints.copyReasons(uam);
Profiler.log(getAapsLogger(), LTag.APS, "detectSensitivityandCarbAbsorption()", startPart); profiler.log(LTag.APS, "detectSensitivityandCarbAbsorption()", startPart);
Profiler.log(getAapsLogger(), LTag.APS, "SMB data gathering", start); profiler.log(LTag.APS, "SMB data gathering", start);
start = System.currentTimeMillis(); start = System.currentTimeMillis();
try { try {
@ -241,14 +247,14 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr
advancedFiltering.value() advancedFiltering.value()
); );
} catch (JSONException e) { } catch (JSONException e) {
FabricPrivacy.getInstance().logException(e); fabricPrivacy.logException(e);
return; return;
} }
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
DetermineBasalResultSMB determineBasalResultSMB = determineBasalAdapterSMBJS.invoke(); DetermineBasalResultSMB determineBasalResultSMB = determineBasalAdapterSMBJS.invoke();
Profiler.log(getAapsLogger(), LTag.APS, "SMB calculation", start); profiler.log(LTag.APS, "SMB calculation", start);
if (determineBasalResultSMB == null) { if (determineBasalResultSMB == null) {
getAapsLogger().error(LTag.APS, "SMB calculation returned null"); getAapsLogger().error(LTag.APS, "SMB calculation returned null");
lastDetermineBasalAdapterSMBJS = null; lastDetermineBasalAdapterSMBJS = null;

View file

@ -78,6 +78,7 @@ public class NewNSTreatmentDialog extends DaggerDialogFragment implements View.O
@Inject ActivePluginProvider activePlugin; @Inject ActivePluginProvider activePlugin;
@Inject TreatmentsPlugin treatmentsPlugin; @Inject TreatmentsPlugin treatmentsPlugin;
@Inject HardLimits hardLimits; @Inject HardLimits hardLimits;
@Inject Translator translator;
private static OptionsToShow options; private static OptionsToShow options;
private static @StringRes int event; private static @StringRes int event;
@ -623,7 +624,7 @@ public class NewNSTreatmentDialog extends DaggerDialogFragment implements View.O
if (data.has("glucoseType")) { if (data.has("glucoseType")) {
ret += resourceHelper.gs(R.string.careportal_newnstreatment_glucosetype); ret += resourceHelper.gs(R.string.careportal_newnstreatment_glucosetype);
ret += ": "; ret += ": ";
ret += Translator.translate(JsonHelper.safeGetString(data, "glucoseType", "")); ret += translator.translate(JsonHelper.safeGetString(data, "glucoseType", ""));
ret += "\n"; ret += "\n";
} }
if (data.has("carbs")) { if (data.has("carbs")) {
@ -712,7 +713,7 @@ public class NewNSTreatmentDialog extends DaggerDialogFragment implements View.O
private void confirmNSTreatmentCreation() { private void confirmNSTreatmentCreation() {
final JSONObject data = gatherData(); final JSONObject data = gatherData();
OKDialog.showConfirmation(getContext(), Translator.translate(JsonHelper.safeGetString(data, "eventType", resourceHelper.gs(R.string.overview_treatment_label))), buildConfirmText(data), () -> NSUpload.createNSTreatment(data, profileStore, profileFunction, eventTime.getTime())); OKDialog.showConfirmation(getContext(), translator.translate(JsonHelper.safeGetString(data, "eventType", resourceHelper.gs(R.string.overview_treatment_label))), buildConfirmText(data), () -> NSUpload.createNSTreatment(data, profileStore, profileFunction, eventTime.getTime()));
} }

View file

@ -4,7 +4,6 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.ResolveInfo import android.content.pm.ResolveInfo
import android.os.Bundle import android.os.Bundle
import dagger.Lazy
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Config import info.nightscout.androidaps.Config
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
@ -30,8 +29,8 @@ import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewB
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished
import info.nightscout.androidaps.receivers.ReceiverStatusStore
import info.nightscout.androidaps.services.Intents import info.nightscout.androidaps.services.Intents
import info.nightscout.androidaps.utils.BatteryLevel
import info.nightscout.androidaps.utils.DefaultValueHelper import info.nightscout.androidaps.utils.DefaultValueHelper
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
@ -52,8 +51,10 @@ class DataBroadcastPlugin @Inject constructor(
private val profileFunction: ProfileFunction, private val profileFunction: ProfileFunction,
private val defaultValueHelper: DefaultValueHelper, private val defaultValueHelper: DefaultValueHelper,
private val nsDeviceStatus: NSDeviceStatus, private val nsDeviceStatus: NSDeviceStatus,
private val lazyLoopPlugin: Lazy<LoopPlugin>, private val loopPlugin: LoopPlugin,
private val activePlugin: ActivePluginProvider private val activePlugin: ActivePluginProvider,
private var receiverStatusStore: ReceiverStatusStore
) : PluginBase(PluginDescription() ) : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL) .mainType(PluginType.GENERAL)
@ -154,16 +155,16 @@ class DataBroadcastPlugin @Inject constructor(
private fun loopStatus(bundle: Bundle) { private fun loopStatus(bundle: Bundle) {
//batteries //batteries
bundle.putInt("phoneBattery", BatteryLevel.getBatteryLevel()) bundle.putInt("phoneBattery", receiverStatusStore.batteryLevel)
bundle.putInt("rigBattery", nsDeviceStatus.uploaderStatus.replace("%", "").trim { it <= ' ' }.toInt()) bundle.putInt("rigBattery", nsDeviceStatus.uploaderStatus.replace("%", "").trim { it <= ' ' }.toInt())
if (Config.APS && lazyLoopPlugin.get().lastRun?.lastTBREnact != 0L) { //we are AndroidAPS if (Config.APS && loopPlugin.lastRun?.lastTBREnact != 0L) { //we are AndroidAPS
bundle.putLong("suggestedTimeStamp", lazyLoopPlugin.get().lastRun?.lastAPSRun ?: -1L) bundle.putLong("suggestedTimeStamp", loopPlugin.lastRun?.lastAPSRun ?: -1L)
bundle.putString("suggested", lazyLoopPlugin.get().lastRun?.request?.json().toString()) bundle.putString("suggested", loopPlugin.lastRun?.request?.json().toString())
if (lazyLoopPlugin.get().lastRun?.tbrSetByPump != null && lazyLoopPlugin.get().lastRun?.tbrSetByPump?.enacted == true) { if (loopPlugin.lastRun?.tbrSetByPump != null && loopPlugin.lastRun?.tbrSetByPump?.enacted == true) {
bundle.putLong("enactedTimeStamp", lazyLoopPlugin.get().lastRun?.lastTBREnact bundle.putLong("enactedTimeStamp", loopPlugin.lastRun?.lastTBREnact
?: -1L) ?: -1L)
bundle.putString("enacted", lazyLoopPlugin.get().lastRun?.request?.json().toString()) bundle.putString("enacted", loopPlugin.lastRun?.request?.json().toString())
} }
} else { //NSClient or remote } else { //NSClient or remote
val data = NSDeviceStatus.deviceStatusOpenAPSData val data = NSDeviceStatus.deviceStatusOpenAPSData

View file

@ -39,11 +39,9 @@ import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
import info.nightscout.androidaps.plugins.aps.loop.APSResult; import info.nightscout.androidaps.plugins.aps.loop.APSResult;
import info.nightscout.androidaps.plugins.aps.loop.DeviceStatus; import info.nightscout.androidaps.plugins.aps.loop.DeviceStatus;
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.PluginStore;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.utils.BatteryLevel; import info.nightscout.androidaps.receivers.ReceiverStatusStore;
import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.JsonHelper; import info.nightscout.androidaps.utils.JsonHelper;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SP;
@ -160,7 +158,7 @@ public class NSUpload {
} }
} }
public static void uploadDeviceStatus(LoopPlugin loopPlugin, IobCobCalculatorPlugin iobCobCalculatorPlugin, ProfileFunction profileFunction, PumpInterface pumpInterface) { public static void uploadDeviceStatus(LoopPlugin loopPlugin, IobCobCalculatorPlugin iobCobCalculatorPlugin, ProfileFunction profileFunction, PumpInterface pumpInterface, ReceiverStatusStore receiverStatusStore) {
Profile profile = profileFunction.getProfile(); Profile profile = profileFunction.getProfile();
String profileName = profileFunction.getProfileName(); String profileName = profileFunction.getProfileName();
@ -216,7 +214,7 @@ public class NSUpload {
deviceStatus.pump = pumpstatus; deviceStatus.pump = pumpstatus;
} }
int batteryLevel = BatteryLevel.getBatteryLevel(); int batteryLevel = receiverStatusStore.getBatteryLevel();
deviceStatus.uploaderBattery = batteryLevel; deviceStatus.uploaderBattery = batteryLevel;
deviceStatus.created_at = DateUtil.toISOString(new Date()); deviceStatus.created_at = DateUtil.toISOString(new Date());

View file

@ -50,7 +50,7 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.treatments.Treatment; import info.nightscout.androidaps.plugins.treatments.Treatment;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.utils.BatteryLevel; import info.nightscout.androidaps.receivers.ReceiverStatusStore;
import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.DefaultValueHelper; import info.nightscout.androidaps.utils.DefaultValueHelper;
import info.nightscout.androidaps.utils.ToastUtils; import info.nightscout.androidaps.utils.ToastUtils;
@ -71,6 +71,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
@Inject public IobCobCalculatorPlugin iobCobCalculatorPlugin; @Inject public IobCobCalculatorPlugin iobCobCalculatorPlugin;
@Inject public TreatmentsPlugin treatmentsPlugin; @Inject public TreatmentsPlugin treatmentsPlugin;
@Inject public ActionStringHandler actionStringHandler; @Inject public ActionStringHandler actionStringHandler;
@Inject ReceiverStatusStore receiverStatusStore;
public static final String ACTION_RESEND = WatchUpdaterService.class.getName().concat(".Resend"); public static final String ACTION_RESEND = WatchUpdaterService.class.getName().concat(".Resend");
public static final String ACTION_OPEN_SETTINGS = WatchUpdaterService.class.getName().concat(".OpenSettings"); public static final String ACTION_OPEN_SETTINGS = WatchUpdaterService.class.getName().concat(".OpenSettings");
@ -705,7 +706,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
//batteries //batteries
int phoneBattery = BatteryLevel.getBatteryLevel(); int phoneBattery = receiverStatusStore.getBatteryLevel();
String rigBattery = nsDeviceStatus.getUploaderStatus().trim(); String rigBattery = nsDeviceStatus.getUploaderStatus().trim();

View file

@ -23,7 +23,6 @@ import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.events.Event; import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.interfaces.ActivePluginProvider; import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults; import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper; import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
@ -66,6 +65,8 @@ public class IobCobOref1Thread extends Thread {
@Inject SensitivityAAPSPlugin sensitivityAAPSPlugin; @Inject SensitivityAAPSPlugin sensitivityAAPSPlugin;
@Inject SensitivityWeightedAveragePlugin sensitivityWeightedAveragePlugin; @Inject SensitivityWeightedAveragePlugin sensitivityWeightedAveragePlugin;
@Inject BuildHelper buildHelper; @Inject BuildHelper buildHelper;
@Inject Profiler profiler;
@Inject FabricPrivacy fabricPrivacy;
private final HasAndroidInjector injector; private final HasAndroidInjector injector;
private boolean bgDataReload; private boolean bgDataReload;
@ -222,7 +223,7 @@ public class IobCobOref1Thread extends Thread {
} }
} catch (Exception e) { } catch (Exception e) {
aapsLogger.error("Unhandled exception", e); aapsLogger.error("Unhandled exception", e);
FabricPrivacy.getInstance().logException(e); fabricPrivacy.logException(e);
aapsLogger.debug(autosensDataTable.toString()); aapsLogger.debug(autosensDataTable.toString());
aapsLogger.debug(bucketed_data.toString()); aapsLogger.debug(bucketed_data.toString());
aapsLogger.debug(iobCobCalculatorPlugin.getBgReadings().toString()); aapsLogger.debug(iobCobCalculatorPlugin.getBgReadings().toString());
@ -391,7 +392,7 @@ public class IobCobOref1Thread extends Thread {
rxBus.send(new EventIobCalculationProgress("")); rxBus.send(new EventIobCalculationProgress(""));
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread ended: " + from); aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread ended: " + from);
aapsLogger.debug(LTag.AUTOSENS, "Midnights: " + MidnightTime.log()); aapsLogger.debug(LTag.AUTOSENS, "Midnights: " + MidnightTime.log());
Profiler.log(aapsLogger, LTag.AUTOSENS, "IobCobOref1Thread", start); profiler.log(LTag.AUTOSENS, "IobCobOref1Thread", start);
} }
} }
} }

View file

@ -62,6 +62,8 @@ public class IobCobThread extends Thread {
@Inject SensitivityAAPSPlugin sensitivityAAPSPlugin; @Inject SensitivityAAPSPlugin sensitivityAAPSPlugin;
@Inject SensitivityWeightedAveragePlugin sensitivityWeightedAveragePlugin; @Inject SensitivityWeightedAveragePlugin sensitivityWeightedAveragePlugin;
@Inject BuildHelper buildHelper; @Inject BuildHelper buildHelper;
@Inject Profiler profiler;
@Inject FabricPrivacy fabricPrivacy;
private final HasAndroidInjector injector; private final HasAndroidInjector injector;
private boolean bgDataReload; private boolean bgDataReload;
@ -218,7 +220,7 @@ public class IobCobThread extends Thread {
} }
} catch (Exception e) { } catch (Exception e) {
aapsLogger.error("Unhandled exception", e); aapsLogger.error("Unhandled exception", e);
FabricPrivacy.getInstance().logException(e); fabricPrivacy.logException(e);
aapsLogger.debug(autosensDataTable.toString()); aapsLogger.debug(autosensDataTable.toString());
aapsLogger.debug(bucketed_data.toString()); aapsLogger.debug(bucketed_data.toString());
aapsLogger.debug(iobCobCalculatorPlugin.getBgReadings().toString()); aapsLogger.debug(iobCobCalculatorPlugin.getBgReadings().toString());
@ -314,7 +316,7 @@ public class IobCobThread extends Thread {
rxBus.send(new EventIobCalculationProgress("")); rxBus.send(new EventIobCalculationProgress(""));
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread ended: " + from); aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread ended: " + from);
aapsLogger.debug(LTag.AUTOSENS, "Midnights: " + MidnightTime.log()); aapsLogger.debug(LTag.AUTOSENS, "Midnights: " + MidnightTime.log());
Profiler.log(aapsLogger, LTag.AUTOSENS, "IobCobThread", start); profiler.log(LTag.AUTOSENS, "IobCobThread", start);
} }
} }

View file

@ -69,6 +69,7 @@ import info.nightscout.androidaps.plugins.treatments.Treatment;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.InstanceId; import info.nightscout.androidaps.utils.InstanceId;
import info.nightscout.androidaps.utils.TimeChangeType;
import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP; import info.nightscout.androidaps.utils.sharedPreferences.SP;
@ -1404,9 +1405,8 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
} }
@Override @Override
public void timeDateOrTimeZoneChanged() { public void timezoneOrDSTChanged(TimeChangeType changeType) {
} }
} }

View file

@ -6,6 +6,7 @@ import android.content.ServiceConnection;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import org.jetbrains.annotations.NotNull;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -20,6 +21,7 @@ import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventCustomActionsChanged;
import info.nightscout.androidaps.interfaces.ActivePluginProvider; import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.interfaces.CommandQueueProvider; import info.nightscout.androidaps.interfaces.CommandQueueProvider;
import info.nightscout.androidaps.interfaces.ConstraintsInterface; import info.nightscout.androidaps.interfaces.ConstraintsInterface;
@ -30,16 +32,19 @@ import info.nightscout.androidaps.interfaces.PumpPluginBase;
import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper; import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.common.ManufacturerType;
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress; import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress;
import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus; import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState; import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkService;
import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryData; import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryData;
import info.nightscout.androidaps.plugins.treatments.Treatment; import info.nightscout.androidaps.plugins.treatments.Treatment;
import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
@ -57,6 +62,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
protected ActivePluginProvider activePlugin; protected ActivePluginProvider activePlugin;
protected Context context; protected Context context;
protected FabricPrivacy fabricPrivacy; protected FabricPrivacy fabricPrivacy;
protected SP sp;
/* /*
protected static final PumpEnactResult OPERATION_NOT_SUPPORTED = new PumpEnactResult().success(false) protected static final PumpEnactResult OPERATION_NOT_SUPPORTED = new PumpEnactResult().success(false)
@ -65,12 +71,12 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
.enacted(false).comment(MainApp.gs(R.string.pump_operation_not_yet_supported_by_pump)); .enacted(false).comment(MainApp.gs(R.string.pump_operation_not_yet_supported_by_pump));
*/ */
protected PumpDescription pumpDescription = new PumpDescription(); protected PumpDescription pumpDescription = new PumpDescription();
protected PumpStatus pumpStatus;
protected ServiceConnection serviceConnection = null; protected ServiceConnection serviceConnection = null;
protected boolean serviceRunning = false; protected boolean serviceRunning = false;
// protected boolean isInitialized = false; // protected boolean isInitialized = false;
protected PumpDriverState pumpState = PumpDriverState.NotInitialized; protected PumpDriverState pumpState = PumpDriverState.NotInitialized;
protected boolean displayConnectionMessages = false; protected boolean displayConnectionMessages = false;
protected PumpType pumpType;
protected PumpPluginAbstract( protected PumpPluginAbstract(
@ -82,6 +88,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
CommandQueueProvider commandQueue, CommandQueueProvider commandQueue,
RxBusWrapper rxBus, RxBusWrapper rxBus,
ActivePluginProvider activePlugin, ActivePluginProvider activePlugin,
SP sp,
Context context, Context context,
FabricPrivacy fabricPrivacy FabricPrivacy fabricPrivacy
) { ) {
@ -92,14 +99,21 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
this.activePlugin = activePlugin; this.activePlugin = activePlugin;
this.context = context; this.context = context;
this.fabricPrivacy = fabricPrivacy; this.fabricPrivacy = fabricPrivacy;
this.sp = sp;
pumpDescription.setPumpDescription(pumpType); pumpDescription.setPumpDescription(pumpType);
this.pumpType = pumpType;
} }
public abstract void initPumpStatusData(); public abstract void initPumpStatusData();
public abstract void resetRileyLinkConfiguration();
public abstract void doTuneUpDevice();
public abstract RileyLinkService getRileyLinkService();
@Override @Override
protected void onStart() { protected void onStart() {
@ -115,7 +129,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
disposable.add(rxBus disposable.add(rxBus
.toObservable(EventAppExit.class) .toObservable(EventAppExit.class)
.observeOn(Schedulers.io()) .observeOn(Schedulers.io())
.subscribe(event -> context.unbindService(serviceConnection), exception -> fabricPrivacy.logException(exception)) .subscribe(event -> context.unbindService(serviceConnection), fabricPrivacy::logException)
); );
onStartCustomActions(); onStartCustomActions();
} }
@ -144,9 +158,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
*/ */
public abstract Class getServiceClass(); public abstract Class getServiceClass();
public PumpStatus getPumpStatusData() { public abstract PumpStatus getPumpStatusData();
return pumpStatus;
}
public boolean isInitialized() { public boolean isInitialized() {
@ -210,12 +222,6 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
aapsLogger.debug(LTag.PUMP, "finishHandshaking [PumpPluginAbstract] - default (empty) implementation."); aapsLogger.debug(LTag.PUMP, "finishHandshaking [PumpPluginAbstract] - default (empty) implementation.");
} }
public void getPumpStatus() {
aapsLogger.debug(LTag.PUMP, "getPumpStatus [PumpPluginAbstract] - Not implemented.");
}
// Upload to pump new basal profile // Upload to pump new basal profile
@NonNull public PumpEnactResult setNewBasalProfile(Profile profile) { @NonNull public PumpEnactResult setNewBasalProfile(Profile profile) {
aapsLogger.debug(LTag.PUMP, "setNewBasalProfile [PumpPluginAbstract] - Not implemented."); aapsLogger.debug(LTag.PUMP, "setNewBasalProfile [PumpPluginAbstract] - Not implemented.");
@ -231,7 +237,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
public long lastDataTime() { public long lastDataTime() {
aapsLogger.debug(LTag.PUMP, "lastDataTime [PumpPluginAbstract]."); aapsLogger.debug(LTag.PUMP, "lastDataTime [PumpPluginAbstract].");
return pumpStatus.lastConnection; return getPumpStatusData().lastConnection;
} }
@ -320,7 +326,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
@NonNull @Override @NonNull @Override
public JSONObject getJSONStatus(Profile profile, String profileName) { public JSONObject getJSONStatus(Profile profile, String profileName) {
if ((pumpStatus.lastConnection + 5 * 60 * 1000L) < System.currentTimeMillis()) { if ((getPumpStatusData().lastConnection + 5 * 60 * 1000L) < System.currentTimeMillis()) {
return new JSONObject(); return new JSONObject();
} }
@ -329,8 +335,8 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
JSONObject status = new JSONObject(); JSONObject status = new JSONObject();
JSONObject extended = new JSONObject(); JSONObject extended = new JSONObject();
try { try {
battery.put("percent", pumpStatus.batteryRemaining); battery.put("percent", getPumpStatusData().batteryRemaining);
status.put("status", pumpStatus.pumpStatusType != null ? pumpStatus.pumpStatusType.getStatus() : "normal"); status.put("status", getPumpStatusData().pumpStatusType != null ? getPumpStatusData().pumpStatusType.getStatus() : "normal");
extended.put("Version", BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION); extended.put("Version", BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION);
try { try {
extended.put("ActiveProfile", profileName); extended.put("ActiveProfile", profileName);
@ -357,7 +363,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
pump.put("battery", battery); pump.put("battery", battery);
pump.put("status", status); pump.put("status", status);
pump.put("extended", extended); pump.put("extended", extended);
pump.put("reservoir", pumpStatus.reservoirRemainingUnits); pump.put("reservoir", getPumpStatusData().reservoirRemainingUnits);
pump.put("clock", DateUtil.toISOString(new Date())); pump.put("clock", DateUtil.toISOString(new Date()));
} catch (JSONException e) { } catch (JSONException e) {
aapsLogger.error("Unhandled exception", e); aapsLogger.error("Unhandled exception", e);
@ -370,14 +376,14 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
@NonNull @Override @NonNull @Override
public String shortStatus(boolean veryShort) { public String shortStatus(boolean veryShort) {
String ret = ""; String ret = "";
if (pumpStatus.lastConnection != 0) { if (getPumpStatusData().lastConnection != 0) {
long agoMsec = System.currentTimeMillis() - pumpStatus.lastConnection; long agoMsec = System.currentTimeMillis() - getPumpStatusData().lastConnection;
int agoMin = (int) (agoMsec / 60d / 1000d); int agoMin = (int) (agoMsec / 60d / 1000d);
ret += "LastConn: " + agoMin + " min ago\n"; ret += "LastConn: " + agoMin + " min ago\n";
} }
if (pumpStatus.lastBolusTime != null && pumpStatus.lastBolusTime.getTime() != 0) { if (getPumpStatusData().lastBolusTime != null && getPumpStatusData().lastBolusTime.getTime() != 0) {
ret += "LastBolus: " + DecimalFormatter.to2Decimal(pumpStatus.lastBolusAmount) + "U @" + // ret += "LastBolus: " + DecimalFormatter.to2Decimal(getPumpStatusData().lastBolusAmount) + "U @" + //
android.text.format.DateFormat.format("HH:mm", pumpStatus.lastBolusTime) + "\n"; android.text.format.DateFormat.format("HH:mm", getPumpStatusData().lastBolusTime) + "\n";
} }
TemporaryBasal activeTemp = activePlugin.getActiveTreatments().getRealTempBasalFromHistory(System.currentTimeMillis()); TemporaryBasal activeTemp = activePlugin.getActiveTreatments().getRealTempBasalFromHistory(System.currentTimeMillis());
if (activeTemp != null) { if (activeTemp != null) {
@ -392,9 +398,9 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
// ret += "TDD: " + DecimalFormatter.to0Decimal(pumpStatus.dailyTotalUnits) + " / " // ret += "TDD: " + DecimalFormatter.to0Decimal(pumpStatus.dailyTotalUnits) + " / "
// + pumpStatus.maxDailyTotalUnits + " U\n"; // + pumpStatus.maxDailyTotalUnits + " U\n";
// } // }
ret += "IOB: " + pumpStatus.iob + "U\n"; ret += "IOB: " + getPumpStatusData().iob + "U\n";
ret += "Reserv: " + DecimalFormatter.to0Decimal(pumpStatus.reservoirRemainingUnits) + "U\n"; ret += "Reserv: " + DecimalFormatter.to0Decimal(getPumpStatusData().reservoirRemainingUnits) + "U\n";
ret += "Batt: " + pumpStatus.batteryRemaining + "\n"; ret += "Batt: " + getPumpStatusData().batteryRemaining + "\n";
return ret; return ret;
} }
@ -435,6 +441,37 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
} }
protected void refreshCustomActionsList() {
rxBus.send(new EventCustomActionsChanged());
}
public ManufacturerType manufacturer() {
return pumpType.getManufacturer();
}
@NotNull
public PumpType model() {
return pumpType;
}
public PumpType getPumpType() {
return pumpType;
}
public void setPumpType(PumpType pumpType) {
this.pumpType = pumpType;
}
public boolean canHandleDST() {
return false;
}
protected abstract PumpEnactResult deliverBolus(DetailedBolusInfo detailedBolusInfo); protected abstract PumpEnactResult deliverBolus(DetailedBolusInfo detailedBolusInfo);
protected abstract void triggerUIChange(); protected abstract void triggerUIChange();

View file

@ -2,12 +2,10 @@ package info.nightscout.androidaps.plugins.pump.common.data;
import java.util.Date; import java.util.Date;
import org.joda.time.LocalDateTime;
import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpStatusType; import info.nightscout.androidaps.plugins.pump.common.defs.PumpStatusType;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.utils.DateUtil;
/** /**
* Created by andy on 4/28/18. * Created by andy on 4/28/18.
@ -16,10 +14,12 @@ import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
public abstract class PumpStatus { public abstract class PumpStatus {
// connection // connection
public LocalDateTime lastDataTime; public long lastDataTime;
public long lastConnection = 0L; public long lastConnection = 0L;
public long previousConnection = 0L; // here should be stored last connection of previous session (so needs to be public long previousConnection = 0L; // here should be stored last connection of previous session (so needs to be
// read before lastConnection is modified for first time). // read before lastConnection is modified for first time).
public long lastErrorConnection = 0L;
// last bolus // last bolus
public Date lastBolusTime; public Date lastBolusTime;
@ -27,10 +27,10 @@ public abstract class PumpStatus {
// other pump settings // other pump settings
public String activeProfileName = "0"; public String activeProfileName = "0";
public double reservoirRemainingUnits = 0d; public double reservoirRemainingUnits = 0.0d;
public int reservoirFullUnits = 0; public int reservoirFullUnits = 0;
public int batteryRemaining = 0; // percent, so 0-100 public int batteryRemaining = 0; // percent, so 0-100
public Double batteryVoltage = null; public Double batteryVoltage = null;
// iob // iob
@ -40,7 +40,6 @@ public abstract class PumpStatus {
public Double dailyTotalUnits; public Double dailyTotalUnits;
public String maxDailyTotalUnits; public String maxDailyTotalUnits;
public boolean validBasalRateProfileSelectedOnPump = true; public boolean validBasalRateProfileSelectedOnPump = true;
public PumpType pumpType = PumpType.GenericAAPS;
public ProfileStore profileStore; public ProfileStore profileStore;
public String units; // Constants.MGDL or Constants.MMOL public String units; // Constants.MGDL or Constants.MMOL
public PumpStatusType pumpStatusType = PumpStatusType.Running; public PumpStatusType pumpStatusType = PumpStatusType.Running;
@ -50,41 +49,25 @@ public abstract class PumpStatus {
public int tempBasalRatio = 0; public int tempBasalRatio = 0;
public int tempBasalRemainMin = 0; public int tempBasalRemainMin = 0;
public Date tempBasalStart; public Date tempBasalStart;
protected PumpDescription pumpDescription; //protected PumpDescription pumpDescription;
public PumpStatus(PumpDescription pumpDescription) { public PumpStatus() {
this.pumpDescription = pumpDescription; // public PumpStatus(PumpDescription pumpDescription) {
// this.pumpDescription = pumpDescription;
this.initSettings(); // this.initSettings();
} }
public abstract void initSettings();
public void setLastCommunicationToNow() { public void setLastCommunicationToNow() {
this.lastDataTime = LocalDateTime.now(); this.lastDataTime = DateUtil.now();
this.lastConnection = System.currentTimeMillis(); this.lastConnection = System.currentTimeMillis();
} }
public void setLastFailedCommunicationToNow() {
this.lastErrorConnection = System.currentTimeMillis();
}
public abstract String getErrorInfo(); public abstract String getErrorInfo();
public abstract void refreshConfiguration();
public PumpType getPumpType() {
return pumpType;
}
public void setPumpType(PumpType pumpType) {
this.pumpType = pumpType;
}
// public Date last_bolus_time;
// public double last_bolus_amount = 0;
} }

View file

@ -0,0 +1,77 @@
package info.nightscout.androidaps.plugins.pump.common.data;
import com.google.gson.annotations.Expose;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.logging.L;
public class TempBasalPair {
@Expose
protected double insulinRate = 0.0d;
@Expose
protected int durationMinutes = 0;
@Expose
protected boolean isPercent = false;
private Long start;
private Long end;
public TempBasalPair() {
}
public TempBasalPair(double insulinRate, boolean isPercent, int durationMinutes) {
this.insulinRate = insulinRate;
this.isPercent = isPercent;
this.durationMinutes = durationMinutes;
}
public double getInsulinRate() {
return insulinRate;
}
public void setInsulinRate(double insulinRate) {
this.insulinRate = insulinRate;
}
public int getDurationMinutes() {
return durationMinutes;
}
public void setDurationMinutes(int durationMinutes) {
this.durationMinutes = durationMinutes;
}
public boolean isPercent() {
return isPercent;
}
public void setIsPercent(boolean yesIsPercent) {
this.isPercent = yesIsPercent;
}
public void setStartTime(Long startTime) {
this.start = startTime;
}
public void setEndTime(Long endTime) {
this.end = endTime;
}
@Override
public String toString() {
return "TempBasalPair [" + "Rate=" + insulinRate + ", DurationMinutes=" + durationMinutes + ", IsPercent="
+ isPercent + "]";
}
}

View file

@ -23,6 +23,7 @@ public enum PumpCapability {
DanaWithHistoryCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, StoreCarbInfo, TDD, ManualTDDLoad), // DanaWithHistoryCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, StoreCarbInfo, TDD, ManualTDDLoad), //
InsightCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill,TDD,BasalRate30min), // InsightCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill,TDD,BasalRate30min), //
MedtronicCapabilities(Bolus, TempBasal, BasalProfileSet, Refill, TDD), // MedtronicCapabilities(Bolus, TempBasal, BasalProfileSet, Refill, TDD), //
OmnipodCapabilities(Bolus, TempBasal, BasalProfileSet, BasalRate30min), //
// BasalRates (separately grouped) // BasalRates (separately grouped)
BasalRate_Duration15minAllowed, // BasalRate_Duration15minAllowed, //
@ -69,4 +70,4 @@ public enum PumpCapability {
} }

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump; package info.nightscout.androidaps.plugins.pump.common.defs;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -9,7 +9,7 @@ import info.nightscout.androidaps.R;
/** /**
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes * This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
* management and modified/extended for AAPS. * management and modified/extended for AAPS.
* * <p>
* Author: Andy {andy.rozman@gmail.com} * Author: Andy {andy.rozman@gmail.com}
*/ */

View file

@ -57,7 +57,14 @@ public enum PumpType {
new DoseSettings(0.01d, 15, 24 * 60, 0.05d), // new DoseSettings(0.01d, 15, 24 * 60, 0.05d), //
PumpTempBasalType.Percent, PumpTempBasalType.Percent,
new DoseSettings(10, 15, 24 * 60, 0d, 250d), PumpCapability.BasalRate_Duration15and30minAllowed, // new DoseSettings(10, 15, 24 * 60, 0d, 250d), PumpCapability.BasalRate_Duration15and30minAllowed, //
0.02d, 0.01d, DoseStepSize.InsightBolus, PumpCapability.InsightCapabilities), // 0.02d, null, 0.01d, DoseStepSize.InsightBolus, PumpCapability.InsightCapabilities, false, false), //
AccuChekSolo("Accu-Chek Solo", ManufacturerType.Roche, "Solo", 0.01d, null, //
new DoseSettings(0.01d, 15, 24 * 60, 0.05d), //
PumpTempBasalType.Percent,
new DoseSettings(10, 15, 24 * 60, 0d, 250d), PumpCapability.BasalRate_Duration15and30minAllowed, //
0.02d, null, 0.01d, DoseStepSize.InsightBolus, PumpCapability.InsightCapabilities, false, false), //
// Animas // Animas
AnimasVibe("Animas Vibe", ManufacturerType.Animas, "Vibe", 0.05d, null, // AnimasBolus? AnimasVibe("Animas Vibe", ManufacturerType.Animas, "Vibe", 0.05d, null, // AnimasBolus?
@ -91,11 +98,17 @@ public enum PumpType {
// Insulet // Insulet
Insulet_Omnipod("Insulet Omnipod", ManufacturerType.Insulet, "Omnipod", 0.05d, null, // Insulet_Omnipod("Insulet Omnipod", ManufacturerType.Insulet, "Omnipod (Eros)", 0.05d, null, //
new DoseSettings(0.05d, 30, 8 * 60, 0.05d), // new DoseSettings(0.05d, 30, 8 * 60, 0.05d), //
PumpTempBasalType.Absolute, // PumpTempBasalType.Absolute, //
new DoseSettings(0.05d, 30, 12 * 60, 0d, 30.0d), PumpCapability.BasalRate_Duration30minAllowed, // cannot exceed max basal rate 30u/hr new DoseSettings(0.05d, 30, 12 * 60, 0d, 30.0d), PumpCapability.BasalRate_Duration30minAllowed, //
0.05d, 0.05d, null, PumpCapability.VirtualPumpCapabilities), 0.05d, null, 0.05d, null, PumpCapability.OmnipodCapabilities, true, true),
Insulet_Omnipod_Dash("Insulet Omnipod Dash", ManufacturerType.Insulet, "Omnipod 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, true, true), // TODO just copied OmniPod for now
// Medtronic // Medtronic
Medtronic_512_712("Medtronic 512/712", ManufacturerType.Medtronic, "512/712", 0.1d, null, // Medtronic_512_712("Medtronic 512/712", ManufacturerType.Medtronic, "512/712", 0.1d, null, //
@ -150,6 +163,8 @@ public enum PumpType {
private double baseBasalStep; // private double baseBasalStep; //
private DoseStepSize baseBasalSpecialSteps; // private DoseStepSize baseBasalSpecialSteps; //
private PumpCapability pumpCapability; private PumpCapability pumpCapability;
private boolean hasFixedUnreachableAlert;
private boolean hasCustomUnreachableAlertCheck;
private PumpType parent; private PumpType parent;
private static Map<String, PumpType> mapByDescription; private static Map<String, PumpType> mapByDescription;
@ -184,17 +199,58 @@ public enum PumpType {
parent.model = model; parent.model = model;
} }
PumpType(String description, ManufacturerType manufacturer, String model, double bolusSize, DoseStepSize specialBolusSize, // PumpType(String description,
ManufacturerType manufacturer,
String model,
double bolusSize,
DoseStepSize specialBolusSize, //
DoseSettings extendedBolusSettings, // DoseSettings extendedBolusSettings, //
PumpTempBasalType pumpTempBasalType, DoseSettings tbrSettings, PumpCapability specialBasalDurations, // PumpTempBasalType pumpTempBasalType,
double baseBasalMinValue, double baseBasalStep, DoseStepSize baseBasalSpecialSteps, PumpCapability pumpCapability) { DoseSettings tbrSettings,
PumpCapability specialBasalDurations, //
double baseBasalMinValue,
double baseBasalStep,
DoseStepSize baseBasalSpecialSteps,
PumpCapability pumpCapability) {
this(description, manufacturer, model, bolusSize, specialBolusSize, extendedBolusSettings, pumpTempBasalType, tbrSettings, specialBasalDurations, baseBasalMinValue, null, baseBasalStep, baseBasalSpecialSteps, pumpCapability); this(description, manufacturer, model, bolusSize, specialBolusSize, extendedBolusSettings, pumpTempBasalType, tbrSettings, specialBasalDurations, baseBasalMinValue, null, baseBasalStep, baseBasalSpecialSteps, pumpCapability);
} }
PumpType(String description, ManufacturerType manufacturer, String model, double bolusSize, DoseStepSize specialBolusSize, // PumpType(String description,
ManufacturerType manufacturer,
String model,
double bolusSize,
DoseStepSize specialBolusSize, //
DoseSettings extendedBolusSettings, // DoseSettings extendedBolusSettings, //
PumpTempBasalType pumpTempBasalType, DoseSettings tbrSettings, PumpCapability specialBasalDurations, // PumpTempBasalType pumpTempBasalType,
double baseBasalMinValue, Double baseBasalMaxValue, double baseBasalStep, DoseStepSize baseBasalSpecialSteps, PumpCapability pumpCapability) { DoseSettings tbrSettings,
PumpCapability specialBasalDurations, //
double baseBasalMinValue,
Double baseBasalMaxValue,
double baseBasalStep,
DoseStepSize baseBasalSpecialSteps,
PumpCapability pumpCapability) {
this(description, manufacturer, model, bolusSize, specialBolusSize, extendedBolusSettings, pumpTempBasalType,
tbrSettings, specialBasalDurations, baseBasalMinValue, null, baseBasalStep,
baseBasalSpecialSteps, pumpCapability, false, false);
}
PumpType(String description,
ManufacturerType manufacturer,
String model,
double bolusSize,
DoseStepSize specialBolusSize, //
DoseSettings extendedBolusSettings, //
PumpTempBasalType pumpTempBasalType,
DoseSettings tbrSettings,
PumpCapability specialBasalDurations, //
double baseBasalMinValue,
Double baseBasalMaxValue,
double baseBasalStep,
DoseStepSize baseBasalSpecialSteps, //
PumpCapability pumpCapability,
boolean hasFixedUnreachableAlert,
boolean hasCustomUnreachableAlertCheck) {
this.description = description; this.description = description;
this.manufacturer = manufacturer; this.manufacturer = manufacturer;
this.model = model; this.model = model;
@ -209,9 +265,19 @@ public enum PumpType {
this.baseBasalStep = baseBasalStep; this.baseBasalStep = baseBasalStep;
this.baseBasalSpecialSteps = baseBasalSpecialSteps; this.baseBasalSpecialSteps = baseBasalSpecialSteps;
this.pumpCapability = pumpCapability; this.pumpCapability = pumpCapability;
this.hasFixedUnreachableAlert = hasFixedUnreachableAlert;
this.hasCustomUnreachableAlertCheck = hasCustomUnreachableAlertCheck;
} }
public boolean getHasFixedUnreachableAlert() {
return hasFixedUnreachableAlert;
}
public boolean getHasCustomUnreachableAlertCheck() {
return hasFixedUnreachableAlert;
}
public String getDescription() { public String getDescription() {
return description; return description;
} }

View file

@ -44,9 +44,8 @@ import info.nightscout.androidaps.plugins.pump.common.ble.BlePreCheck;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes;
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus; import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin;
import info.nightscout.androidaps.plugins.pump.medtronic.events.EventMedtronicPumpConfigurationChanged; import info.nightscout.androidaps.plugins.pump.medtronic.events.EventMedtronicPumpConfigurationChanged;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP; import info.nightscout.androidaps.utils.sharedPreferences.SP;
@ -58,6 +57,12 @@ public class RileyLinkBLEScanActivity extends NoSplashAppCompatActivity {
@Inject RxBusWrapper rxBus; @Inject RxBusWrapper rxBus;
@Inject ResourceHelper resourceHelper; @Inject ResourceHelper resourceHelper;
@Inject BlePreCheck blePrecheck; @Inject BlePreCheck blePrecheck;
@Inject RileyLinkUtil rileyLinkUtil;
// TODO change this. Currently verifyConfiguration uses MDT data not only RL
@Inject MedtronicPumpPlugin medtronicPumpPlugin;
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 30241; // arbitrary.
private static final int REQUEST_ENABLE_BT = 30242; // arbitrary
private static String TAG = "RileyLinkBLEScanActivity"; private static String TAG = "RileyLinkBLEScanActivity";
@ -103,10 +108,7 @@ public class RileyLinkBLEScanActivity extends NoSplashAppCompatActivity {
sp.putString(RileyLinkConst.Prefs.RileyLinkAddress, bleAddress); sp.putString(RileyLinkConst.Prefs.RileyLinkAddress, bleAddress);
RileyLinkUtil.getRileyLinkSelectPreference().setSummary(bleAddress); medtronicPumpPlugin.getRileyLinkService().verifyConfiguration(); // force reloading of address
MedtronicPumpStatus pumpStatus = MedtronicUtil.getPumpStatus();
pumpStatus.verifyConfiguration(); // force reloading of address
rxBus.send(new EventMedtronicPumpConfigurationChanged()); rxBus.send(new EventMedtronicPumpConfigurationChanged());
@ -161,7 +163,7 @@ public class RileyLinkBLEScanActivity extends NoSplashAppCompatActivity {
} }
// disable currently selected RL, so that we can discover it // disable currently selected RL, so that we can discover it
RileyLinkUtil.sendBroadcastMessage(RileyLinkConst.Intents.RileyLinkDisconnect); rileyLinkUtil.sendBroadcastMessage(RileyLinkConst.Intents.RileyLinkDisconnect, this);
} }

View file

@ -1,12 +1,10 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink; package info.nightscout.androidaps.plugins.pump.common.hw.rileylink;
import org.slf4j.Logger; import javax.inject.Inject;
import org.slf4j.LoggerFactory;
import android.content.Context; import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus; import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RFSpy; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RFSpy;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkCommunicationException; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkCommunicationException;
@ -23,8 +21,8 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.WakeAndTuneTask; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.WakeAndTuneTask;
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState; import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil; import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.sharedPreferences.SP;
/** /**
* This is abstract class for RileyLink Communication, this one needs to be extended by specific "Pump" class. * This is abstract class for RileyLink Communication, this one needs to be extended by specific "Pump" class.
@ -33,69 +31,85 @@ import info.nightscout.androidaps.utils.SP;
*/ */
public abstract class RileyLinkCommunicationManager { public abstract class RileyLinkCommunicationManager {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPCOMM); @Inject protected AAPSLogger aapsLogger;
@Inject protected SP sp;
private static final int SCAN_TIMEOUT = 1500; @Inject MedtronicPumpStatus medtronicPumpStatus;
private static final int ALLOWED_PUMP_UNREACHABLE = 10 * 60 * 1000; // 10 minutes @Inject RileyLinkServiceData rileyLinkServiceData;
@Inject ServiceTaskExecutor serviceTaskExecutor;
private final int SCAN_TIMEOUT = 1500;
private final int ALLOWED_PUMP_UNREACHABLE = 10 * 60 * 1000; // 10 minutes
protected final HasAndroidInjector injector;
protected final RFSpy rfspy; protected final RFSpy rfspy;
protected final Context context;
protected int receiverDeviceAwakeForMinutes = 1; // override this in constructor of specific implementation protected int receiverDeviceAwakeForMinutes = 1; // override this in constructor of specific implementation
protected String receiverDeviceID; // String representation of receiver device (ex. Pump (xxxxxx) or Pod (yyyyyy)) protected String receiverDeviceID; // String representation of receiver device (ex. Pump (xxxxxx) or Pod (yyyyyy))
protected long lastGoodReceiverCommunicationTime = 0; protected long lastGoodReceiverCommunicationTime = 0;
protected PumpStatus pumpStatus; // protected PumpStatus pumpStatus;
protected RileyLinkServiceData rileyLinkServiceData;
private long nextWakeUpRequired = 0L; private long nextWakeUpRequired = 0L;
// internal flag
private boolean showPumpMessages = true;
private int timeoutCount = 0; private int timeoutCount = 0;
public RileyLinkCommunicationManager(Context context, RFSpy rfspy) { public RileyLinkCommunicationManager(HasAndroidInjector injector, RFSpy rfspy) {
this.context = context; this.injector = injector;
injector.androidInjector().inject(this);
this.rfspy = rfspy; this.rfspy = rfspy;
this.rileyLinkServiceData = RileyLinkUtil.getRileyLinkServiceData();
RileyLinkUtil.setRileyLinkCommunicationManager(this);
configurePumpSpecificSettings();
} }
protected abstract void configurePumpSpecificSettings();
// All pump communications go through this function. // All pump communications go through this function.
protected <E extends RLMessage> E sendAndListen(RLMessage msg, int timeout_ms, Class<E> clazz) protected <E extends RLMessage> E sendAndListen(RLMessage msg, int timeout_ms, Class<E> clazz)
throws RileyLinkCommunicationException { throws RileyLinkCommunicationException {
return sendAndListen(msg, timeout_ms, null, clazz);
}
private <E extends RLMessage> E sendAndListen(RLMessage msg, int timeout_ms, Integer extendPreamble_ms, Class<E> clazz)
throws RileyLinkCommunicationException {
return sendAndListen(msg, timeout_ms, 0, extendPreamble_ms, clazz);
}
// For backward compatibility
private <E extends RLMessage> E sendAndListen(RLMessage msg, int timeout_ms, int repeatCount, Integer extendPreamble_ms, Class<E> clazz)
throws RileyLinkCommunicationException {
return sendAndListen(msg, timeout_ms, repeatCount, 0, extendPreamble_ms, clazz);
}
private <E extends RLMessage> E sendAndListen(RLMessage msg, int timeout_ms, int repeatCount, int retryCount, Integer extendPreamble_ms, Class<E> clazz)
throws RileyLinkCommunicationException {
// internal flag
boolean showPumpMessages = true;
if (showPumpMessages) { if (showPumpMessages) {
if (isLogEnabled()) aapsLogger.info(LTag.PUMPCOMM, "Sent:" + ByteUtil.shortHexString(msg.getTxData()));
LOG.info("Sent:" + ByteUtil.shortHexString(msg.getTxData()));
} }
RFSpyResponse rfSpyResponse = rfspy.transmitThenReceive(new RadioPacket(msg.getTxData()), timeout_ms); RFSpyResponse rfSpyResponse = rfspy.transmitThenReceive(new RadioPacket(injector, msg.getTxData()),
(byte) 0, (byte) repeatCount, (byte) 0, (byte) 0, timeout_ms, (byte) retryCount, extendPreamble_ms);
RadioResponse radioResponse = rfSpyResponse.getRadioResponse(); RadioResponse radioResponse = rfSpyResponse.getRadioResponse(injector);
E response = createResponseMessage(radioResponse.getPayload(), clazz);
E response = createResponseMessage(rfSpyResponse.getRadioResponse().getPayload(), clazz);
if (response.isValid()) { if (response.isValid()) {
// Mark this as the last time we heard from the pump. // Mark this as the last time we heard from the pump.
rememberLastGoodDeviceCommunicationTime(); rememberLastGoodDeviceCommunicationTime();
} else { } else {
LOG.warn("isDeviceReachable. Response is invalid ! [interrupted={}, timeout={}, unknownCommand={}, invalidParam={}]", rfSpyResponse.wasInterrupted(), aapsLogger.warn(LTag.PUMPCOMM, "isDeviceReachable. Response is invalid ! [interrupted={}, timeout={}, unknownCommand={}, invalidParam={}]", rfSpyResponse.wasInterrupted(),
rfSpyResponse.wasTimeout(), rfSpyResponse.isUnknownCommand(), rfSpyResponse.isInvalidParam()); rfSpyResponse.wasTimeout(), rfSpyResponse.isUnknownCommand(), rfSpyResponse.isInvalidParam());
if (rfSpyResponse.wasTimeout()) { if (rfSpyResponse.wasTimeout()) {
timeoutCount++; if (hasTunning()) {
timeoutCount++;
long diff = System.currentTimeMillis() - pumpStatus.lastConnection; long diff = System.currentTimeMillis() - getPumpStatus().lastConnection;
if (diff > ALLOWED_PUMP_UNREACHABLE) { if (diff > ALLOWED_PUMP_UNREACHABLE) {
LOG.warn("We reached max time that Pump can be unreachable. Starting Tuning."); aapsLogger.warn(LTag.PUMPCOMM, "We reached max time that Pump can be unreachable. Starting Tuning.");
ServiceTaskExecutor.startTask(new WakeAndTuneTask()); serviceTaskExecutor.startTask(new WakeAndTuneTask(injector));
timeoutCount = 0; timeoutCount = 0;
}
} }
throw new RileyLinkCommunicationException(RileyLinkBLEError.Timeout); throw new RileyLinkCommunicationException(RileyLinkBLEError.Timeout);
@ -105,8 +119,7 @@ public abstract class RileyLinkCommunicationManager {
} }
if (showPumpMessages) { if (showPumpMessages) {
if (isLogEnabled()) aapsLogger.info(LTag.PUMPCOMM, "Received:" + ByteUtil.shortHexString(rfSpyResponse.getRadioResponse(injector).getPayload()));
LOG.info("Received:" + ByteUtil.shortHexString(rfSpyResponse.getRadioResponse().getPayload()));
} }
return response; return response;
@ -125,6 +138,9 @@ public abstract class RileyLinkCommunicationManager {
return rfspy != null ? rfspy.notConnectedCount : 0; return rfspy != null ? rfspy.notConnectedCount : 0;
} }
public boolean hasTunning() {
return true;
}
// FIXME change wakeup // FIXME change wakeup
@ -134,27 +150,24 @@ public abstract class RileyLinkCommunicationManager {
// **** FIXME: this wakeup doesn't seem to work well... must revisit // **** FIXME: this wakeup doesn't seem to work well... must revisit
// receiverDeviceAwakeForMinutes = duration_minutes; // receiverDeviceAwakeForMinutes = duration_minutes;
MedtronicUtil.setPumpDeviceState(PumpDeviceState.WakingUp); medtronicPumpStatus.setPumpDeviceState(PumpDeviceState.WakingUp);
if (force) if (force)
nextWakeUpRequired = 0L; nextWakeUpRequired = 0L;
if (System.currentTimeMillis() > nextWakeUpRequired) { if (System.currentTimeMillis() > nextWakeUpRequired) {
if (isLogEnabled()) aapsLogger.info(LTag.PUMPCOMM, "Waking pump...");
LOG.info("Waking pump...");
byte[] pumpMsgContent = createPumpMessageContent(RLMessageType.ReadSimpleData); // simple byte[] pumpMsgContent = createPumpMessageContent(RLMessageType.ReadSimpleData); // simple
RFSpyResponse resp = rfspy.transmitThenReceive(new RadioPacket(pumpMsgContent), (byte)0, (byte)200, RFSpyResponse resp = rfspy.transmitThenReceive(new RadioPacket(injector, pumpMsgContent), (byte) 0, (byte) 200,
(byte)0, (byte)0, 25000, (byte)0); (byte) 0, (byte) 0, 25000, (byte) 0);
if (isLogEnabled()) aapsLogger.info(LTag.PUMPCOMM, "wakeup: raw response is " + ByteUtil.shortHexString(resp.getRaw()));
LOG.info("wakeup: raw response is " + ByteUtil.shortHexString(resp.getRaw()));
// FIXME wakeUp successful !!!!!!!!!!!!!!!!!! // FIXME wakeUp successful !!!!!!!!!!!!!!!!!!
nextWakeUpRequired = System.currentTimeMillis() + (receiverDeviceAwakeForMinutes * 60 * 1000); nextWakeUpRequired = System.currentTimeMillis() + (receiverDeviceAwakeForMinutes * 60 * 1000);
} else { } else {
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "Last pump communication was recent, not waking pump.");
LOG.trace("Last pump communication was recent, not waking pump.");
} }
// long lastGoodPlus = getLastGoodReceiverCommunicationTime() + (receiverDeviceAwakeForMinutes * 60 * 1000); // long lastGoodPlus = getLastGoodReceiverCommunicationTime() + (receiverDeviceAwakeForMinutes * 60 * 1000);
@ -178,7 +191,7 @@ public abstract class RileyLinkCommunicationManager {
public double tuneForDevice() { public double tuneForDevice() {
return scanForDevice(RileyLinkUtil.getRileyLinkTargetFrequency().getScanFrequencies()); return scanForDevice(rileyLinkServiceData.rileyLinkTargetFrequency.getScanFrequencies());
} }
@ -192,7 +205,7 @@ public abstract class RileyLinkCommunicationManager {
*/ */
public boolean isValidFrequency(double frequency) { public boolean isValidFrequency(double frequency) {
double[] scanFrequencies = RileyLinkUtil.getRileyLinkTargetFrequency().getScanFrequencies(); double[] scanFrequencies = rileyLinkServiceData.rileyLinkTargetFrequency.getScanFrequencies();
if (scanFrequencies.length == 1) { if (scanFrequencies.length == 1) {
return RileyLinkUtil.isSame(scanFrequencies[0], frequency); return RileyLinkUtil.isSame(scanFrequencies[0], frequency);
@ -210,9 +223,8 @@ public abstract class RileyLinkCommunicationManager {
public abstract boolean tryToConnectToDevice(); public abstract boolean tryToConnectToDevice();
public double scanForDevice(double[] frequencies) { private double scanForDevice(double[] frequencies) {
if (isLogEnabled()) aapsLogger.info(LTag.PUMPCOMM, "Scanning for receiver ({})", receiverDeviceID);
LOG.info("Scanning for receiver ({})", receiverDeviceID);
wakeUp(receiverDeviceAwakeForMinutes, false); wakeUp(receiverDeviceAwakeForMinutes, false);
FrequencyScanResults results = new FrequencyScanResults(); FrequencyScanResults results = new FrequencyScanResults();
@ -226,12 +238,12 @@ public abstract class RileyLinkCommunicationManager {
for (int j = 0; j < tries; j++) { for (int j = 0; j < tries; j++) {
byte[] pumpMsgContent = createPumpMessageContent(RLMessageType.ReadSimpleData); byte[] pumpMsgContent = createPumpMessageContent(RLMessageType.ReadSimpleData);
RFSpyResponse resp = rfspy.transmitThenReceive(new RadioPacket(pumpMsgContent), (byte)0, (byte)0, RFSpyResponse resp = rfspy.transmitThenReceive(new RadioPacket(injector, pumpMsgContent), (byte) 0, (byte) 0,
(byte)0, (byte)0, 1250, (byte)0); (byte) 0, (byte) 0, 1250, (byte) 0);
if (resp.wasTimeout()) { if (resp.wasTimeout()) {
LOG.error("scanForPump: Failed to find pump at frequency {}", frequencies[i]); aapsLogger.error(LTag.PUMPCOMM, "scanForPump: Failed to find pump at frequency {}", frequencies[i]);
} else if (resp.looksLikeRadioPacket()) { } else if (resp.looksLikeRadioPacket()) {
RadioResponse radioResponse = new RadioResponse(); RadioResponse radioResponse = new RadioResponse(injector);
try { try {
@ -243,23 +255,23 @@ public abstract class RileyLinkCommunicationManager {
trial.rssiList.add(rssi); trial.rssiList.add(rssi);
trial.successes++; trial.successes++;
} else { } else {
LOG.warn("Failed to parse radio response: " + ByteUtil.shortHexString(resp.getRaw())); aapsLogger.warn(LTag.PUMPCOMM, "Failed to parse radio response: " + ByteUtil.shortHexString(resp.getRaw()));
trial.rssiList.add(-99); trial.rssiList.add(-99);
} }
} catch (RileyLinkCommunicationException rle) { } catch (RileyLinkCommunicationException rle) {
LOG.warn("Failed to decode radio response: " + ByteUtil.shortHexString(resp.getRaw())); aapsLogger.warn(LTag.PUMPCOMM, "Failed to decode radio response: " + ByteUtil.shortHexString(resp.getRaw()));
trial.rssiList.add(-99); trial.rssiList.add(-99);
} }
} else { } else {
LOG.error("scanForPump: raw response is " + ByteUtil.shortHexString(resp.getRaw())); aapsLogger.error(LTag.PUMPCOMM, "scanForPump: raw response is " + ByteUtil.shortHexString(resp.getRaw()));
trial.rssiList.add(-99); trial.rssiList.add(-99);
} }
trial.tries++; trial.tries++;
} }
sumRSSI += -99.0 * (trial.tries - trial.successes); sumRSSI += -99.0 * (trial.tries - trial.successes);
trial.averageRSSI2 = (double)(sumRSSI) / (double)(trial.tries); trial.averageRSSI2 = (double) (sumRSSI) / (double) (trial.tries);
trial.calculateAverage(); trial.calculateAverage();
@ -274,10 +286,10 @@ public abstract class RileyLinkCommunicationManager {
FrequencyTrial one = results.trials.get(k); FrequencyTrial one = results.trials.get(k);
stringBuilder.append(String.format("Scan Result[%s]: Freq=%s, avg RSSI = %s\n", "" + k, "" stringBuilder.append(String.format("Scan Result[%s]: Freq=%s, avg RSSI = %s\n", "" + k, ""
+ one.frequencyMHz, "" + one.averageRSSI + ", RSSIs =" + one.rssiList)); + one.frequencyMHz, "" + one.averageRSSI + ", RSSIs =" + one.rssiList));
} }
LOG.info(stringBuilder.toString()); aapsLogger.info(LTag.PUMPCOMM, stringBuilder.toString());
results.sort(); // sorts in ascending order results.sort(); // sorts in ascending order
@ -285,11 +297,10 @@ public abstract class RileyLinkCommunicationManager {
results.bestFrequencyMHz = bestTrial.frequencyMHz; results.bestFrequencyMHz = bestTrial.frequencyMHz;
if (bestTrial.successes > 0) { if (bestTrial.successes > 0) {
rfspy.setBaseFrequency(results.bestFrequencyMHz); rfspy.setBaseFrequency(results.bestFrequencyMHz);
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "Best frequency found: " + results.bestFrequencyMHz);
LOG.debug("Best frequency found: " + results.bestFrequencyMHz);
return results.bestFrequencyMHz; return results.bestFrequencyMHz;
} else { } else {
LOG.error("No pump response during scan."); aapsLogger.error(LTag.PUMPCOMM, "No pump response during scan.");
return 0.0; return 0.0;
} }
} }
@ -315,25 +326,25 @@ public abstract class RileyLinkCommunicationManager {
rfspy.setBaseFrequency(freqMHz); rfspy.setBaseFrequency(freqMHz);
// RLMessage msg = makeRLMessage(RLMessageType.ReadSimpleData); // RLMessage msg = makeRLMessage(RLMessageType.ReadSimpleData);
byte[] pumpMsgContent = createPumpMessageContent(RLMessageType.ReadSimpleData); byte[] pumpMsgContent = createPumpMessageContent(RLMessageType.ReadSimpleData);
RadioPacket pkt = new RadioPacket(pumpMsgContent); RadioPacket pkt = new RadioPacket(injector, pumpMsgContent);
RFSpyResponse resp = rfspy.transmitThenReceive(pkt, (byte)0, (byte)0, (byte)0, (byte)0, SCAN_TIMEOUT, (byte)0); RFSpyResponse resp = rfspy.transmitThenReceive(pkt, (byte) 0, (byte) 0, (byte) 0, (byte) 0, SCAN_TIMEOUT, (byte) 0);
if (resp.wasTimeout()) { if (resp.wasTimeout()) {
LOG.warn("tune_tryFrequency: no pump response at frequency {}", freqMHz); aapsLogger.warn(LTag.PUMPCOMM, "tune_tryFrequency: no pump response at frequency {}", freqMHz);
} else if (resp.looksLikeRadioPacket()) { } else if (resp.looksLikeRadioPacket()) {
RadioResponse radioResponse = new RadioResponse(); RadioResponse radioResponse = new RadioResponse(injector);
try { try {
radioResponse.init(resp.getRaw()); radioResponse.init(resp.getRaw());
if (radioResponse.isValid()) { if (radioResponse.isValid()) {
LOG.warn("tune_tryFrequency: saw response level {} at frequency {}", radioResponse.rssi, freqMHz); aapsLogger.warn(LTag.PUMPCOMM, "tune_tryFrequency: saw response level {} at frequency {}", radioResponse.rssi, freqMHz);
return calculateRssi(radioResponse.rssi); return calculateRssi(radioResponse.rssi);
} else { } else {
LOG.warn("tune_tryFrequency: invalid radio response:" aapsLogger.warn(LTag.PUMPCOMM, "tune_tryFrequency: invalid radio response:"
+ ByteUtil.shortHexString(radioResponse.getPayload())); + ByteUtil.shortHexString(radioResponse.getPayload()));
} }
} catch (RileyLinkCommunicationException e) { } catch (RileyLinkCommunicationException e) {
LOG.warn("Failed to decode radio response: " + ByteUtil.shortHexString(resp.getRaw())); aapsLogger.warn(LTag.PUMPCOMM, "Failed to decode radio response: " + ByteUtil.shortHexString(resp.getRaw()));
} }
} }
@ -351,7 +362,7 @@ public abstract class RileyLinkCommunicationManager {
// Try again at larger step size // Try again at larger step size
stepsize += 0.05; stepsize += 0.05;
} else { } else {
if ((int)(evenBetterFrequency * 100) == (int)(betterFrequency * 100)) { if ((int) (evenBetterFrequency * 100) == (int) (betterFrequency * 100)) {
// value did not change, so we're done. // value did not change, so we're done.
break; break;
} }
@ -360,16 +371,13 @@ public abstract class RileyLinkCommunicationManager {
} }
if (betterFrequency == 0.0) { if (betterFrequency == 0.0) {
// we've failed... caller should try a full scan for pump // we've failed... caller should try a full scan for pump
if (isLogEnabled()) aapsLogger.error(LTag.PUMPCOMM, "quickTuneForPump: failed to find pump");
LOG.error("quickTuneForPump: failed to find pump");
} else { } else {
rfspy.setBaseFrequency(betterFrequency); rfspy.setBaseFrequency(betterFrequency);
if (betterFrequency != startFrequencyMHz) { if (betterFrequency != startFrequencyMHz) {
if (isLogEnabled()) aapsLogger.info(LTag.PUMPCOMM, "quickTuneForPump: new frequency is {}MHz", betterFrequency);
LOG.info("quickTuneForPump: new frequency is {}MHz", betterFrequency);
} else { } else {
if (isLogEnabled()) aapsLogger.info(LTag.PUMPCOMM, "quickTuneForPump: pump frequency is the same: {}MHz", startFrequencyMHz);
LOG.info("quickTuneForPump: pump frequency is the same: {}MHz", startFrequencyMHz);
} }
} }
return betterFrequency; return betterFrequency;
@ -377,8 +385,7 @@ public abstract class RileyLinkCommunicationManager {
private double quickTunePumpStep(double startFrequencyMHz, double stepSizeMHz) { private double quickTunePumpStep(double startFrequencyMHz, double stepSizeMHz) {
if (isLogEnabled()) aapsLogger.info(LTag.PUMPCOMM, "Doing quick radio tune for receiver ({})", receiverDeviceID);
LOG.info("Doing quick radio tune for receiver ({})", receiverDeviceID);
wakeUp(false); wakeUp(false);
int startRssi = tune_tryFrequency(startFrequencyMHz); int startRssi = tune_tryFrequency(startFrequencyMHz);
double lowerFrequency = startFrequencyMHz - stepSizeMHz; double lowerFrequency = startFrequencyMHz - stepSizeMHz;
@ -404,37 +411,29 @@ public abstract class RileyLinkCommunicationManager {
protected void rememberLastGoodDeviceCommunicationTime() { protected void rememberLastGoodDeviceCommunicationTime() {
lastGoodReceiverCommunicationTime = System.currentTimeMillis(); lastGoodReceiverCommunicationTime = System.currentTimeMillis();
SP.putLong(RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, lastGoodReceiverCommunicationTime); sp.putLong(RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, lastGoodReceiverCommunicationTime);
pumpStatus.setLastCommunicationToNow(); getPumpStatus().setLastCommunicationToNow();
} }
private long getLastGoodReceiverCommunicationTime() { private long getLastGoodReceiverCommunicationTime() {
// If we have a value of zero, we need to load from prefs. // If we have a value of zero, we need to load from prefs.
if (lastGoodReceiverCommunicationTime == 0L) { if (lastGoodReceiverCommunicationTime == 0L) {
lastGoodReceiverCommunicationTime = SP.getLong(RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L); lastGoodReceiverCommunicationTime = sp.getLong(RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L);
// Might still be zero, but that's fine. // Might still be zero, but that's fine.
} }
double minutesAgo = (System.currentTimeMillis() - lastGoodReceiverCommunicationTime) / (1000.0 * 60.0); double minutesAgo = (System.currentTimeMillis() - lastGoodReceiverCommunicationTime) / (1000.0 * 60.0);
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "Last good pump communication was " + minutesAgo + " minutes ago.");
LOG.trace("Last good pump communication was " + minutesAgo + " minutes ago.");
return lastGoodReceiverCommunicationTime; return lastGoodReceiverCommunicationTime;
} }
public PumpStatus getPumpStatus() {
return pumpStatus;
}
public void clearNotConnectedCount() { public void clearNotConnectedCount() {
if (rfspy != null) { if (rfspy != null) {
rfspy.notConnectedCount = 0; rfspy.notConnectedCount = 0;
} }
} }
private boolean isLogEnabled() { public abstract PumpStatus getPumpStatus();
return L.isEnabled(L.PUMPCOMM);
}
public abstract boolean isDeviceReachable();
} }

View file

@ -5,9 +5,6 @@ import android.content.Intent;
import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -15,180 +12,56 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import info.nightscout.androidaps.logging.L; import javax.inject.Inject;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; import javax.inject.Singleton;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkBLE;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.encoding.Encoding4b6b; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.encoding.Encoding4b6b;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.encoding.Encoding4b6bGeoff; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.encoding.Encoding4b6bGeoff;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkEncodingType; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkEncodingType;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkFirmwareVersion;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkTargetFrequency;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.BleAdvertisedData; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.BleAdvertisedData;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkService;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceNotification;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceResult; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceResult;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceTransport; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceTransport;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTask; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTask;
import info.nightscout.androidaps.plugins.pump.common.ui.RileyLinkSelectPreference;
import info.nightscout.androidaps.plugins.pump.medtronic.events.EventMedtronicDeviceStatusChange;
/** /**
* Created by andy on 17/05/2018. * Created by andy on 17/05/2018.
*/ */
@Singleton
public class RileyLinkUtil { public class RileyLinkUtil {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMP); private List<RLHistoryItem> historyRileyLink = new ArrayList<>();
protected static List<RLHistoryItem> historyRileyLink = new ArrayList<>(); private ServiceTask currentTask;
protected static RileyLinkCommunicationManager rileyLinkCommunicationManager;
static ServiceTask currentTask;
private static Context context;
private static RileyLinkBLE rileyLinkBLE;
private static RileyLinkServiceData rileyLinkServiceData;
private static RileyLinkService rileyLinkService;
private static RileyLinkTargetFrequency rileyLinkTargetFrequency;
private static RileyLinkTargetDevice targetDevice; private RileyLinkEncodingType encoding;
private static RileyLinkEncodingType encoding; private Encoding4b6b encoding4b6b;
private static RileyLinkSelectPreference rileyLinkSelectPreference;
private static Encoding4b6b encoding4b6b;
private static RileyLinkFirmwareVersion firmwareVersion;
@Inject
public static void setContext(Context contextIn) { public RileyLinkUtil() {
RileyLinkUtil.context = contextIn;
} }
public RileyLinkEncodingType getEncoding() {
public static RileyLinkEncodingType getEncoding() {
return encoding; return encoding;
} }
public static void setEncoding(RileyLinkEncodingType encoding) { public void setEncoding(RileyLinkEncodingType encoding) {
RileyLinkUtil.encoding = encoding; this.encoding = encoding;
if (encoding == RileyLinkEncodingType.FourByteSixByteLocal) { if (encoding == RileyLinkEncodingType.FourByteSixByteLocal) {
RileyLinkUtil.encoding4b6b = new Encoding4b6bGeoff(); this.encoding4b6b = new Encoding4b6bGeoff();
} }
} }
public static void sendBroadcastMessage(String message) { public void sendBroadcastMessage(String message, Context context) {
if (context != null) { Intent intent = new Intent(message);
Intent intent = new Intent(message); LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
LocalBroadcastManager.getInstance(RileyLinkUtil.context).sendBroadcast(intent);
}
} }
public static void setServiceState(RileyLinkServiceState newState) {
setServiceState(newState, null);
}
public static RileyLinkError getError() {
if (RileyLinkUtil.rileyLinkServiceData != null)
return RileyLinkUtil.rileyLinkServiceData.errorCode;
else
return null;
}
public static RileyLinkServiceState getServiceState() {
return workWithServiceState(null, null, false);
}
public static void setServiceState(RileyLinkServiceState newState, RileyLinkError errorCode) {
workWithServiceState(newState, errorCode, true);
}
private static synchronized RileyLinkServiceState workWithServiceState(RileyLinkServiceState newState,
RileyLinkError errorCode, boolean set) {
if (set) {
RileyLinkUtil.rileyLinkServiceData.serviceState = newState;
RileyLinkUtil.rileyLinkServiceData.errorCode = errorCode;
if (L.isEnabled(L.PUMP))
LOG.info("RileyLink State Changed: {} {}", newState, errorCode == null ? "" : " - Error State: "
+ errorCode.name());
RileyLinkUtil.historyRileyLink.add(new RLHistoryItem(RileyLinkUtil.rileyLinkServiceData.serviceState,
RileyLinkUtil.rileyLinkServiceData.errorCode, targetDevice));
RxBus.Companion.getINSTANCE().send(new EventMedtronicDeviceStatusChange(newState, errorCode));
return null;
} else {
return (RileyLinkUtil.rileyLinkServiceData == null || RileyLinkUtil.rileyLinkServiceData.serviceState == null) ? //
RileyLinkServiceState.NotStarted
: RileyLinkUtil.rileyLinkServiceData.serviceState;
}
}
public static RileyLinkBLE getRileyLinkBLE() {
return RileyLinkUtil.rileyLinkBLE;
}
public static void setRileyLinkBLE(RileyLinkBLE rileyLinkBLEIn) {
RileyLinkUtil.rileyLinkBLE = rileyLinkBLEIn;
}
public static RileyLinkServiceData getRileyLinkServiceData() {
return RileyLinkUtil.rileyLinkServiceData;
}
public static void setRileyLinkServiceData(RileyLinkServiceData rileyLinkServiceData) {
RileyLinkUtil.rileyLinkServiceData = rileyLinkServiceData;
}
public static boolean hasPumpBeenTunned() {
return RileyLinkUtil.rileyLinkServiceData.tuneUpDone;
}
public static RileyLinkService getRileyLinkService() {
return RileyLinkUtil.rileyLinkService;
}
public static void setRileyLinkService(RileyLinkService rileyLinkService) {
RileyLinkUtil.rileyLinkService = rileyLinkService;
}
public static RileyLinkCommunicationManager getRileyLinkCommunicationManager() {
return RileyLinkUtil.rileyLinkCommunicationManager;
}
public static void setRileyLinkCommunicationManager(RileyLinkCommunicationManager rileyLinkCommunicationManager) {
RileyLinkUtil.rileyLinkCommunicationManager = rileyLinkCommunicationManager;
}
public static boolean sendNotification(ServiceNotification notification, Integer clientHashcode) {
return false;
}
// FIXME remove ? // FIXME remove ?
public static void setCurrentTask(ServiceTask task) { public void setCurrentTask(ServiceTask task) {
if (currentTask == null) { if (currentTask == null) {
currentTask = task; currentTask = task;
} else { } else {
@ -197,7 +70,7 @@ public class RileyLinkUtil {
} }
public static void finishCurrentTask(ServiceTask task) { public void finishCurrentTask(ServiceTask task) {
if (task != currentTask) { if (task != currentTask) {
//LOG.error("finishCurrentTask: task does not match"); //LOG.error("finishCurrentTask: task does not match");
} }
@ -211,7 +84,7 @@ public class RileyLinkUtil {
} }
public static void sendServiceTransportResponse(ServiceTransport transport, ServiceResult serviceResult) { private static void sendServiceTransportResponse(ServiceTransport transport, ServiceResult serviceResult) {
// get the key (hashcode) of the client who requested this // get the key (hashcode) of the client who requested this
Integer clientHashcode = transport.getSenderHashcode(); Integer clientHashcode = transport.getSenderHashcode();
// make a new bundle to send as the message data // make a new bundle to send as the message data
@ -222,16 +95,6 @@ public class RileyLinkUtil {
} }
public static RileyLinkTargetFrequency getRileyLinkTargetFrequency() {
return RileyLinkUtil.rileyLinkTargetFrequency;
}
public static void setRileyLinkTargetFrequency(RileyLinkTargetFrequency rileyLinkTargetFrequency) {
RileyLinkUtil.rileyLinkTargetFrequency = rileyLinkTargetFrequency;
}
public static boolean isSame(Double d1, Double d2) { public static boolean isSame(Double d1, Double d2) {
double diff = d1 - d2; double diff = d1 - d2;
@ -239,7 +102,6 @@ public class RileyLinkUtil {
} }
@Deprecated
public static BleAdvertisedData parseAdertisedData(byte[] advertisedData) { public static BleAdvertisedData parseAdertisedData(byte[] advertisedData) {
List<UUID> uuids = new ArrayList<UUID>(); List<UUID> uuids = new ArrayList<UUID>();
String name = null; String name = null;
@ -285,45 +147,11 @@ public class RileyLinkUtil {
return new BleAdvertisedData(uuids, name); return new BleAdvertisedData(uuids, name);
} }
public List<RLHistoryItem> getRileyLinkHistory() {
public static List<RLHistoryItem> getRileyLinkHistory() {
return historyRileyLink; return historyRileyLink;
} }
public Encoding4b6b getEncoding4b6b() {
public static RileyLinkTargetDevice getTargetDevice() { return encoding4b6b;
return targetDevice;
}
public static void setTargetDevice(RileyLinkTargetDevice targetDevice) {
RileyLinkUtil.targetDevice = targetDevice;
}
public static void setRileyLinkSelectPreference(RileyLinkSelectPreference rileyLinkSelectPreference) {
RileyLinkUtil.rileyLinkSelectPreference = rileyLinkSelectPreference;
}
public static RileyLinkSelectPreference getRileyLinkSelectPreference() {
return rileyLinkSelectPreference;
}
public static Encoding4b6b getEncoding4b6b() {
return RileyLinkUtil.encoding4b6b;
}
public static void setFirmwareVersion(RileyLinkFirmwareVersion firmwareVersion) {
RileyLinkUtil.firmwareVersion = firmwareVersion;
}
public static RileyLinkFirmwareVersion getFirmwareVersion() {
return firmwareVersion;
} }
} }

View file

@ -2,15 +2,14 @@ package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble;
import android.os.SystemClock; import android.os.SystemClock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.UUID; import java.util.UUID;
import info.nightscout.androidaps.MainApp; import javax.inject.Inject;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.command.Reset; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.command.Reset;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.command.RileyLinkCommand; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.command.RileyLinkCommand;
@ -28,44 +27,47 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.Rile
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkFirmwareVersion; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkFirmwareVersion;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkTargetFrequency; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkTargetFrequency;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.BLECommOperationResult; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.BLECommOperationResult;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData;
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil; import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil;
import info.nightscout.androidaps.plugins.pump.common.utils.ThreadUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ThreadUtil;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicConst; import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicConst;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
/** /**
* Created by geoff on 5/26/16. * Created by geoff on 5/26/16.
*/ */
public class RFSpy { public class RFSpy {
public static final long RILEYLINK_FREQ_XTAL = 24000000; @Inject AAPSLogger aapsLogger;
public static final int EXPECTED_MAX_BLUETOOTH_LATENCY_MS = 7500; // 1500 @Inject ResourceHelper resourceHelper;
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPBTCOMM); @Inject SP sp;
@Inject RileyLinkServiceData rileyLinkServiceData;
@Inject RileyLinkUtil rileyLinkUtil;
private final HasAndroidInjector injector;
private static final long RILEYLINK_FREQ_XTAL = 24000000;
private static final int EXPECTED_MAX_BLUETOOTH_LATENCY_MS = 7500; // 1500
public int notConnectedCount = 0; public int notConnectedCount = 0;
private RileyLinkBLE rileyLinkBle; private RileyLinkBLE rileyLinkBle;
private RFSpyReader reader; private RFSpyReader reader;
private RileyLinkTargetFrequency selectedTargetFrequency;
private UUID radioServiceUUID = UUID.fromString(GattAttributes.SERVICE_RADIO); private UUID radioServiceUUID = UUID.fromString(GattAttributes.SERVICE_RADIO);
private UUID radioDataUUID = UUID.fromString(GattAttributes.CHARA_RADIO_DATA); private UUID radioDataUUID = UUID.fromString(GattAttributes.CHARA_RADIO_DATA);
private UUID radioVersionUUID = UUID.fromString(GattAttributes.CHARA_RADIO_VERSION); private UUID radioVersionUUID = UUID.fromString(GattAttributes.CHARA_RADIO_VERSION);
private UUID responseCountUUID = UUID.fromString(GattAttributes.CHARA_RADIO_RESPONSE_COUNT); private UUID responseCountUUID = UUID.fromString(GattAttributes.CHARA_RADIO_RESPONSE_COUNT);
private RileyLinkFirmwareVersion firmwareVersion;
private String bleVersion; // We don't use it so no need of sofisticated logic private String bleVersion; // We don't use it so no need of sofisticated logic
Double currentFrequencyMHz; private Double currentFrequencyMHz;
public RFSpy(RileyLinkBLE rileyLinkBle) { public RFSpy(HasAndroidInjector injector, RileyLinkBLE rileyLinkBle) {
injector.androidInjector().inject(this);
this.injector = injector;
this.rileyLinkBle = rileyLinkBle; this.rileyLinkBle = rileyLinkBle;
reader = new RFSpyReader(rileyLinkBle); reader = new RFSpyReader(aapsLogger, rileyLinkBle);
} }
public RileyLinkFirmwareVersion getRLVersionCached() {
return firmwareVersion;
}
public String getBLEVersionCached() { public String getBLEVersionCached() {
return bleVersion; return bleVersion;
} }
@ -74,13 +76,7 @@ public class RFSpy {
// Call this after the RL services are discovered. // Call this after the RL services are discovered.
// Starts an async task to read when data is available // Starts an async task to read when data is available
public void startReader() { public void startReader() {
rileyLinkBle.registerRadioResponseCountNotification(new Runnable() { rileyLinkBle.registerRadioResponseCountNotification(this::newDataIsAvailable);
@Override
public void run() {
newDataIsAvailable();
}
});
reader.start(); reader.start();
} }
@ -89,13 +85,12 @@ public class RFSpy {
// firmware version // firmware version
public void initializeRileyLink() { public void initializeRileyLink() {
bleVersion = getVersion(); bleVersion = getVersion();
firmwareVersion = getFirmwareVersion(); rileyLinkServiceData.firmwareVersion = getFirmwareVersion();
RileyLinkUtil.setFirmwareVersion(firmwareVersion);
} }
// Call this from the "response count" notification handler. // Call this from the "response count" notification handler.
public void newDataIsAvailable() { private void newDataIsAvailable() {
// pass the message to the reader (which should be internal to RFSpy) // pass the message to the reader (which should be internal to RFSpy)
reader.newDataIsAvailable(); reader.newDataIsAvailable();
} }
@ -107,20 +102,24 @@ public class RFSpy {
BLECommOperationResult result = rileyLinkBle.readCharacteristic_blocking(radioServiceUUID, radioVersionUUID); BLECommOperationResult result = rileyLinkBle.readCharacteristic_blocking(radioServiceUUID, radioVersionUUID);
if (result.resultCode == BLECommOperationResult.RESULT_SUCCESS) { if (result.resultCode == BLECommOperationResult.RESULT_SUCCESS) {
String version = StringUtil.fromBytes(result.value); String version = StringUtil.fromBytes(result.value);
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPBTCOMM, "BLE Version: " + version);
LOG.debug("BLE Version: " + version);
return version; return version;
} else { } else {
LOG.error("getVersion failed with code: " + result.resultCode); aapsLogger.error(LTag.PUMPBTCOMM, "getVersion failed with code: " + result.resultCode);
return "(null)"; return "(null)";
} }
} }
public boolean isRileyLinkStillAvailable() {
RileyLinkFirmwareVersion firmwareVersion = getFirmwareVersion();
public RileyLinkFirmwareVersion getFirmwareVersion() { return (firmwareVersion != RileyLinkFirmwareVersion.UnknownVersion);
}
if (isLogEnabled())
LOG.debug("Firmware Version. Get Version - Start"); private RileyLinkFirmwareVersion getFirmwareVersion() {
aapsLogger.debug(LTag.PUMPBTCOMM, "Firmware Version. Get Version - Start");
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
// We have to call raw version of communication to get firmware version // We have to call raw version of communication to get firmware version
@ -129,8 +128,7 @@ public class RFSpy {
byte[] getVersionRaw = getByteArray(RileyLinkCommandType.GetVersion.code); byte[] getVersionRaw = getByteArray(RileyLinkCommandType.GetVersion.code);
byte[] response = writeToDataRaw(getVersionRaw, 5000); byte[] response = writeToDataRaw(getVersionRaw, 5000);
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPBTCOMM, "Firmware Version. GetVersion [response={}]", ByteUtil.shortHexString(response));
LOG.debug("Firmware Version. GetVersion [response={}]", ByteUtil.shortHexString(response));
if (response != null) { // && response[0] == (byte) 0xDD) { if (response != null) { // && response[0] == (byte) 0xDD) {
@ -139,8 +137,7 @@ public class RFSpy {
RileyLinkFirmwareVersion version = RileyLinkFirmwareVersion.getByVersionString(StringUtil RileyLinkFirmwareVersion version = RileyLinkFirmwareVersion.getByVersionString(StringUtil
.fromBytes(response)); .fromBytes(response));
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPBTCOMM, "Firmware Version string: {}, resolved to {}.", versionString, version);
LOG.trace("Firmware Version string: {}, resolved to {}.", versionString, version);
if (version != RileyLinkFirmwareVersion.UnknownVersion) if (version != RileyLinkFirmwareVersion.UnknownVersion)
return version; return version;
@ -149,7 +146,7 @@ public class RFSpy {
} }
} }
LOG.error("Firmware Version can't be determined. Checking with BLE Version [{}].", bleVersion); aapsLogger.error(LTag.PUMPBTCOMM, "Firmware Version can't be determined. Checking with BLE Version [{}].", bleVersion);
if (bleVersion.contains(" 2.")) { if (bleVersion.contains(" 2.")) {
return RileyLinkFirmwareVersion.Version_2_0; return RileyLinkFirmwareVersion.Version_2_0;
@ -165,7 +162,7 @@ public class RFSpy {
byte[] junkInBuffer = reader.poll(0); byte[] junkInBuffer = reader.poll(0);
while (junkInBuffer != null) { while (junkInBuffer != null) {
LOG.warn(ThreadUtil.sig() + "writeToData: draining read queue, found this: " aapsLogger.warn(LTag.PUMPBTCOMM, ThreadUtil.sig() + "writeToData: draining read queue, found this: "
+ ByteUtil.shortHexString(junkInBuffer)); + ByteUtil.shortHexString(junkInBuffer));
junkInBuffer = reader.poll(0); junkInBuffer = reader.poll(0);
} }
@ -173,12 +170,12 @@ public class RFSpy {
// prepend length, and send it. // prepend length, and send it.
byte[] prepended = ByteUtil.concat(new byte[]{(byte) (bytes.length)}, bytes); byte[] prepended = ByteUtil.concat(new byte[]{(byte) (bytes.length)}, bytes);
LOG.debug("writeToData (raw={})", ByteUtil.shortHexString(prepended)); aapsLogger.debug(LTag.PUMPBTCOMM, "writeToData (raw={})", ByteUtil.shortHexString(prepended));
BLECommOperationResult writeCheck = rileyLinkBle.writeCharacteristic_blocking(radioServiceUUID, radioDataUUID, BLECommOperationResult writeCheck = rileyLinkBle.writeCharacteristic_blocking(radioServiceUUID, radioDataUUID,
prepended); prepended);
if (writeCheck.resultCode != BLECommOperationResult.RESULT_SUCCESS) { if (writeCheck.resultCode != BLECommOperationResult.RESULT_SUCCESS) {
LOG.error("BLE Write operation failed, code=" + writeCheck.resultCode); aapsLogger.error(LTag.PUMPBTCOMM, "BLE Write operation failed, code=" + writeCheck.resultCode);
return null; // will be a null (invalid) response return null; // will be a null (invalid) response
} }
SystemClock.sleep(100); SystemClock.sleep(100);
@ -197,23 +194,22 @@ public class RFSpy {
RFSpyResponse resp = new RFSpyResponse(command, rawResponse); RFSpyResponse resp = new RFSpyResponse(command, rawResponse);
if (rawResponse == null) { if (rawResponse == null) {
LOG.error("writeToData: No response from RileyLink"); aapsLogger.error(LTag.PUMPBTCOMM, "writeToData: No response from RileyLink");
notConnectedCount++; notConnectedCount++;
} else { } else {
if (resp.wasInterrupted()) { if (resp.wasInterrupted()) {
LOG.error("writeToData: RileyLink was interrupted"); aapsLogger.error(LTag.PUMPBTCOMM, "writeToData: RileyLink was interrupted");
} else if (resp.wasTimeout()) { } else if (resp.wasTimeout()) {
LOG.error("writeToData: RileyLink reports timeout"); aapsLogger.error(LTag.PUMPBTCOMM, "writeToData: RileyLink reports timeout");
notConnectedCount++; notConnectedCount++;
} else if (resp.isOK()) { } else if (resp.isOK()) {
LOG.warn("writeToData: RileyLink reports OK"); aapsLogger.warn(LTag.PUMPBTCOMM, "writeToData: RileyLink reports OK");
resetNotConnectedCount(); resetNotConnectedCount();
} else { } else {
if (resp.looksLikeRadioPacket()) { if (resp.looksLikeRadioPacket()) {
// RadioResponse radioResp = resp.getRadioResponse(); // RadioResponse radioResp = resp.getRadioResponse();
// byte[] responsePayload = radioResp.getPayload(); // byte[] responsePayload = radioResp.getPayload();
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPBTCOMM, "writeToData: received radio response. Will decode at upper level");
LOG.trace("writeToData: received radio response. Will decode at upper level");
resetNotConnectedCount(); resetNotConnectedCount();
} }
// Log.i(TAG, "writeToData: raw response is " + ByteUtil.shortHexString(rawResponse)); // Log.i(TAG, "writeToData: raw response is " + ByteUtil.shortHexString(rawResponse));
@ -267,14 +263,14 @@ public class RFSpy {
int sendDelay = repeatCount * delay_ms; int sendDelay = repeatCount * delay_ms;
int receiveDelay = timeout_ms * (retryCount + 1); int receiveDelay = timeout_ms * (retryCount + 1);
SendAndListen command = new SendAndListen(sendChannel, repeatCount, delay_ms, listenChannel, timeout_ms, SendAndListen command = new SendAndListen(injector, sendChannel, repeatCount, delay_ms, listenChannel, timeout_ms,
retryCount, extendPreamble_ms, pkt); retryCount, extendPreamble_ms, pkt);
return writeToData(command, sendDelay + receiveDelay + EXPECTED_MAX_BLUETOOTH_LATENCY_MS); return writeToData(command, sendDelay + receiveDelay + EXPECTED_MAX_BLUETOOTH_LATENCY_MS);
} }
public RFSpyResponse updateRegister(CC111XRegister reg, int val) { private RFSpyResponse updateRegister(CC111XRegister reg, int val) {
RFSpyResponse resp = writeToData(new UpdateRegister(reg, (byte) val), EXPECTED_MAX_BLUETOOTH_LATENCY_MS); RFSpyResponse resp = writeToData(new UpdateRegister(reg, (byte) val), EXPECTED_MAX_BLUETOOTH_LATENCY_MS);
return resp; return resp;
} }
@ -285,11 +281,11 @@ public class RFSpy {
updateRegister(CC111XRegister.freq0, (byte) (value & 0xff)); updateRegister(CC111XRegister.freq0, (byte) (value & 0xff));
updateRegister(CC111XRegister.freq1, (byte) ((value >> 8) & 0xff)); updateRegister(CC111XRegister.freq1, (byte) ((value >> 8) & 0xff));
updateRegister(CC111XRegister.freq2, (byte) ((value >> 16) & 0xff)); updateRegister(CC111XRegister.freq2, (byte) ((value >> 16) & 0xff));
LOG.info("Set frequency to {} MHz", freqMHz); aapsLogger.info(LTag.PUMPBTCOMM, "Set frequency to {} MHz", freqMHz);
this.currentFrequencyMHz = freqMHz; this.currentFrequencyMHz = freqMHz;
configureRadioForRegion(RileyLinkUtil.getRileyLinkTargetFrequency()); configureRadioForRegion(rileyLinkServiceData.rileyLinkTargetFrequency);
} }
@ -355,35 +351,32 @@ public class RFSpy {
} }
break; break;
default: default:
LOG.warn("No region configuration for RfSpy and {}", frequency.name()); aapsLogger.warn(LTag.PUMPBTCOMM, "No region configuration for RfSpy and {}", frequency.name());
break; break;
} }
this.selectedTargetFrequency = frequency;
} }
private void setMedtronicEncoding() { private void setMedtronicEncoding() {
RileyLinkEncodingType encoding = RileyLinkEncodingType.FourByteSixByteLocal; RileyLinkEncodingType encoding = RileyLinkEncodingType.FourByteSixByteLocal;
if (RileyLinkFirmwareVersion.isSameVersion(this.firmwareVersion, RileyLinkFirmwareVersion.Version2AndHigher)) { if (RileyLinkFirmwareVersion.isSameVersion(rileyLinkServiceData.firmwareVersion, RileyLinkFirmwareVersion.Version2AndHigher)) {
if (SP.getString(MedtronicConst.Prefs.Encoding, "None").equals(MainApp.gs(R.string.key_medtronic_pump_encoding_4b6b_rileylink))) { if (sp.getString(MedtronicConst.Prefs.Encoding, "None").equals(resourceHelper.gs(R.string.key_medtronic_pump_encoding_4b6b_rileylink))) {
encoding = RileyLinkEncodingType.FourByteSixByteRileyLink; encoding = RileyLinkEncodingType.FourByteSixByteRileyLink;
} }
} }
setRileyLinkEncoding(encoding); setRileyLinkEncoding(encoding);
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPBTCOMM, "Set Encoding for Medtronic: " + encoding.name());
LOG.debug("Set Encoding for Medtronic: " + encoding.name());
} }
private RFSpyResponse setPreamble(int preamble) { private RFSpyResponse setPreamble(int preamble) {
RFSpyResponse resp = null; RFSpyResponse resp = null;
try { try {
resp = writeToData(new SetPreamble(preamble), EXPECTED_MAX_BLUETOOTH_LATENCY_MS); resp = writeToData(new SetPreamble(injector, preamble), EXPECTED_MAX_BLUETOOTH_LATENCY_MS);
} catch (Exception e) { } catch (Exception e) {
e.toString(); e.toString();
} }
@ -396,7 +389,7 @@ public class RFSpy {
if (resp.isOK()) { if (resp.isOK()) {
reader.setRileyLinkEncodingType(encoding); reader.setRileyLinkEncodingType(encoding);
RileyLinkUtil.setEncoding(encoding); rileyLinkUtil.setEncoding(encoding);
} }
return resp; return resp;
@ -424,16 +417,10 @@ public class RFSpy {
RFSpyResponse resp = null; RFSpyResponse resp = null;
try { try {
resp = writeToData(new Reset(), EXPECTED_MAX_BLUETOOTH_LATENCY_MS); resp = writeToData(new Reset(), EXPECTED_MAX_BLUETOOTH_LATENCY_MS);
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPBTCOMM, "Reset command send, response: {}", resp);
LOG.debug("Reset command send, response: {}", resp);
} catch (Exception e) { } catch (Exception e) {
e.toString(); e.toString();
} }
return resp; return resp;
} }
private boolean isLogEnabled() {
return L.isEnabled(L.PUMPBTCOMM);
}
} }

View file

@ -1,19 +1,15 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble; package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble;
import android.os.AsyncTask;
import android.os.SystemClock;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.slf4j.Logger; import info.nightscout.androidaps.logging.AAPSLogger;
import org.slf4j.LoggerFactory; import info.nightscout.androidaps.logging.LTag;
import android.os.AsyncTask;
import android.os.SystemClock;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkEncodingType; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkEncodingType;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.BLECommOperationResult; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.BLECommOperationResult;
@ -25,7 +21,7 @@ import info.nightscout.androidaps.plugins.pump.common.utils.ThreadUtil;
*/ */
public class RFSpyReader { public class RFSpyReader {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPBTCOMM); private final AAPSLogger aapsLogger;
private static AsyncTask<Void, Void, Void> readerTask; private static AsyncTask<Void, Void, Void> readerTask;
private RileyLinkBLE rileyLinkBle; private RileyLinkBLE rileyLinkBle;
private Semaphore waitForRadioData = new Semaphore(0, true); private Semaphore waitForRadioData = new Semaphore(0, true);
@ -35,13 +31,9 @@ public class RFSpyReader {
private boolean stopAtNull = true; private boolean stopAtNull = true;
public RFSpyReader(RileyLinkBLE rileyLinkBle) { RFSpyReader(AAPSLogger aapsLogger, RileyLinkBLE rileyLinkBle) {
this.rileyLinkBle = rileyLinkBle; this.rileyLinkBle = rileyLinkBle;
} this.aapsLogger = aapsLogger;
public void init(RileyLinkBLE rileyLinkBLE) {
this.rileyLinkBle = rileyLinkBLE;
} }
@ -52,45 +44,43 @@ public class RFSpyReader {
this.rileyLinkBle = rileyLinkBle; this.rileyLinkBle = rileyLinkBle;
} }
public void setRileyLinkEncodingType(RileyLinkEncodingType encodingType) { void setRileyLinkEncodingType(RileyLinkEncodingType encodingType) {
stopAtNull = !(encodingType == RileyLinkEncodingType.Manchester || // stopAtNull = !(encodingType == RileyLinkEncodingType.Manchester || //
encodingType == RileyLinkEncodingType.FourByteSixByteRileyLink); encodingType == RileyLinkEncodingType.FourByteSixByteRileyLink);
} }
// This timeout must be coordinated with the length of the RFSpy radio operation or Bad Things Happen. // This timeout must be coordinated with the length of the RFSpy radio operation or Bad Things Happen.
public byte[] poll(int timeout_ms) { byte[] poll(int timeout_ms) {
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPBTCOMM, ThreadUtil.sig() + "Entering poll at t==" + SystemClock.uptimeMillis() + ", timeout is " + timeout_ms
LOG.trace(ThreadUtil.sig() + "Entering poll at t==" + SystemClock.uptimeMillis() + ", timeout is " + timeout_ms
+ " mDataQueue size is " + mDataQueue.size()); + " mDataQueue size is " + mDataQueue.size());
if (mDataQueue.isEmpty()) if (mDataQueue.isEmpty()) {
try { try {
// block until timeout or data available. // block until timeout or data available.
// returns null if timeout. // returns null if timeout.
byte[] dataFromQueue = mDataQueue.poll(timeout_ms, TimeUnit.MILLISECONDS); byte[] dataFromQueue = mDataQueue.poll(timeout_ms, TimeUnit.MILLISECONDS);
if (dataFromQueue != null) { if (dataFromQueue != null) {
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPBTCOMM, "Got data [" + ByteUtil.shortHexString(dataFromQueue) + "] at t=="
LOG.debug("Got data [" + ByteUtil.shortHexString(dataFromQueue) + "] at t=="
+ SystemClock.uptimeMillis()); + SystemClock.uptimeMillis());
} else { } else {
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPBTCOMM, "Got data [null] at t==" + SystemClock.uptimeMillis());
LOG.debug("Got data [null] at t==" + SystemClock.uptimeMillis());
} }
return dataFromQueue; return dataFromQueue;
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOG.error("poll: Interrupted waiting for data"); aapsLogger.error(LTag.PUMPBTCOMM, "poll: Interrupted waiting for data");
} }
}
return null; return null;
} }
// Call this from the "response count" notification handler. // Call this from the "response count" notification handler.
public void newDataIsAvailable() { void newDataIsAvailable() {
releaseCount++; releaseCount++;
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPBTCOMM, ThreadUtil.sig() + "waitForRadioData released(count=" + releaseCount + ") at t="
LOG.trace(ThreadUtil.sig() + "waitForRadioData released(count=" + releaseCount + ") at t="
+ SystemClock.uptimeMillis()); + SystemClock.uptimeMillis());
waitForRadioData.release(); waitForRadioData.release();
} }
@ -108,8 +98,7 @@ public class RFSpyReader {
try { try {
acquireCount++; acquireCount++;
waitForRadioData.acquire(); waitForRadioData.acquire();
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPBTCOMM, ThreadUtil.sig() + "waitForRadioData acquired (count=" + acquireCount + ") at t="
LOG.trace(ThreadUtil.sig() + "waitForRadioData acquired (count=" + acquireCount + ") at t="
+ SystemClock.uptimeMillis()); + SystemClock.uptimeMillis());
SystemClock.sleep(100); SystemClock.sleep(100);
SystemClock.sleep(1); SystemClock.sleep(1);
@ -128,24 +117,19 @@ public class RFSpyReader {
} }
mDataQueue.add(result.value); mDataQueue.add(result.value);
} else if (result.resultCode == BLECommOperationResult.RESULT_INTERRUPTED) { } else if (result.resultCode == BLECommOperationResult.RESULT_INTERRUPTED) {
LOG.error("Read operation was interrupted"); aapsLogger.error(LTag.PUMPBTCOMM, "Read operation was interrupted");
} else if (result.resultCode == BLECommOperationResult.RESULT_TIMEOUT) { } else if (result.resultCode == BLECommOperationResult.RESULT_TIMEOUT) {
LOG.error("Read operation on Radio Data timed out"); aapsLogger.error(LTag.PUMPBTCOMM, "Read operation on Radio Data timed out");
} else if (result.resultCode == BLECommOperationResult.RESULT_BUSY) { } else if (result.resultCode == BLECommOperationResult.RESULT_BUSY) {
LOG.error("FAIL: RileyLinkBLE reports operation already in progress"); aapsLogger.error(LTag.PUMPBTCOMM, "FAIL: RileyLinkBLE reports operation already in progress");
} else if (result.resultCode == BLECommOperationResult.RESULT_NONE) { } else if (result.resultCode == BLECommOperationResult.RESULT_NONE) {
LOG.error("FAIL: got invalid result code: " + result.resultCode); aapsLogger.error(LTag.PUMPBTCOMM, "FAIL: got invalid result code: " + result.resultCode);
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOG.error("Interrupted while waiting for data"); aapsLogger.error(LTag.PUMPBTCOMM, "Interrupted while waiting for data");
} }
} }
} }
}.execute(); }.execute();
} }
private boolean isLogEnabled() {
return L.isEnabled(L.PUMPBTCOMM);
}
} }

View file

@ -12,15 +12,16 @@ import android.content.Context;
import android.os.SystemClock; import android.os.SystemClock;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
import info.nightscout.androidaps.logging.L; import javax.inject.Inject;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes;
@ -31,6 +32,7 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operation
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.DescriptorWriteOperation; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.DescriptorWriteOperation;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData;
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
import info.nightscout.androidaps.plugins.pump.common.utils.ThreadUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ThreadUtil;
@ -40,11 +42,13 @@ import info.nightscout.androidaps.plugins.pump.common.utils.ThreadUtil;
*/ */
public class RileyLinkBLE { public class RileyLinkBLE {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPBTCOMM); @Inject AAPSLogger aapsLogger;
@Inject RileyLinkServiceData rileyLinkServiceData;
@Inject RileyLinkUtil rileyLinkUtil;
private final Context context; private final Context context;
public boolean gattDebugEnabled = true; private boolean gattDebugEnabled = true;
boolean manualDisconnect = false; private boolean manualDisconnect = false;
private BluetoothAdapter bluetoothAdapter; private BluetoothAdapter bluetoothAdapter;
private BluetoothGattCallback bluetoothGattCallback; private BluetoothGattCallback bluetoothGattCallback;
private BluetoothDevice rileyLinkDevice; private BluetoothDevice rileyLinkDevice;
@ -55,24 +59,24 @@ public class RileyLinkBLE {
private boolean mIsConnected = false; private boolean mIsConnected = false;
public RileyLinkBLE(final Context context) { public RileyLinkBLE(HasAndroidInjector injector, final Context context) {
injector.androidInjector().inject(this);
this.context = context; this.context = context;
this.bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); this.bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPBTCOMM, "BT Adapter: " + this.bluetoothAdapter);
LOG.debug("BT Adapter: " + this.bluetoothAdapter);
bluetoothGattCallback = new BluetoothGattCallback() { bluetoothGattCallback = new BluetoothGattCallback() {
@Override @Override
public void onCharacteristicChanged(final BluetoothGatt gatt, public void onCharacteristicChanged(final BluetoothGatt gatt,
final BluetoothGattCharacteristic characteristic) { final BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic); super.onCharacteristicChanged(gatt, characteristic);
if (gattDebugEnabled && isLogEnabled()) { if (gattDebugEnabled) {
LOG.trace(ThreadUtil.sig() + "onCharacteristicChanged " aapsLogger.debug(LTag.PUMPBTCOMM, ThreadUtil.sig() + "onCharacteristicChanged "
+ GattAttributes.lookup(characteristic.getUuid()) + " " + GattAttributes.lookup(characteristic.getUuid()) + " "
+ ByteUtil.getHex(characteristic.getValue())); + ByteUtil.getHex(characteristic.getValue()));
if (characteristic.getUuid().equals(UUID.fromString(GattAttributes.CHARA_RADIO_RESPONSE_COUNT))) { if (characteristic.getUuid().equals(UUID.fromString(GattAttributes.CHARA_RADIO_RESPONSE_COUNT))) {
LOG.debug("Response Count is " + ByteUtil.shortHexString(characteristic.getValue())); aapsLogger.debug(LTag.PUMPBTCOMM, "Response Count is " + ByteUtil.shortHexString(characteristic.getValue()));
} }
} }
if (radioResponseCountNotified != null) { if (radioResponseCountNotified != null) {
@ -87,8 +91,8 @@ public class RileyLinkBLE {
super.onCharacteristicRead(gatt, characteristic, status); super.onCharacteristicRead(gatt, characteristic, status);
final String statusMessage = getGattStatusMessage(status); final String statusMessage = getGattStatusMessage(status);
if (gattDebugEnabled && isLogEnabled()) { if (gattDebugEnabled) {
LOG.trace(ThreadUtil.sig() + "onCharacteristicRead (" aapsLogger.debug(LTag.PUMPBTCOMM, ThreadUtil.sig() + "onCharacteristicRead ("
+ GattAttributes.lookup(characteristic.getUuid()) + ") " + statusMessage + ":" + GattAttributes.lookup(characteristic.getUuid()) + ") " + statusMessage + ":"
+ ByteUtil.getHex(characteristic.getValue())); + ByteUtil.getHex(characteristic.getValue()));
} }
@ -102,8 +106,8 @@ public class RileyLinkBLE {
super.onCharacteristicWrite(gatt, characteristic, status); super.onCharacteristicWrite(gatt, characteristic, status);
final String uuidString = GattAttributes.lookup(characteristic.getUuid()); final String uuidString = GattAttributes.lookup(characteristic.getUuid());
if (gattDebugEnabled && isLogEnabled()) { if (gattDebugEnabled) {
LOG.trace(ThreadUtil.sig() + "onCharacteristicWrite " + getGattStatusMessage(status) + " " aapsLogger.debug(LTag.PUMPBTCOMM, ThreadUtil.sig() + "onCharacteristicWrite " + getGattStatusMessage(status) + " "
+ uuidString + " " + ByteUtil.shortHexString(characteristic.getValue())); + uuidString + " " + ByteUtil.shortHexString(characteristic.getValue()));
} }
mCurrentOperation.gattOperationCompletionCallback(characteristic.getUuid(), characteristic.getValue()); mCurrentOperation.gattOperationCompletionCallback(characteristic.getUuid(), characteristic.getValue());
@ -116,7 +120,7 @@ public class RileyLinkBLE {
// https://github.com/NordicSemiconductor/puck-central-android/blob/master/PuckCentral/app/src/main/java/no/nordicsemi/puckcentral/bluetooth/gatt/GattManager.java#L117 // https://github.com/NordicSemiconductor/puck-central-android/blob/master/PuckCentral/app/src/main/java/no/nordicsemi/puckcentral/bluetooth/gatt/GattManager.java#L117
if (status == 133) { if (status == 133) {
LOG.error("Got the status 133 bug, closing gatt"); aapsLogger.error(LTag.PUMPBTCOMM, "Got the status 133 bug, closing gatt");
disconnect(); disconnect();
SystemClock.sleep(500); SystemClock.sleep(500);
return; return;
@ -136,29 +140,27 @@ public class RileyLinkBLE {
stateMessage = "UNKNOWN newState (" + newState + ")"; stateMessage = "UNKNOWN newState (" + newState + ")";
} }
if (isLogEnabled()) aapsLogger.warn(LTag.PUMPBTCOMM, "onConnectionStateChange " + getGattStatusMessage(status) + " " + stateMessage);
LOG.warn("onConnectionStateChange " + getGattStatusMessage(status) + " " + stateMessage);
} }
if (newState == BluetoothProfile.STATE_CONNECTED) { if (newState == BluetoothProfile.STATE_CONNECTED) {
if (status == BluetoothGatt.GATT_SUCCESS) { if (status == BluetoothGatt.GATT_SUCCESS) {
RileyLinkUtil.sendBroadcastMessage(RileyLinkConst.Intents.BluetoothConnected); rileyLinkUtil.sendBroadcastMessage(RileyLinkConst.Intents.BluetoothConnected, context);
} else { } else {
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPBTCOMM, "BT State connected, GATT status {} ({})", status, getGattStatusMessage(status));
LOG.debug("BT State connected, GATT status {} ({})", status, getGattStatusMessage(status));
} }
} else if ((newState == BluetoothProfile.STATE_CONNECTING) || // } else if ((newState == BluetoothProfile.STATE_CONNECTING) || //
(newState == BluetoothProfile.STATE_DISCONNECTING)) { (newState == BluetoothProfile.STATE_DISCONNECTING)) {
// LOG.debug("We are in {} state.", status == BluetoothProfile.STATE_CONNECTING ? "Connecting" : // aapsLogger.debug(LTag.PUMPBTCOMM,"We are in {} state.", status == BluetoothProfile.STATE_CONNECTING ? "Connecting" :
// "Disconnecting"); // "Disconnecting");
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) { } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
RileyLinkUtil.sendBroadcastMessage(RileyLinkConst.Intents.RileyLinkDisconnected); rileyLinkUtil.sendBroadcastMessage(RileyLinkConst.Intents.RileyLinkDisconnected, context);
if (manualDisconnect) if (manualDisconnect)
close(); close();
LOG.warn("RileyLink Disconnected."); aapsLogger.warn(LTag.PUMPBTCOMM, "RileyLink Disconnected.");
} else { } else {
LOG.warn("Some other state: (status={},newState={})", status, newState); aapsLogger.warn(LTag.PUMPBTCOMM, "Some other state: (status={},newState={})", status, newState);
} }
} }
@ -166,8 +168,8 @@ public class RileyLinkBLE {
@Override @Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorWrite(gatt, descriptor, status); super.onDescriptorWrite(gatt, descriptor, status);
if (gattDebugEnabled && isLogEnabled()) { if (gattDebugEnabled) {
LOG.warn("onDescriptorWrite " + GattAttributes.lookup(descriptor.getUuid()) + " " aapsLogger.warn(LTag.PUMPBTCOMM, "onDescriptorWrite " + GattAttributes.lookup(descriptor.getUuid()) + " "
+ getGattStatusMessage(status) + " written: " + ByteUtil.getHex(descriptor.getValue())); + getGattStatusMessage(status) + " written: " + ByteUtil.getHex(descriptor.getValue()));
} }
mCurrentOperation.gattOperationCompletionCallback(descriptor.getUuid(), descriptor.getValue()); mCurrentOperation.gattOperationCompletionCallback(descriptor.getUuid(), descriptor.getValue());
@ -178,8 +180,8 @@ public class RileyLinkBLE {
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorRead(gatt, descriptor, status); super.onDescriptorRead(gatt, descriptor, status);
mCurrentOperation.gattOperationCompletionCallback(descriptor.getUuid(), descriptor.getValue()); mCurrentOperation.gattOperationCompletionCallback(descriptor.getUuid(), descriptor.getValue());
if (gattDebugEnabled && isLogEnabled()) { if (gattDebugEnabled) {
LOG.warn("onDescriptorRead " + getGattStatusMessage(status) + " status " + descriptor); aapsLogger.warn(LTag.PUMPBTCOMM, "onDescriptorRead " + getGattStatusMessage(status) + " status " + descriptor);
} }
} }
@ -187,8 +189,8 @@ public class RileyLinkBLE {
@Override @Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) { public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
super.onMtuChanged(gatt, mtu, status); super.onMtuChanged(gatt, mtu, status);
if (gattDebugEnabled && isLogEnabled()) { if (gattDebugEnabled) {
LOG.warn("onMtuChanged " + mtu + " status " + status); aapsLogger.warn(LTag.PUMPBTCOMM, "onMtuChanged " + mtu + " status " + status);
} }
} }
@ -196,8 +198,8 @@ public class RileyLinkBLE {
@Override @Override
public void onReadRemoteRssi(final BluetoothGatt gatt, int rssi, int status) { public void onReadRemoteRssi(final BluetoothGatt gatt, int rssi, int status) {
super.onReadRemoteRssi(gatt, rssi, status); super.onReadRemoteRssi(gatt, rssi, status);
if (gattDebugEnabled && isLogEnabled()) { if (gattDebugEnabled) {
LOG.warn("onReadRemoteRssi " + getGattStatusMessage(status) + ": " + rssi); aapsLogger.warn(LTag.PUMPBTCOMM, "onReadRemoteRssi " + getGattStatusMessage(status) + ": " + rssi);
} }
} }
@ -205,8 +207,8 @@ public class RileyLinkBLE {
@Override @Override
public void onReliableWriteCompleted(BluetoothGatt gatt, int status) { public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
super.onReliableWriteCompleted(gatt, status); super.onReliableWriteCompleted(gatt, status);
if (gattDebugEnabled && isLogEnabled()) { if (gattDebugEnabled) {
LOG.warn("onReliableWriteCompleted status " + status); aapsLogger.warn(LTag.PUMPBTCOMM, "onReliableWriteCompleted status " + status);
} }
} }
@ -232,27 +234,26 @@ public class RileyLinkBLE {
} }
} }
if (gattDebugEnabled && isLogEnabled()) { if (gattDebugEnabled) {
LOG.warn("onServicesDiscovered " + getGattStatusMessage(status)); aapsLogger.warn(LTag.PUMPBTCOMM, "onServicesDiscovered " + getGattStatusMessage(status));
} }
LOG.info("Gatt device is RileyLink device: " + rileyLinkFound); aapsLogger.info(LTag.PUMPBTCOMM, "Gatt device is RileyLink device: " + rileyLinkFound);
if (rileyLinkFound) { if (rileyLinkFound) {
mIsConnected = true; mIsConnected = true;
RileyLinkUtil.sendBroadcastMessage(RileyLinkConst.Intents.RileyLinkReady); rileyLinkUtil.sendBroadcastMessage(RileyLinkConst.Intents.RileyLinkReady, context);
// RileyLinkUtil.sendNotification(new // RileyLinkUtil.sendNotification(new
// ServiceNotification(RileyLinkConst.Intents.RileyLinkReady), null); // ServiceNotification(RileyLinkConst.Intents.RileyLinkReady), null);
} else { } else {
mIsConnected = false; mIsConnected = false;
RileyLinkUtil.setServiceState(RileyLinkServiceState.RileyLinkError, rileyLinkServiceData.setServiceState(RileyLinkServiceState.RileyLinkError,
RileyLinkError.DeviceIsNotRileyLink); RileyLinkError.DeviceIsNotRileyLink);
} }
} else { } else {
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPBTCOMM, "onServicesDiscovered " + getGattStatusMessage(status));
LOG.debug("onServicesDiscovered " + getGattStatusMessage(status)); rileyLinkUtil.sendBroadcastMessage(RileyLinkConst.Intents.RileyLinkGattFailed, context);
RileyLinkUtil.sendBroadcastMessage(RileyLinkConst.Intents.RileyLinkGattFailed);
} }
} }
}; };
@ -261,9 +262,7 @@ public class RileyLinkBLE {
private boolean isAnyRileyLinkServiceFound(BluetoothGattService service) { private boolean isAnyRileyLinkServiceFound(BluetoothGattService service) {
boolean found = false; boolean found = GattAttributes.isRileyLink(service.getUuid());
found = GattAttributes.isRileyLink(service.getUuid());
if (found) { if (found) {
return true; return true;
@ -313,7 +312,7 @@ public class RileyLinkBLE {
stringBuilder.append("\n\n"); stringBuilder.append("\n\n");
LOG.warn(stringBuilder.toString()); aapsLogger.warn(LTag.PUMPBTCOMM, stringBuilder.toString());
List<BluetoothGattService> includedServices = service.getIncludedServices(); List<BluetoothGattService> includedServices = service.getIncludedServices();
@ -324,7 +323,7 @@ public class RileyLinkBLE {
} }
public void registerRadioResponseCountNotification(Runnable notifier) { void registerRadioResponseCountNotification(Runnable notifier) {
radioResponseCountNotified = notifier; radioResponseCountNotified = notifier;
} }
@ -342,11 +341,10 @@ public class RileyLinkBLE {
} }
if (bluetoothConnectionGatt.discoverServices()) { if (bluetoothConnectionGatt.discoverServices()) {
if (isLogEnabled()) aapsLogger.warn(LTag.PUMPBTCOMM, "Starting to discover GATT Services.");
LOG.warn("Starting to discover GATT Services.");
return true; return true;
} else { } else {
LOG.error("Cannot discover GATT Services."); aapsLogger.error(LTag.PUMPBTCOMM, "Cannot discover GATT Services.");
return false; return false;
} }
} }
@ -356,7 +354,7 @@ public class RileyLinkBLE {
BLECommOperationResult result = setNotification_blocking(UUID.fromString(GattAttributes.SERVICE_RADIO), // BLECommOperationResult result = setNotification_blocking(UUID.fromString(GattAttributes.SERVICE_RADIO), //
UUID.fromString(GattAttributes.CHARA_RADIO_RESPONSE_COUNT)); UUID.fromString(GattAttributes.CHARA_RADIO_RESPONSE_COUNT));
if (result.resultCode != BLECommOperationResult.RESULT_SUCCESS) { if (result.resultCode != BLECommOperationResult.RESULT_SUCCESS) {
LOG.error("Error setting response count notification"); aapsLogger.error(LTag.PUMPBTCOMM, "Error setting response count notification");
return false; return false;
} }
return true; return true;
@ -364,36 +362,34 @@ public class RileyLinkBLE {
public void findRileyLink(String RileyLinkAddress) { public void findRileyLink(String RileyLinkAddress) {
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPBTCOMM, "RileyLink address: " + RileyLinkAddress);
LOG.debug("RileyLink address: " + RileyLinkAddress);
// Must verify that this is a valid MAC, or crash. // Must verify that this is a valid MAC, or crash.
rileyLinkDevice = bluetoothAdapter.getRemoteDevice(RileyLinkAddress); rileyLinkDevice = bluetoothAdapter.getRemoteDevice(RileyLinkAddress);
// if this succeeds, we get a connection state change callback? // if this succeeds, we get a connection state change callback?
if (rileyLinkDevice!=null) { if (rileyLinkDevice != null) {
connectGatt(); connectGatt();
} else { } else {
LOG.error("RileyLink device not found with address: " + RileyLinkAddress); aapsLogger.error(LTag.PUMPBTCOMM, "RileyLink device not found with address: " + RileyLinkAddress);
} }
} }
// This function must be run on UI thread. // This function must be run on UI thread.
public void connectGatt() { public void connectGatt() {
if (this.rileyLinkDevice==null) { if (this.rileyLinkDevice == null) {
LOG.error("RileyLink device is null, can't do connectGatt."); aapsLogger.error(LTag.PUMPBTCOMM, "RileyLink device is null, can't do connectGatt.");
return; return;
} }
bluetoothConnectionGatt = rileyLinkDevice.connectGatt(context, true, bluetoothGattCallback); bluetoothConnectionGatt = rileyLinkDevice.connectGatt(context, true, bluetoothGattCallback);
// , BluetoothDevice.TRANSPORT_LE // , BluetoothDevice.TRANSPORT_LE
if (bluetoothConnectionGatt == null) { if (bluetoothConnectionGatt == null) {
LOG.error("Failed to connect to Bluetooth Low Energy device at " + bluetoothAdapter.getAddress()); aapsLogger.error(LTag.PUMPBTCOMM, "Failed to connect to Bluetooth Low Energy device at " + bluetoothAdapter.getAddress());
} else { } else {
if (gattDebugEnabled) { if (gattDebugEnabled) {
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPBTCOMM, "Gatt Connected.");
LOG.debug("Gatt Connected.");
} }
} }
} }
@ -401,8 +397,7 @@ public class RileyLinkBLE {
public void disconnect() { public void disconnect() {
mIsConnected = false; mIsConnected = false;
if (isLogEnabled()) aapsLogger.warn(LTag.PUMPBTCOMM, "Closing GATT connection");
LOG.warn("Closing GATT connection");
// Close old conenction // Close old conenction
if (bluetoothConnectionGatt != null) { if (bluetoothConnectionGatt != null) {
// Not sure if to disconnect or to close first.. // Not sure if to disconnect or to close first..
@ -420,7 +415,7 @@ public class RileyLinkBLE {
} }
public BLECommOperationResult setNotification_blocking(UUID serviceUUID, UUID charaUUID) { private BLECommOperationResult setNotification_blocking(UUID serviceUUID, UUID charaUUID) {
BLECommOperationResult rval = new BLECommOperationResult(); BLECommOperationResult rval = new BLECommOperationResult();
if (bluetoothConnectionGatt != null) { if (bluetoothConnectionGatt != null) {
@ -428,7 +423,7 @@ public class RileyLinkBLE {
gattOperationSema.acquire(); gattOperationSema.acquire();
SystemClock.sleep(1); // attempting to yield thread, to make sequence of events easier to follow SystemClock.sleep(1); // attempting to yield thread, to make sequence of events easier to follow
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOG.error("setNotification_blocking: interrupted waiting for gattOperationSema"); aapsLogger.error(LTag.PUMPBTCOMM, "setNotification_blocking: interrupted waiting for gattOperationSema");
return rval; return rval;
} }
if (mCurrentOperation != null) { if (mCurrentOperation != null) {
@ -437,7 +432,7 @@ public class RileyLinkBLE {
if (bluetoothConnectionGatt.getService(serviceUUID) == null) { if (bluetoothConnectionGatt.getService(serviceUUID) == null) {
// Catch if the service is not supported by the BLE device // Catch if the service is not supported by the BLE device
rval.resultCode = BLECommOperationResult.RESULT_NONE; rval.resultCode = BLECommOperationResult.RESULT_NONE;
LOG.error("BT Device not supported"); aapsLogger.error(LTag.PUMPBTCOMM, "BT Device not supported");
// TODO: 11/07/2016 UI update for user // TODO: 11/07/2016 UI update for user
} else { } else {
BluetoothGattCharacteristic chara = bluetoothConnectionGatt.getService(serviceUUID) BluetoothGattCharacteristic chara = bluetoothConnectionGatt.getService(serviceUUID)
@ -447,13 +442,12 @@ public class RileyLinkBLE {
List<BluetoothGattDescriptor> list = chara.getDescriptors(); List<BluetoothGattDescriptor> list = chara.getDescriptors();
if (gattDebugEnabled) { if (gattDebugEnabled) {
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPBTCOMM, "Found descriptor: " + list.get(i).toString());
LOG.debug("Found descriptor: " + list.get(i).toString());
} }
} }
BluetoothGattDescriptor descr = list.get(0); BluetoothGattDescriptor descr = list.get(0);
// Tell the remote device to send the notifications // Tell the remote device to send the notifications
mCurrentOperation = new DescriptorWriteOperation(bluetoothConnectionGatt, descr, mCurrentOperation = new DescriptorWriteOperation(aapsLogger, bluetoothConnectionGatt, descr,
BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mCurrentOperation.execute(this); mCurrentOperation.execute(this);
if (mCurrentOperation.timedOut) { if (mCurrentOperation.timedOut) {
@ -468,7 +462,7 @@ public class RileyLinkBLE {
gattOperationSema.release(); gattOperationSema.release();
} }
} else { } else {
LOG.error("setNotification_blocking: not configured!"); aapsLogger.error(LTag.PUMPBTCOMM, "setNotification_blocking: not configured!");
rval.resultCode = BLECommOperationResult.RESULT_NOT_CONFIGURED; rval.resultCode = BLECommOperationResult.RESULT_NOT_CONFIGURED;
} }
return rval; return rval;
@ -476,7 +470,7 @@ public class RileyLinkBLE {
// call from main // call from main
public BLECommOperationResult writeCharacteristic_blocking(UUID serviceUUID, UUID charaUUID, byte[] value) { BLECommOperationResult writeCharacteristic_blocking(UUID serviceUUID, UUID charaUUID, byte[] value) {
BLECommOperationResult rval = new BLECommOperationResult(); BLECommOperationResult rval = new BLECommOperationResult();
if (bluetoothConnectionGatt != null) { if (bluetoothConnectionGatt != null) {
rval.value = value; rval.value = value;
@ -484,7 +478,7 @@ public class RileyLinkBLE {
gattOperationSema.acquire(); gattOperationSema.acquire();
SystemClock.sleep(1); // attempting to yield thread, to make sequence of events easier to follow SystemClock.sleep(1); // attempting to yield thread, to make sequence of events easier to follow
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOG.error("writeCharacteristic_blocking: interrupted waiting for gattOperationSema"); aapsLogger.error(LTag.PUMPBTCOMM, "writeCharacteristic_blocking: interrupted waiting for gattOperationSema");
return rval; return rval;
} }
@ -497,12 +491,12 @@ public class RileyLinkBLE {
// app that created the bluetoothConnectionGatt has been destroyed/created, // app that created the bluetoothConnectionGatt has been destroyed/created,
// e.g. when the user switches from portrait to landscape. // e.g. when the user switches from portrait to landscape.
rval.resultCode = BLECommOperationResult.RESULT_NONE; rval.resultCode = BLECommOperationResult.RESULT_NONE;
LOG.error("BT Device not supported"); aapsLogger.error(LTag.PUMPBTCOMM, "BT Device not supported");
// TODO: 11/07/2016 UI update for user // TODO: 11/07/2016 UI update for user
} else { } else {
BluetoothGattCharacteristic chara = bluetoothConnectionGatt.getService(serviceUUID) BluetoothGattCharacteristic chara = bluetoothConnectionGatt.getService(serviceUUID)
.getCharacteristic(charaUUID); .getCharacteristic(charaUUID);
mCurrentOperation = new CharacteristicWriteOperation(bluetoothConnectionGatt, chara, value); mCurrentOperation = new CharacteristicWriteOperation(aapsLogger, bluetoothConnectionGatt, chara, value);
mCurrentOperation.execute(this); mCurrentOperation.execute(this);
if (mCurrentOperation.timedOut) { if (mCurrentOperation.timedOut) {
rval.resultCode = BLECommOperationResult.RESULT_TIMEOUT; rval.resultCode = BLECommOperationResult.RESULT_TIMEOUT;
@ -516,21 +510,21 @@ public class RileyLinkBLE {
gattOperationSema.release(); gattOperationSema.release();
} }
} else { } else {
LOG.error("writeCharacteristic_blocking: not configured!"); aapsLogger.error(LTag.PUMPBTCOMM, "writeCharacteristic_blocking: not configured!");
rval.resultCode = BLECommOperationResult.RESULT_NOT_CONFIGURED; rval.resultCode = BLECommOperationResult.RESULT_NOT_CONFIGURED;
} }
return rval; return rval;
} }
public BLECommOperationResult readCharacteristic_blocking(UUID serviceUUID, UUID charaUUID) { BLECommOperationResult readCharacteristic_blocking(UUID serviceUUID, UUID charaUUID) {
BLECommOperationResult rval = new BLECommOperationResult(); BLECommOperationResult rval = new BLECommOperationResult();
if (bluetoothConnectionGatt != null) { if (bluetoothConnectionGatt != null) {
try { try {
gattOperationSema.acquire(); gattOperationSema.acquire();
SystemClock.sleep(1); // attempting to yield thread, to make sequence of events easier to follow SystemClock.sleep(1); // attempting to yield thread, to make sequence of events easier to follow
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOG.error("readCharacteristic_blocking: Interrupted waiting for gattOperationSema"); aapsLogger.error(LTag.PUMPBTCOMM, "readCharacteristic_blocking: Interrupted waiting for gattOperationSema");
return rval; return rval;
} }
if (mCurrentOperation != null) { if (mCurrentOperation != null) {
@ -539,12 +533,12 @@ public class RileyLinkBLE {
if (bluetoothConnectionGatt.getService(serviceUUID) == null) { if (bluetoothConnectionGatt.getService(serviceUUID) == null) {
// Catch if the service is not supported by the BLE device // Catch if the service is not supported by the BLE device
rval.resultCode = BLECommOperationResult.RESULT_NONE; rval.resultCode = BLECommOperationResult.RESULT_NONE;
LOG.error("BT Device not supported"); aapsLogger.error(LTag.PUMPBTCOMM, "BT Device not supported");
// TODO: 11/07/2016 UI update for user // TODO: 11/07/2016 UI update for user
} else { } else {
BluetoothGattCharacteristic chara = bluetoothConnectionGatt.getService(serviceUUID).getCharacteristic( BluetoothGattCharacteristic chara = bluetoothConnectionGatt.getService(serviceUUID).getCharacteristic(
charaUUID); charaUUID);
mCurrentOperation = new CharacteristicReadOperation(bluetoothConnectionGatt, chara); mCurrentOperation = new CharacteristicReadOperation(aapsLogger, bluetoothConnectionGatt, chara);
mCurrentOperation.execute(this); mCurrentOperation.execute(this);
if (mCurrentOperation.timedOut) { if (mCurrentOperation.timedOut) {
rval.resultCode = BLECommOperationResult.RESULT_TIMEOUT; rval.resultCode = BLECommOperationResult.RESULT_TIMEOUT;
@ -559,7 +553,7 @@ public class RileyLinkBLE {
mCurrentOperation = null; mCurrentOperation = null;
gattOperationSema.release(); gattOperationSema.release();
} else { } else {
LOG.error("readCharacteristic_blocking: not configured!"); aapsLogger.error(LTag.PUMPBTCOMM, "readCharacteristic_blocking: not configured!");
rval.resultCode = BLECommOperationResult.RESULT_NOT_CONFIGURED; rval.resultCode = BLECommOperationResult.RESULT_NOT_CONFIGURED;
} }
return rval; return rval;
@ -582,9 +576,4 @@ public class RileyLinkBLE {
return statusMessage; return statusMessage;
} }
private boolean isLogEnabled() {
return L.isEnabled(L.PUMPBTCOMM);
}
} }

View file

@ -27,4 +27,7 @@ public class RileyLinkCommunicationException extends Exception {
// this.extendedErrorText = extendedErrorText; // this.extendedErrorText = extendedErrorText;
} }
public RileyLinkBLEError getErrorCode() {
return errorCode;
}
} }

View file

@ -3,14 +3,20 @@ package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.command;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import javax.inject.Inject;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RadioPacket; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RadioPacket;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkCommandType; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkCommandType;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkFirmwareVersion; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkFirmwareVersion;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData;
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
public class SendAndListen extends RileyLinkCommand { public class SendAndListen extends RileyLinkCommand {
@Inject RileyLinkServiceData rileyLinkServiceData;
private byte sendChannel; private byte sendChannel;
private byte repeatCount; private byte repeatCount;
private int delayBetweenPackets_ms; private int delayBetweenPackets_ms;
@ -21,20 +27,21 @@ public class SendAndListen extends RileyLinkCommand {
private RadioPacket packetToSend; private RadioPacket packetToSend;
public SendAndListen(byte sendChannel, byte repeatCount, byte delayBetweenPackets_ms, byte listenChannel, public SendAndListen(HasAndroidInjector injector, byte sendChannel, byte repeatCount, byte delayBetweenPackets_ms, byte listenChannel,
int timeout_ms, byte retryCount, RadioPacket packetToSend int timeout_ms, byte retryCount, RadioPacket packetToSend
) { ) {
this(sendChannel, repeatCount, delayBetweenPackets_ms, listenChannel, timeout_ms, retryCount, null, this(injector, sendChannel, repeatCount, delayBetweenPackets_ms, listenChannel, timeout_ms, retryCount, null,
packetToSend); packetToSend);
} }
public SendAndListen(byte sendChannel, byte repeatCount, int delayBetweenPackets_ms, byte listenChannel, public SendAndListen(HasAndroidInjector injector, byte sendChannel, byte repeatCount, int delayBetweenPackets_ms, byte listenChannel,
int timeout_ms, byte retryCount, Integer preambleExtension_ms, RadioPacket packetToSend int timeout_ms, byte retryCount, Integer preambleExtension_ms, RadioPacket packetToSend
) { ) {
super(); super();
injector.androidInjector().inject(this);
this.sendChannel = sendChannel; this.sendChannel = sendChannel;
this.repeatCount = repeatCount; this.repeatCount = repeatCount;
this.delayBetweenPackets_ms = delayBetweenPackets_ms; this.delayBetweenPackets_ms = delayBetweenPackets_ms;
@ -57,8 +64,8 @@ public class SendAndListen extends RileyLinkCommand {
// If firmware version is not set (error reading version from device, shouldn't happen), // If firmware version is not set (error reading version from device, shouldn't happen),
// we will default to version 2 // we will default to version 2
boolean isPacketV2 = RileyLinkUtil.getFirmwareVersion() != null ? RileyLinkUtil.getFirmwareVersion() boolean isPacketV2 = rileyLinkServiceData.firmwareVersion == null || rileyLinkServiceData.firmwareVersion
.isSameVersion(RileyLinkFirmwareVersion.Version2AndHigher) : true; .isSameVersion(RileyLinkFirmwareVersion.Version2AndHigher);
ArrayList<Byte> bytes = new ArrayList<Byte>(); ArrayList<Byte> bytes = new ArrayList<Byte>();
bytes.add(this.getCommandType().code); bytes.add(this.getCommandType().code);

View file

@ -4,20 +4,26 @@ import java.nio.ByteBuffer;
import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.NotImplementedException;
import javax.inject.Inject;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkCommandType; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkCommandType;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkFirmwareVersion; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkFirmwareVersion;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData;
public class SetPreamble extends RileyLinkCommand { public class SetPreamble extends RileyLinkCommand {
@Inject RileyLinkServiceData rileyLinkServiceData;
private int preamble; private int preamble;
public SetPreamble(int preamble) throws Exception { public SetPreamble(HasAndroidInjector injector, int preamble) throws Exception {
super(); super();
// this command was not supported before 2.0 // this command was not supported before 2.0
if (!RileyLinkUtil.getFirmwareVersion().isSameVersion(RileyLinkFirmwareVersion.Version2AndHigher)) { if (!rileyLinkServiceData.firmwareVersion.isSameVersion(RileyLinkFirmwareVersion.Version2AndHigher)) {
throw new NotImplementedException("Old firmware does not support SetPreamble command"); throw new NotImplementedException("Old firmware does not support SetPreamble command");
} }

View file

@ -1,5 +1,6 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data; package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkCommunicationException; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkCommunicationException;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.command.RileyLinkCommand; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.command.RileyLinkCommand;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RFSpyRLResponse; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RFSpyRLResponse;
@ -48,12 +49,12 @@ public class RFSpyResponse {
} }
public RadioResponse getRadioResponse() throws RileyLinkCommunicationException { public RadioResponse getRadioResponse(HasAndroidInjector injector) throws RileyLinkCommunicationException {
if (looksLikeRadioPacket()) { if (looksLikeRadioPacket()) {
radioResponse = new RadioResponse(command); radioResponse = new RadioResponse(injector, command);
radioResponse.init(raw); radioResponse.init(raw);
} else { } else {
radioResponse = new RadioResponse(); radioResponse = new RadioResponse(injector);
} }
return radioResponse; return radioResponse;
} }

View file

@ -2,6 +2,9 @@ package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data;
import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.NotImplementedException;
import javax.inject.Inject;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
import info.nightscout.androidaps.plugins.pump.common.utils.CRC; import info.nightscout.androidaps.plugins.pump.common.utils.CRC;
@ -12,10 +15,13 @@ import info.nightscout.androidaps.plugins.pump.common.utils.CRC;
public class RadioPacket { public class RadioPacket {
protected byte[] pkt; @Inject RileyLinkUtil rileyLinkUtil;
private byte[] pkt;
public RadioPacket(byte[] pkt) { public RadioPacket(HasAndroidInjector injector, byte[] pkt) {
injector.androidInjector().inject(this);
this.pkt = pkt; this.pkt = pkt;
} }
@ -25,7 +31,7 @@ public class RadioPacket {
} }
public byte[] getWithCRC() { private byte[] getWithCRC() {
byte[] withCRC = ByteUtil.concat(pkt, CRC.crc8(pkt)); byte[] withCRC = ByteUtil.concat(pkt, CRC.crc8(pkt));
return withCRC; return withCRC;
} }
@ -33,7 +39,7 @@ public class RadioPacket {
public byte[] getEncoded() { public byte[] getEncoded() {
switch (RileyLinkUtil.getEncoding()) { switch (rileyLinkUtil.getEncoding()) {
case Manchester: { // We have this encoding in RL firmware case Manchester: { // We have this encoding in RL firmware
return pkt; return pkt;
} }
@ -41,8 +47,8 @@ public class RadioPacket {
case FourByteSixByteLocal: { case FourByteSixByteLocal: {
byte[] withCRC = getWithCRC(); byte[] withCRC = getWithCRC();
byte[] encoded = RileyLinkUtil.getEncoding4b6b().encode4b6b(withCRC); byte[] encoded = rileyLinkUtil.getEncoding4b6b().encode4b6b(withCRC);
return ByteUtil.concat(encoded, (byte)0); return ByteUtil.concat(encoded, (byte) 0);
} }
case FourByteSixByteRileyLink: { case FourByteSixByteRileyLink: {
@ -50,8 +56,7 @@ public class RadioPacket {
} }
default: default:
throw new NotImplementedException(("Encoding not supported: " + RileyLinkUtil.getEncoding().toString())); throw new NotImplementedException(("Encoding not supported: " + rileyLinkUtil.getEncoding().toString()));
} }
} }
} }

View file

@ -1,17 +1,19 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data; package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data;
import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.NotImplementedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.logging.L; import javax.inject.Inject;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkCommunicationException; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkCommunicationException;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.command.RileyLinkCommand; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.command.RileyLinkCommand;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkBLEError; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkBLEError;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkCommandType; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkCommandType;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkFirmwareVersion; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkFirmwareVersion;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData;
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
import info.nightscout.androidaps.plugins.pump.common.utils.CRC; import info.nightscout.androidaps.plugins.pump.common.utils.CRC;
@ -20,26 +22,25 @@ import info.nightscout.androidaps.plugins.pump.common.utils.CRC;
*/ */
public class RadioResponse { public class RadioResponse {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPBTCOMM);
public boolean decodedOK = false; @Inject AAPSLogger aapsLogger;
@Inject RileyLinkServiceData rileyLinkServiceData;
@Inject RileyLinkUtil rileyLinkUtil;
private boolean decodedOK = false;
public int rssi; public int rssi;
public int responseNumber; private int responseNumber;
public byte[] decodedPayload = new byte[0]; private byte[] decodedPayload = new byte[0];
public byte receivedCRC; private byte receivedCRC;
private RileyLinkCommand command; private RileyLinkCommand command;
public RadioResponse() { public RadioResponse(HasAndroidInjector injector) {
injector.androidInjector().inject(this);
} }
public RadioResponse(HasAndroidInjector injector, RileyLinkCommand command /* , byte[] raw */) {
// public RadioResponse(byte[] rxData) { this(injector);
// init(rxData);
// }
public RadioResponse(RileyLinkCommand command /* , byte[] raw */) {
this.command = command; this.command = command;
// init(raw); // init(raw);
} }
@ -75,8 +76,8 @@ public class RadioResponse {
} }
byte[] encodedPayload; byte[] encodedPayload;
if (RileyLinkFirmwareVersion.isSameVersion(RileyLinkUtil.getRileyLinkServiceData().versionCC110, if (RileyLinkFirmwareVersion.isSameVersion(rileyLinkServiceData.versionCC110,
RileyLinkFirmwareVersion.Version2)) { RileyLinkFirmwareVersion.Version2)) {
encodedPayload = ByteUtil.substring(rxData, 3, rxData.length - 3); encodedPayload = ByteUtil.substring(rxData, 3, rxData.length - 3);
rssi = rxData[1]; rssi = rxData[1];
responseNumber = rxData[2]; responseNumber = rxData[2];
@ -92,23 +93,23 @@ public class RadioResponse {
// well, for non-radio commands we shouldn't even reach this point // well, for non-radio commands we shouldn't even reach this point
// but getVersion is kind of exception // but getVersion is kind of exception
if (command != null && // if (command != null && //
command.getCommandType() != RileyLinkCommandType.SendAndListen) { command.getCommandType() != RileyLinkCommandType.SendAndListen) {
decodedOK = true; decodedOK = true;
decodedPayload = encodedPayload; decodedPayload = encodedPayload;
return; return;
} }
switch (RileyLinkUtil.getEncoding()) { switch (rileyLinkUtil.getEncoding()) {
case Manchester: case Manchester:
case FourByteSixByteRileyLink: { case FourByteSixByteRileyLink: {
decodedOK = true; decodedOK = true;
decodedPayload = encodedPayload; decodedPayload = encodedPayload;
} }
break; break;
case FourByteSixByteLocal: { case FourByteSixByteLocal: {
byte[] decodeThis = RileyLinkUtil.getEncoding4b6b().decode4b6b(encodedPayload); byte[] decodeThis = rileyLinkUtil.getEncoding4b6b().decode4b6b(encodedPayload);
if (decodeThis != null && decodeThis.length > 2) { if (decodeThis != null && decodeThis.length > 2) {
decodedOK = true; decodedOK = true;
@ -117,22 +118,22 @@ public class RadioResponse {
receivedCRC = decodeThis[decodeThis.length - 1]; receivedCRC = decodeThis[decodeThis.length - 1];
byte calculatedCRC = CRC.crc8(decodedPayload); byte calculatedCRC = CRC.crc8(decodedPayload);
if (receivedCRC != calculatedCRC) { if (receivedCRC != calculatedCRC) {
LOG.error(String.format("RadioResponse: CRC mismatch, calculated 0x%02x, received 0x%02x", aapsLogger.error(LTag.PUMPCOMM, String.format("RadioResponse: CRC mismatch, calculated 0x%02x, received 0x%02x",
calculatedCRC, receivedCRC)); calculatedCRC, receivedCRC));
} }
} else { } else {
throw new RileyLinkCommunicationException(RileyLinkBLEError.TooShortOrNullResponse); throw new RileyLinkCommunicationException(RileyLinkBLEError.TooShortOrNullResponse);
} }
} }
break; break;
default: default:
throw new NotImplementedException("this {" + RileyLinkUtil.getEncoding().toString() throw new NotImplementedException("this {" + rileyLinkUtil.getEncoding().toString()
+ "} encoding is not supported"); + "} encoding is not supported");
} }
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
decodedOK = false; decodedOK = false;
LOG.error("Failed to decode radio data: " + ByteUtil.shortHexString(encodedPayload)); aapsLogger.error(LTag.PUMPBTCOMM, "Failed to decode radio data: " + ByteUtil.shortHexString(encodedPayload));
} }
} }

View file

@ -1,17 +1,14 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations; package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattCharacteristic;
import android.os.SystemClock; import android.os.SystemClock;
import info.nightscout.androidaps.logging.L; import java.util.UUID;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; import java.util.concurrent.TimeUnit;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkBLE; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkBLE;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes;
@ -20,12 +17,13 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.Gatt
*/ */
public class CharacteristicReadOperation extends BLECommOperation { public class CharacteristicReadOperation extends BLECommOperation {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPBTCOMM); private final AAPSLogger aapsLogger;
private BluetoothGattCharacteristic characteristic; private BluetoothGattCharacteristic characteristic;
public CharacteristicReadOperation(BluetoothGatt gatt, BluetoothGattCharacteristic chara) { public CharacteristicReadOperation(AAPSLogger aapsLogger, BluetoothGatt gatt, BluetoothGattCharacteristic chara) {
this.aapsLogger = aapsLogger;
this.gatt = gatt; this.gatt = gatt;
this.characteristic = chara; this.characteristic = chara;
} }
@ -39,15 +37,14 @@ public class CharacteristicReadOperation extends BLECommOperation {
boolean didAcquire = operationComplete.tryAcquire(getGattOperationTimeout_ms(), TimeUnit.MILLISECONDS); boolean didAcquire = operationComplete.tryAcquire(getGattOperationTimeout_ms(), TimeUnit.MILLISECONDS);
if (didAcquire) { if (didAcquire) {
SystemClock.sleep(1); // This is to allow the IBinder thread to exit before we continue, allowing easier SystemClock.sleep(1); // This is to allow the IBinder thread to exit before we continue, allowing easier
// understanding of the sequence of events. // understanding of the sequence of events.
// success // success
} else { } else {
LOG.error("Timeout waiting for gatt write operation to complete"); aapsLogger.error(LTag.PUMPBTCOMM, "Timeout waiting for gatt write operation to complete");
timedOut = true; timedOut = true;
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
if (isLogEnabled()) aapsLogger.error(LTag.PUMPBTCOMM, "Interrupted while waiting for gatt write operation to complete");
LOG.error("Interrupted while waiting for gatt write operation to complete");
interrupted = true; interrupted = true;
} }
value = characteristic.getValue(); value = characteristic.getValue();
@ -58,15 +55,10 @@ public class CharacteristicReadOperation extends BLECommOperation {
public void gattOperationCompletionCallback(UUID uuid, byte[] value) { public void gattOperationCompletionCallback(UUID uuid, byte[] value) {
super.gattOperationCompletionCallback(uuid, value); super.gattOperationCompletionCallback(uuid, value);
if (!characteristic.getUuid().equals(uuid)) { if (!characteristic.getUuid().equals(uuid)) {
LOG.error(String.format( aapsLogger.error(LTag.PUMPCOMM, String.format(
"Completion callback: UUID does not match! out of sequence? Found: %s, should be %s", "Completion callback: UUID does not match! out of sequence? Found: %s, should be %s",
GattAttributes.lookup(characteristic.getUuid()), GattAttributes.lookup(uuid))); GattAttributes.lookup(characteristic.getUuid()), GattAttributes.lookup(uuid)));
} }
operationComplete.release(); operationComplete.release();
} }
private boolean isLogEnabled() {
return L.isEnabled(L.PUMPBTCOMM);
}
} }

View file

@ -1,17 +1,14 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations; package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattCharacteristic;
import android.os.SystemClock; import android.os.SystemClock;
import info.nightscout.androidaps.logging.L; import java.util.UUID;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; import java.util.concurrent.TimeUnit;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkBLE; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkBLE;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes;
@ -20,12 +17,13 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.Gatt
*/ */
public class CharacteristicWriteOperation extends BLECommOperation { public class CharacteristicWriteOperation extends BLECommOperation {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPBTCOMM); private final AAPSLogger aapsLogger;
private BluetoothGattCharacteristic characteristic; private BluetoothGattCharacteristic characteristic;
public CharacteristicWriteOperation(BluetoothGatt gatt, BluetoothGattCharacteristic chara, byte[] value) { public CharacteristicWriteOperation(AAPSLogger aapsLogger, BluetoothGatt gatt, BluetoothGattCharacteristic chara, byte[] value) {
this.aapsLogger = aapsLogger;
this.gatt = gatt; this.gatt = gatt;
this.characteristic = chara; this.characteristic = chara;
this.value = value; this.value = value;
@ -42,14 +40,14 @@ public class CharacteristicWriteOperation extends BLECommOperation {
boolean didAcquire = operationComplete.tryAcquire(getGattOperationTimeout_ms(), TimeUnit.MILLISECONDS); boolean didAcquire = operationComplete.tryAcquire(getGattOperationTimeout_ms(), TimeUnit.MILLISECONDS);
if (didAcquire) { if (didAcquire) {
SystemClock.sleep(1); // This is to allow the IBinder thread to exit before we continue, allowing easier SystemClock.sleep(1); // This is to allow the IBinder thread to exit before we continue, allowing easier
// understanding of the sequence of events. // understanding of the sequence of events.
// success // success
} else { } else {
LOG.error("Timeout waiting for gatt write operation to complete"); aapsLogger.error(LTag.PUMPBTCOMM, "Timeout waiting for gatt write operation to complete");
timedOut = true; timedOut = true;
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOG.error("Interrupted while waiting for gatt write operation to complete"); aapsLogger.error(LTag.PUMPBTCOMM, "Interrupted while waiting for gatt write operation to complete");
interrupted = true; interrupted = true;
} }
@ -60,16 +58,10 @@ public class CharacteristicWriteOperation extends BLECommOperation {
@Override @Override
public void gattOperationCompletionCallback(UUID uuid, byte[] value) { public void gattOperationCompletionCallback(UUID uuid, byte[] value) {
if (!characteristic.getUuid().equals(uuid)) { if (!characteristic.getUuid().equals(uuid)) {
LOG.error(String.format( aapsLogger.error(LTag.PUMPCOMM, String.format(
"Completion callback: UUID does not match! out of sequence? Found: %s, should be %s", "Completion callback: UUID does not match! out of sequence? Found: %s, should be %s",
GattAttributes.lookup(characteristic.getUuid()), GattAttributes.lookup(uuid))); GattAttributes.lookup(characteristic.getUuid()), GattAttributes.lookup(uuid)));
} }
operationComplete.release(); operationComplete.release();
} }
private boolean isLogEnabled() {
return L.isEnabled(L.PUMPBTCOMM);
}
} }

View file

@ -1,16 +1,14 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations; package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattDescriptor; import android.bluetooth.BluetoothGattDescriptor;
import android.os.SystemClock; import android.os.SystemClock;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; import java.util.UUID;
import java.util.concurrent.TimeUnit;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkBLE; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkBLE;
/** /**
@ -18,12 +16,13 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLink
*/ */
public class DescriptorWriteOperation extends BLECommOperation { public class DescriptorWriteOperation extends BLECommOperation {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(DescriptorWriteOperation.class); private final AAPSLogger aapsLogger;
private BluetoothGattDescriptor descr; private BluetoothGattDescriptor descr;
public DescriptorWriteOperation(BluetoothGatt gatt, BluetoothGattDescriptor descr, byte[] value) { public DescriptorWriteOperation(AAPSLogger aapsLogger, BluetoothGatt gatt, BluetoothGattDescriptor descr, byte[] value) {
this.aapsLogger = aapsLogger;
this.gatt = gatt; this.gatt = gatt;
this.descr = descr; this.descr = descr;
this.value = value; this.value = value;
@ -46,14 +45,14 @@ public class DescriptorWriteOperation extends BLECommOperation {
boolean didAcquire = operationComplete.tryAcquire(getGattOperationTimeout_ms(), TimeUnit.MILLISECONDS); boolean didAcquire = operationComplete.tryAcquire(getGattOperationTimeout_ms(), TimeUnit.MILLISECONDS);
if (didAcquire) { if (didAcquire) {
SystemClock.sleep(1); // This is to allow the IBinder thread to exit before we continue, allowing easier SystemClock.sleep(1); // This is to allow the IBinder thread to exit before we continue, allowing easier
// understanding of the sequence of events. // understanding of the sequence of events.
// success // success
} else { } else {
LOG.error("Timeout waiting for descriptor write operation to complete"); aapsLogger.error(LTag.PUMPBTCOMM, "Timeout waiting for descriptor write operation to complete");
timedOut = true; timedOut = true;
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOG.error("Interrupted while waiting for descriptor write operation to complete"); aapsLogger.error(LTag.PUMPBTCOMM, "Interrupted while waiting for descriptor write operation to complete");
interrupted = true; interrupted = true;
} }
} }

View file

@ -2,12 +2,12 @@ package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data;
import org.joda.time.LocalDateTime; import org.joda.time.LocalDateTime;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice;
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType; import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType;
import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState; import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
/** /**
* Created by andy on 5/19/18. * Created by andy on 5/19/18.
@ -26,7 +26,7 @@ public class RLHistoryItem {
public RLHistoryItem(RileyLinkServiceState serviceState, RileyLinkError errorCode, public RLHistoryItem(RileyLinkServiceState serviceState, RileyLinkError errorCode,
RileyLinkTargetDevice targetDevice) { RileyLinkTargetDevice targetDevice) {
this.targetDevice = targetDevice; this.targetDevice = targetDevice;
this.dateTime = new LocalDateTime(); this.dateTime = new LocalDateTime();
this.serviceState = serviceState; this.serviceState = serviceState;
@ -65,16 +65,16 @@ public class RLHistoryItem {
} }
public String getDescription() { public String getDescription(ResourceHelper resourceHelper) {
// TODO extend when we have Omnipod // TODO extend when we have Omnipod
switch (this.source) { switch (this.source) {
case RileyLink: case RileyLink:
return "State: " + MainApp.gs(serviceState.getResourceId(targetDevice)) return "State: " + resourceHelper.gs(serviceState.getResourceId(targetDevice))
+ (this.errorCode == null ? "" : ", Error Code: " + errorCode); + (this.errorCode == null ? "" : ", Error Code: " + errorCode);
case MedtronicPump: case MedtronicPump:
return MainApp.gs(pumpDeviceState.getResourceId()); return resourceHelper.gs(pumpDeviceState.getResourceId());
case MedtronicCommand: case MedtronicCommand:
return medtronicCommandType.name(); return medtronicCommandType.name();
@ -97,7 +97,8 @@ public class RLHistoryItem {
public enum RLHistoryItemSource { public enum RLHistoryItemSource {
RileyLink("RileyLink"), // RileyLink("RileyLink"), //
MedtronicPump("Medtronic"), // MedtronicPump("Medtronic"), //
MedtronicCommand("Medtronic"); MedtronicCommand("Medtronic"), //
OmnipodCommand("Omnipod");
private String desc; private String desc;
@ -112,4 +113,12 @@ public class RLHistoryItem {
} }
} }
public static class Comparator implements java.util.Comparator<RLHistoryItem> {
@Override
public int compare(RLHistoryItem o1, RLHistoryItem o2) {
return o2.dateTime.compareTo(o1.dateTime);
}
}
} }

View file

@ -26,12 +26,13 @@ import info.nightscout.androidaps.utils.resources.ResourceHelper;
public class RileyLinkStatusActivity extends NoSplashAppCompatActivity { public class RileyLinkStatusActivity extends NoSplashAppCompatActivity {
@Inject ResourceHelper resourceHelper; @Inject ResourceHelper resourceHelper;
@Inject RileyLinkUtil rileyLinkUtil;
@Inject RileyLinkServiceData rileyLinkServiceData;
TextView connectionStatus; TextView connectionStatus;
TextView configuredAddress; TextView configuredAddress;
TextView connectedDevice; TextView connectedDevice;
TextView connectionError; TextView connectionError;
RileyLinkServiceData rileyLinkServiceData;
private SectionsPagerAdapter mSectionsPagerAdapter; private SectionsPagerAdapter mSectionsPagerAdapter;
private FloatingActionButton floatingActionButton; private FloatingActionButton floatingActionButton;
@ -76,8 +77,6 @@ public class RileyLinkStatusActivity extends NoSplashAppCompatActivity {
this.connectedDevice = findViewById(R.id.rls_t1_connected_device); this.connectedDevice = findViewById(R.id.rls_t1_connected_device);
this.connectionError = findViewById(R.id.rls_t1_connection_error); this.connectionError = findViewById(R.id.rls_t1_connection_error);
rileyLinkServiceData = RileyLinkUtil.getRileyLinkServiceData();
// // 7-12 // // 7-12
// int[] ids = {R.id.rls_t1_tv02, R.id.rls_t1_tv03, R.id.rls_t1_tv04, R.id.rls_t1_tv05, R.id.rls_t1_tv07, // // int[] ids = {R.id.rls_t1_tv02, R.id.rls_t1_tv03, R.id.rls_t1_tv04, R.id.rls_t1_tv05, R.id.rls_t1_tv07, //
// R.id.rls_t1_tv08, R.id.rls_t1_tv09, R.id.rls_t1_tv10, R.id.rls_t1_tv11, R.id.rls_t1_tv12}; // R.id.rls_t1_tv08, R.id.rls_t1_tv09, R.id.rls_t1_tv10, R.id.rls_t1_tv11, R.id.rls_t1_tv12};
@ -97,12 +96,12 @@ public class RileyLinkStatusActivity extends NoSplashAppCompatActivity {
public void refreshData(int position) { public void refreshData(int position) {
if (position == 0) { if (position == 0) {
// FIXME i18n // FIXME i18n
this.connectionStatus.setText(rileyLinkServiceData.serviceState.name()); this.connectionStatus.setText(rileyLinkServiceData.rileyLinkServiceState.name());
this.configuredAddress.setText(rileyLinkServiceData.rileylinkAddress); this.configuredAddress.setText(rileyLinkServiceData.rileylinkAddress);
// FIXME // FIXME
this.connectedDevice.setText("???"); this.connectedDevice.setText("???");
// FIXME i18n // FIXME i18n
this.connectionError.setText(rileyLinkServiceData.errorCode.name()); this.connectionError.setText(rileyLinkServiceData.rileyLinkError.name());
} else { } else {
} }
@ -114,8 +113,8 @@ public class RileyLinkStatusActivity extends NoSplashAppCompatActivity {
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mSectionsPagerAdapter.addFragment(new RileyLinkStatusGeneral(), resourceHelper.gs(R.string.rileylink_settings_tab1)); mSectionsPagerAdapter.addFragment(new RileyLinkStatusGeneralFragment(), resourceHelper.gs(R.string.rileylink_settings_tab1));
mSectionsPagerAdapter.addFragment(new RileyLinkStatusHistory(), resourceHelper.gs(R.string.rileylink_settings_tab2)); mSectionsPagerAdapter.addFragment(new RileyLinkStatusHistoryFragment(), resourceHelper.gs(R.string.rileylink_settings_tab2));
//mSectionsPagerAdapter.addFragment(new RileyLinkStatusDevice(), "Medtronic"); //mSectionsPagerAdapter.addFragment(new RileyLinkStatusDevice(), "Medtronic");
mViewPager.setAdapter(mSectionsPagerAdapter); mViewPager.setAdapter(mSectionsPagerAdapter);

View file

@ -1,7 +1,6 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog; package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog;
import android.os.Bundle; import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -11,23 +10,33 @@ import org.joda.time.LocalDateTime;
import java.util.Locale; import java.util.Locale;
import info.nightscout.androidaps.MainApp; import javax.inject.Inject;
import dagger.android.support.DaggerFragment;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.pump.common.dialog.RefreshableInterface; import info.nightscout.androidaps.plugins.pump.common.dialog.RefreshableInterface;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkFirmwareVersion; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkFirmwareVersion;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData;
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil; import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil;
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin;
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus; import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil; import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
/** /**
* Created by andy on 5/19/18. * Created by andy on 5/19/18.
*/ */
public class RileyLinkStatusGeneral extends Fragment implements RefreshableInterface { public class RileyLinkStatusGeneralFragment extends DaggerFragment implements RefreshableInterface {
@Inject RileyLinkUtil rileyLinkUtil;
@Inject MedtronicUtil medtronicUtil;
@Inject MedtronicPumpStatus medtronicPumpStatus;
@Inject ResourceHelper resourceHelper;
@Inject MedtronicPumpPlugin medtronicPumpPlugin;
@Inject RileyLinkServiceData rileyLinkServiceData;
TextView connectionStatus; TextView connectionStatus;
TextView configuredAddress; TextView configuredAddress;
@ -41,9 +50,6 @@ public class RileyLinkStatusGeneral extends Fragment implements RefreshableInter
TextView lastDeviceContact; TextView lastDeviceContact;
TextView firmwareVersion; TextView firmwareVersion;
RileyLinkServiceData rileyLinkServiceData;
MedtronicPumpStatus medtronicPumpStatus;
boolean first = false; boolean first = false;
@ -58,7 +64,6 @@ public class RileyLinkStatusGeneral extends Fragment implements RefreshableInter
@Override @Override
public void onStart() { public void onStart() {
super.onStart(); super.onStart();
rileyLinkServiceData = RileyLinkUtil.getRileyLinkServiceData();
this.connectionStatus = getActivity().findViewById(R.id.rls_t1_connection_status); this.connectionStatus = getActivity().findViewById(R.id.rls_t1_connection_status);
this.configuredAddress = getActivity().findViewById(R.id.rls_t1_configured_address); this.configuredAddress = getActivity().findViewById(R.id.rls_t1_configured_address);
@ -93,23 +98,20 @@ public class RileyLinkStatusGeneral extends Fragment implements RefreshableInter
public void refreshData() { public void refreshData() {
RileyLinkTargetDevice targetDevice = RileyLinkUtil.getTargetDevice(); RileyLinkTargetDevice targetDevice = rileyLinkServiceData.targetDevice;
if (RileyLinkUtil.getServiceState()==null) this.connectionStatus.setText(resourceHelper.gs(rileyLinkServiceData.rileyLinkServiceState.getResourceId(targetDevice)));
this.connectionStatus.setText(MainApp.gs(RileyLinkServiceState.NotStarted.getResourceId(targetDevice)));
else
this.connectionStatus.setText(MainApp.gs(RileyLinkUtil.getServiceState().getResourceId(targetDevice)));
if (rileyLinkServiceData != null) { if (rileyLinkServiceData != null) {
this.configuredAddress.setText(rileyLinkServiceData.rileylinkAddress); this.configuredAddress.setText(rileyLinkServiceData.rileylinkAddress);
this.connectionError.setText(rileyLinkServiceData.errorCode == null ? // this.connectionError.setText(rileyLinkServiceData.rileyLinkError == null ? //
"-" "-"
: MainApp.gs(rileyLinkServiceData.errorCode.getResourceId(targetDevice))); : resourceHelper.gs(rileyLinkServiceData.rileyLinkError.getResourceId(targetDevice)));
RileyLinkFirmwareVersion firmwareVersion = rileyLinkServiceData.versionCC110; RileyLinkFirmwareVersion firmwareVersion = rileyLinkServiceData.versionCC110;
if (firmwareVersion==null) { if (firmwareVersion == null) {
this.firmwareVersion.setText("BLE113: -\nCC110: -"); this.firmwareVersion.setText("BLE113: -\nCC110: -");
} else { } else {
this.firmwareVersion.setText("BLE113: " + rileyLinkServiceData.versionBLE113 + // this.firmwareVersion.setText("BLE113: " + rileyLinkServiceData.versionBLE113 + //
@ -119,18 +121,17 @@ public class RileyLinkStatusGeneral extends Fragment implements RefreshableInter
} }
// TODO add handling for Omnipod pump status // TODO add handling for Omnipod pump status
this.medtronicPumpStatus = MedtronicUtil.getPumpStatus();
if (medtronicPumpStatus != null) { if (medtronicPumpStatus != null) {
this.deviceType.setText(MainApp.gs(RileyLinkTargetDevice.MedtronicPump.getResourceId())); this.deviceType.setText(resourceHelper.gs(RileyLinkTargetDevice.MedtronicPump.getResourceId()));
this.deviceModel.setText(medtronicPumpStatus.pumpType.getDescription()); this.deviceModel.setText(medtronicPumpPlugin.getPumpDescription().pumpType.getDescription());
this.serialNumber.setText(medtronicPumpStatus.serialNumber); this.serialNumber.setText(medtronicPumpStatus.serialNumber);
this.pumpFrequency.setText(MainApp.gs(medtronicPumpStatus.pumpFrequency.equals("medtronic_pump_frequency_us_ca") ? R.string.medtronic_pump_frequency_us_ca : R.string.medtronic_pump_frequency_worldwide)); this.pumpFrequency.setText(resourceHelper.gs(medtronicPumpStatus.pumpFrequency.equals("medtronic_pump_frequency_us_ca") ? R.string.medtronic_pump_frequency_us_ca : R.string.medtronic_pump_frequency_worldwide));
// TODO extend when Omnipod used // TODO extend when Omnipod used
if (MedtronicUtil.getMedtronicPumpModel() != null) if (medtronicUtil.getMedtronicPumpModel() != null)
this.connectedDevice.setText("Medtronic " + MedtronicUtil.getMedtronicPumpModel().getPumpModel()); this.connectedDevice.setText("Medtronic " + medtronicUtil.getMedtronicPumpModel().getPumpModel());
else else
this.connectedDevice.setText("???"); this.connectedDevice.setText("???");

View file

@ -1,29 +1,39 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog; package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle; import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.inject.Inject;
import dagger.android.support.DaggerFragment;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.pump.common.dialog.RefreshableInterface; import info.nightscout.androidaps.plugins.pump.common.dialog.RefreshableInterface;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem;
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil;
import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState; import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
/** /**
* Created by andy on 5/19/18. * Created by andy on 5/19/18.
*/ */
public class RileyLinkStatusHistory extends Fragment implements RefreshableInterface { public class RileyLinkStatusHistoryFragment extends DaggerFragment implements RefreshableInterface {
@Inject RileyLinkUtil rileyLinkUtil;
@Inject ResourceHelper resourceHelper;
RecyclerView recyclerView; RecyclerView recyclerView;
RecyclerViewAdapter recyclerViewAdapter; RecyclerViewAdapter recyclerViewAdapter;
@ -36,10 +46,10 @@ public class RileyLinkStatusHistory extends Fragment implements RefreshableInter
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.rileylink_status_history, container, false); View rootView = inflater.inflate(R.layout.rileylink_status_history, container, false);
recyclerView = (RecyclerView)rootView.findViewById(R.id.rileylink_history_list); recyclerView = (RecyclerView) rootView.findViewById(R.id.rileylink_history_list);
recyclerView.setHasFixedSize(true); recyclerView.setHasFixedSize(true);
llm = new LinearLayoutManager(getActivity().getApplicationContext()); llm = new LinearLayoutManager(rootView.getContext());
recyclerView.setLayoutManager(llm); recyclerView.setLayoutManager(llm);
recyclerViewAdapter = new RecyclerViewAdapter(filteredHistoryList); recyclerViewAdapter = new RecyclerViewAdapter(filteredHistoryList);
@ -59,13 +69,13 @@ public class RileyLinkStatusHistory extends Fragment implements RefreshableInter
@Override @Override
public void refreshData() { public void refreshData() {
if (RileyLinkUtil.getRileyLinkHistory()!=null) { if (rileyLinkUtil.getRileyLinkHistory() != null) {
recyclerViewAdapter.addItemsAndClean(RileyLinkUtil.getRileyLinkHistory()); recyclerViewAdapter.addItemsAndClean(rileyLinkUtil.getRileyLinkHistory());
} }
} }
public static class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.HistoryViewHolder> { public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.HistoryViewHolder> {
List<RLHistoryItem> historyList; List<RLHistoryItem> historyList;
@ -83,6 +93,8 @@ public class RileyLinkStatusHistory extends Fragment implements RefreshableInter
public void addItemsAndClean(List<RLHistoryItem> items) { public void addItemsAndClean(List<RLHistoryItem> items) {
this.historyList.clear(); this.historyList.clear();
Collections.sort(items, new RLHistoryItem.Comparator());
for (RLHistoryItem item : items) { for (RLHistoryItem item : items) {
if (!historyList.contains(item) && isValidItem(item)) { if (!historyList.contains(item) && isValidItem(item)) {
@ -98,11 +110,11 @@ public class RileyLinkStatusHistory extends Fragment implements RefreshableInter
PumpDeviceState pumpState = item.getPumpDeviceState(); PumpDeviceState pumpState = item.getPumpDeviceState();
if ((pumpState != null) && // //
(pumpState == PumpDeviceState.Sleeping || // if ((pumpState == PumpDeviceState.Sleeping || //
pumpState == PumpDeviceState.Active || // pumpState == PumpDeviceState.Active || //
pumpState == PumpDeviceState.WakingUp // pumpState == PumpDeviceState.WakingUp //
)) ))
return false; return false;
return true; return true;
@ -110,10 +122,11 @@ public class RileyLinkStatusHistory extends Fragment implements RefreshableInter
} }
@NotNull
@Override @Override
public RecyclerViewAdapter.HistoryViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { public RecyclerViewAdapter.HistoryViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.rileylink_status_history_item, // View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.rileylink_status_history_item, //
viewGroup, false); viewGroup, false);
return new RecyclerViewAdapter.HistoryViewHolder(v); return new RecyclerViewAdapter.HistoryViewHolder(v);
} }
@ -123,9 +136,9 @@ public class RileyLinkStatusHistory extends Fragment implements RefreshableInter
RLHistoryItem item = historyList.get(position); RLHistoryItem item = historyList.get(position);
if (item != null) { if (item != null) {
holder.timeView.setText(StringUtil.toDateTimeString(item.getDateTime())); holder.timeView.setText(DateUtil.dateAndTimeAndSecondsString(item.getDateTime().toDateTime().getMillis()));
holder.typeView.setText(item.getSource().getDesc()); holder.typeView.setText(item.getSource().getDesc());
holder.valueView.setText(item.getDescription()); holder.valueView.setText(item.getDescription(resourceHelper));
} }
} }
@ -141,7 +154,7 @@ public class RileyLinkStatusHistory extends Fragment implements RefreshableInter
super.onAttachedToRecyclerView(recyclerView); super.onAttachedToRecyclerView(recyclerView);
} }
static class HistoryViewHolder extends RecyclerView.ViewHolder { class HistoryViewHolder extends RecyclerView.ViewHolder {
TextView timeView; TextView timeView;
TextView typeView; TextView typeView;
@ -151,9 +164,9 @@ public class RileyLinkStatusHistory extends Fragment implements RefreshableInter
HistoryViewHolder(View itemView) { HistoryViewHolder(View itemView) {
super(itemView); super(itemView);
timeView = (TextView)itemView.findViewById(R.id.rileylink_history_time); timeView = (TextView) itemView.findViewById(R.id.rileylink_history_time);
typeView = (TextView)itemView.findViewById(R.id.rileylink_history_source); typeView = (TextView) itemView.findViewById(R.id.rileylink_history_source);
valueView = (TextView)itemView.findViewById(R.id.rileylink_history_description); valueView = (TextView) itemView.findViewById(R.id.rileylink_history_description);
} }
} }
} }

View file

@ -1,7 +1,6 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service
import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothAdapter
import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
@ -15,6 +14,7 @@ import javax.inject.Inject
class RileyLinkBluetoothStateReceiver : DaggerBroadcastReceiver() { class RileyLinkBluetoothStateReceiver : DaggerBroadcastReceiver() {
@Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var activePlugin: ActivePluginProvider @Inject lateinit var activePlugin: ActivePluginProvider
@Inject lateinit var rileyLinkUtil: RileyLinkUtil
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
super.onReceive(context, intent) super.onReceive(context, intent)
@ -27,7 +27,7 @@ class RileyLinkBluetoothStateReceiver : DaggerBroadcastReceiver() {
BluetoothAdapter.STATE_ON -> { BluetoothAdapter.STATE_ON -> {
aapsLogger.debug("RileyLinkBluetoothStateReceiver: Bluetooth back on. Sending broadcast to RileyLink Framework") aapsLogger.debug("RileyLinkBluetoothStateReceiver: Bluetooth back on. Sending broadcast to RileyLink Framework")
RileyLinkUtil.sendBroadcastMessage(RileyLinkConst.Intents.BluetoothReconnected) rileyLinkUtil.sendBroadcastMessage(RileyLinkConst.Intents.BluetoothReconnected, context)
} }
} }
} }

View file

@ -5,24 +5,24 @@ package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service;
*/ */
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.slf4j.Logger; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.slf4j.LoggerFactory;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import info.nightscout.androidaps.logging.L; import javax.inject.Inject;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
import dagger.android.DaggerBroadcastReceiver;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkFirmwareVersion; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkFirmwareVersion;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState;
@ -31,26 +31,27 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTask; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTask;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTaskExecutor; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTaskExecutor;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.WakeAndTuneTask; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.WakeAndTuneTask;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.sharedPreferences.SP;
/** /**
* I added this class outside of RileyLinkService, because for now it's very important part of RL framework and * I added this class outside of RileyLinkService, because for now it's very important part of RL framework and
* where we get a lot of problems. Especially merging between AAPS and RileyLinkAAPS. I might put it back at * where we get a lot of problems. Especially merging between AAPS and RileyLinkAAPS. I might put it back at
* later time * later time
*/ */
public class RileyLinkBroadcastReceiver extends BroadcastReceiver { public class RileyLinkBroadcastReceiver extends DaggerBroadcastReceiver {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPCOMM); @Inject HasAndroidInjector injector;
@Inject SP sp;
@Inject AAPSLogger aapsLogger;
@Inject RileyLinkServiceData rileyLinkServiceData;
@Inject ServiceTaskExecutor serviceTaskExecutor;
RileyLinkService serviceInstance; RileyLinkService serviceInstance;
protected Map<String, List<String>> broadcastIdentifiers = null; protected Map<String, List<String>> broadcastIdentifiers = null;
String deviceSpecificPrefix; String deviceSpecificPrefix;
Context context;
public RileyLinkBroadcastReceiver(RileyLinkService serviceInstance) {
public RileyLinkBroadcastReceiver(RileyLinkService serviceInstance, Context context) {
this.serviceInstance = serviceInstance; this.serviceInstance = serviceInstance;
this.context = context;
createBroadcastIdentifiers(); createBroadcastIdentifiers();
} }
@ -88,31 +89,31 @@ public class RileyLinkBroadcastReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (intent == null) { if (intent == null) {
LOG.error("onReceive: received null intent"); aapsLogger.error(LTag.PUMPCOMM, "onReceive: received null intent");
} else { } else {
String action = intent.getAction(); String action = intent.getAction();
if (action == null) { if (action == null) {
LOG.error("onReceive: null action"); aapsLogger.error("onReceive: null action");
} else { } else {
if (isLoggingEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "Received Broadcast: " + action);
LOG.debug("Received Broadcast: " + action);
if (!processBluetoothBroadcasts(action) && // if (!processBluetoothBroadcasts(action) && //
!processRileyLinkBroadcasts(action) && // !processRileyLinkBroadcasts(action, context) && //
!processTuneUpBroadcasts(action) && // !processTuneUpBroadcasts(action) && //
!processDeviceSpecificBroadcasts(action, intent) && // !processDeviceSpecificBroadcasts(action, intent) && //
!processApplicationSpecificBroadcasts(action, intent) // !processApplicationSpecificBroadcasts(action, intent) //
) { ) {
LOG.error("Unhandled broadcast: action=" + action); aapsLogger.error(LTag.PUMPCOMM, "Unhandled broadcast: action=" + action);
} }
} }
} }
} }
public void registerBroadcasts() { public void registerBroadcasts(Context context) {
IntentFilter intentFilter = new IntentFilter(); IntentFilter intentFilter = new IntentFilter();
@ -131,61 +132,55 @@ public class RileyLinkBroadcastReceiver extends BroadcastReceiver {
} }
private boolean processRileyLinkBroadcasts(String action) { private boolean processRileyLinkBroadcasts(String action, Context context) {
if (action.equals(RileyLinkConst.Intents.RileyLinkDisconnected)) { if (action.equals(RileyLinkConst.Intents.RileyLinkDisconnected)) {
if (BluetoothAdapter.getDefaultAdapter().isEnabled()) { if (BluetoothAdapter.getDefaultAdapter().isEnabled()) {
RileyLinkUtil rileyLinkServiceData.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.RileyLinkUnreachable);
.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.RileyLinkUnreachable);
} else { } else {
RileyLinkUtil.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.BluetoothDisabled); rileyLinkServiceData.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.BluetoothDisabled);
} }
return true; return true;
} else if (action.equals(RileyLinkConst.Intents.RileyLinkReady)) { } else if (action.equals(RileyLinkConst.Intents.RileyLinkReady)) {
if (isLoggingEnabled()) aapsLogger.warn(LTag.PUMPCOMM, "MedtronicConst.Intents.RileyLinkReady");
LOG.warn("MedtronicConst.Intents.RileyLinkReady");
// sendIPCNotification(RT2Const.IPC.MSG_note_WakingPump); // sendIPCNotification(RT2Const.IPC.MSG_note_WakingPump);
if (this.serviceInstance.rileyLinkBLE == null) serviceInstance.rileyLinkBLE.enableNotifications();
return false; serviceInstance.rfspy.startReader(); // call startReader from outside?
this.serviceInstance.rileyLinkBLE.enableNotifications(); serviceInstance.rfspy.initializeRileyLink();
this.serviceInstance.rfspy.startReader(); // call startReader from outside? String bleVersion = serviceInstance.rfspy.getBLEVersionCached();
RileyLinkFirmwareVersion rlVersion = rileyLinkServiceData.firmwareVersion;
this.serviceInstance.rfspy.initializeRileyLink();
String bleVersion = this.serviceInstance.rfspy.getBLEVersionCached();
RileyLinkFirmwareVersion rlVersion = this.serviceInstance.rfspy.getRLVersionCached();
// if (isLoggingEnabled()) // if (isLoggingEnabled())
LOG.debug("RfSpy version (BLE113): " + bleVersion); aapsLogger.debug(LTag.PUMPCOMM, "RfSpy version (BLE113): " + bleVersion);
this.serviceInstance.rileyLinkServiceData.versionBLE113 = bleVersion; serviceInstance.rileyLinkServiceData.versionBLE113 = bleVersion;
// if (isLoggingEnabled()) // if (isLoggingEnabled())
LOG.debug("RfSpy Radio version (CC110): " + rlVersion.name()); aapsLogger.debug(LTag.PUMPCOMM, "RfSpy Radio version (CC110): " + rlVersion.name());
this.serviceInstance.rileyLinkServiceData.versionCC110 = rlVersion; serviceInstance.rileyLinkServiceData.versionCC110 = rlVersion;
ServiceTask task = new InitializePumpManagerTask(RileyLinkUtil.getTargetDevice()); ServiceTask task = new InitializePumpManagerTask(injector, context);
ServiceTaskExecutor.startTask(task); serviceTaskExecutor.startTask(task);
if (isLoggingEnabled()) aapsLogger.info(LTag.PUMPCOMM, "Announcing RileyLink open For business");
LOG.info("Announcing RileyLink open For business");
return true; return true;
} else if (action.equals(RileyLinkConst.Intents.RileyLinkNewAddressSet)) { } else if (action.equals(RileyLinkConst.Intents.RileyLinkNewAddressSet)) {
String RileylinkBLEAddress = SP.getString(RileyLinkConst.Prefs.RileyLinkAddress, ""); String RileylinkBLEAddress = sp.getString(RileyLinkConst.Prefs.RileyLinkAddress, "");
if (RileylinkBLEAddress.equals("")) { if (RileylinkBLEAddress.equals("")) {
LOG.error("No Rileylink BLE Address saved in app"); aapsLogger.error("No Rileylink BLE Address saved in app");
} else { } else {
// showBusy("Configuring Service", 50); // showBusy("Configuring Service", 50);
// rileyLinkBLE.findRileyLink(RileylinkBLEAddress); // rileyLinkBLE.findRileyLink(RileylinkBLEAddress);
this.serviceInstance.reconfigureRileyLink(RileylinkBLEAddress); serviceInstance.reconfigureRileyLink(RileylinkBLEAddress);
// MainApp.getServiceClientConnection().setThisRileylink(RileylinkBLEAddress); // MainApp.getServiceClientConnection().setThisRileylink(RileylinkBLEAddress);
} }
return true; return true;
} else if (action.equals(RileyLinkConst.Intents.RileyLinkDisconnect)) { } else if (action.equals(RileyLinkConst.Intents.RileyLinkDisconnect)) {
this.serviceInstance.disconnectRileyLink(); serviceInstance.disconnectRileyLink();
return true; return true;
} else { } else {
@ -198,18 +193,16 @@ public class RileyLinkBroadcastReceiver extends BroadcastReceiver {
public boolean processBluetoothBroadcasts(String action) { public boolean processBluetoothBroadcasts(String action) {
if (action.equals(RileyLinkConst.Intents.BluetoothConnected)) { if (action.equals(RileyLinkConst.Intents.BluetoothConnected)) {
if (isLoggingEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "Bluetooth - Connected");
LOG.debug("Bluetooth - Connected"); serviceTaskExecutor.startTask(new DiscoverGattServicesTask(injector));
ServiceTaskExecutor.startTask(new DiscoverGattServicesTask());
return true; return true;
} else if (action.equals(RileyLinkConst.Intents.BluetoothReconnected)) { } else if (action.equals(RileyLinkConst.Intents.BluetoothReconnected)) {
if (isLoggingEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "Bluetooth - Reconnecting");
LOG.debug("Bluetooth - Reconnecting");
serviceInstance.bluetoothInit(); serviceInstance.bluetoothInit();
ServiceTaskExecutor.startTask(new DiscoverGattServicesTask(true)); serviceTaskExecutor.startTask(new DiscoverGattServicesTask(injector, true));
return true; return true;
} else { } else {
@ -224,7 +217,7 @@ public class RileyLinkBroadcastReceiver extends BroadcastReceiver {
if (this.broadcastIdentifiers.get("TuneUp").contains(action)) { if (this.broadcastIdentifiers.get("TuneUp").contains(action)) {
if (serviceInstance.getRileyLinkTargetDevice().isTuneUpEnabled()) { if (serviceInstance.getRileyLinkTargetDevice().isTuneUpEnabled()) {
ServiceTaskExecutor.startTask(new WakeAndTuneTask()); serviceTaskExecutor.startTask(new WakeAndTuneTask(injector));
} }
return true; return true;
} else { } else {
@ -240,7 +233,7 @@ public class RileyLinkBroadcastReceiver extends BroadcastReceiver {
} }
if (action.startsWith(this.deviceSpecificPrefix)) { if (action.startsWith(this.deviceSpecificPrefix)) {
return this.serviceInstance.handleDeviceSpecificBroadcasts(intent); return serviceInstance.handleDeviceSpecificBroadcasts(intent);
} else } else
return false; return false;
} }
@ -250,12 +243,7 @@ public class RileyLinkBroadcastReceiver extends BroadcastReceiver {
return false; return false;
} }
public void unregisterBroadcasts(Context context) {
public boolean isLoggingEnabled() {
return (L.isEnabled(L.PUMPCOMM));
}
public void unregisterBroadcasts() {
LocalBroadcastManager.getInstance(context).unregisterReceiver(this); LocalBroadcastManager.getInstance(context).unregisterReceiver(this);
} }
} }

View file

@ -5,11 +5,14 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import org.jetbrains.annotations.NotNull;
import javax.inject.Inject; import javax.inject.Inject;
import dagger.android.DaggerService; import dagger.android.DaggerService;
import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkCommunicationManager; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkCommunicationManager;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
@ -22,11 +25,10 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLin
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceResult; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceResult;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceTransport; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceTransport;
import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState; import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState;
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil; import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
import info.nightscout.androidaps.utils.sharedPreferences.SP; import info.nightscout.androidaps.utils.sharedPreferences.SP;
import static info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil.getRileyLinkCommunicationManager;
/** /**
* Created by andy on 5/6/18. * Created by andy on 5/6/18.
* Split from original file and renamed. * Split from original file and renamed.
@ -36,33 +38,32 @@ public abstract class RileyLinkService extends DaggerService {
@Inject protected AAPSLogger aapsLogger; @Inject protected AAPSLogger aapsLogger;
@Inject protected SP sp; @Inject protected SP sp;
@Inject protected Context context; @Inject protected Context context;
@Inject protected RxBusWrapper rxBus;
@Inject protected RileyLinkUtil rileyLinkUtil;
@Inject protected MedtronicUtil medtronicUtil; // TODO should be avoided here as it's MDT
@Inject protected RileyLinkServiceData rileyLinkServiceData;
@Inject protected MedtronicPumpStatus medtronicPumpStatus;
@NotNull protected RileyLinkBLE rileyLinkBLE; // android-bluetooth management, must be set in initRileyLinkServiceData
public RileyLinkBLE rileyLinkBLE; // android-bluetooth management
protected BluetoothAdapter bluetoothAdapter; protected BluetoothAdapter bluetoothAdapter;
protected RFSpy rfspy; // interface for RL xxx Mhz radio. protected RFSpy rfspy; // interface for RL xxx Mhz radio.
protected RileyLinkBroadcastReceiver mBroadcastReceiver; protected RileyLinkBroadcastReceiver mBroadcastReceiver;
protected RileyLinkServiceData rileyLinkServiceData;
protected RileyLinkBluetoothStateReceiver bluetoothStateReceiver; protected RileyLinkBluetoothStateReceiver bluetoothStateReceiver;
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
//LOG.debug("onCreate");
RileyLinkUtil.setContext(this.context); rileyLinkUtil.setEncoding(getEncoding());
RileyLinkUtil.setRileyLinkService(this);
RileyLinkUtil.setEncoding(getEncoding());
initRileyLinkServiceData(); initRileyLinkServiceData();
mBroadcastReceiver = new RileyLinkBroadcastReceiver(this, this.context); mBroadcastReceiver = new RileyLinkBroadcastReceiver(this);
mBroadcastReceiver.registerBroadcasts(); mBroadcastReceiver.registerBroadcasts(this);
bluetoothStateReceiver = new RileyLinkBluetoothStateReceiver(); bluetoothStateReceiver = new RileyLinkBluetoothStateReceiver();
bluetoothStateReceiver.registerBroadcasts(this); bluetoothStateReceiver.registerBroadcasts(this);
//LOG.debug("onCreate(): It's ALIVE!");
} }
/** /**
@ -96,13 +97,10 @@ public abstract class RileyLinkService extends DaggerService {
super.onDestroy(); super.onDestroy();
//LOG.error("I die! I die!"); //LOG.error("I die! I die!");
if (rileyLinkBLE != null) { rileyLinkBLE.disconnect(); // dispose of Gatt (disconnect and close)
rileyLinkBLE.disconnect(); // dispose of Gatt (disconnect and close)
rileyLinkBLE = null;
}
if (mBroadcastReceiver != null) { if (mBroadcastReceiver != null) {
mBroadcastReceiver.unregisterBroadcasts(); mBroadcastReceiver.unregisterBroadcasts(this);
} }
if (bluetoothStateReceiver != null) { if (bluetoothStateReceiver != null) {
@ -129,32 +127,30 @@ public abstract class RileyLinkService extends DaggerService {
public abstract RileyLinkCommunicationManager getDeviceCommunicationManager(); public abstract RileyLinkCommunicationManager getDeviceCommunicationManager();
// Here is where the wake-lock begins: // Here is where the wake-lock begins:
// We've received a service startCommand, we grab the lock. // We've received a service startCommand, we grab the lock.
@Override @Override
public int onStartCommand(Intent intent, int flags, int startId) { public int onStartCommand(Intent intent, int flags, int startId) {
RileyLinkUtil.setContext(getApplicationContext());
return (START_STICKY); return (START_STICKY);
} }
public boolean bluetoothInit() { public boolean bluetoothInit() {
aapsLogger.debug(LTag.PUMPCOMM, "bluetoothInit: attempting to get an adapter"); aapsLogger.debug(LTag.PUMPCOMM, "bluetoothInit: attempting to get an adapter");
RileyLinkUtil.setServiceState(RileyLinkServiceState.BluetoothInitializing); rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.BluetoothInitializing);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) { if (bluetoothAdapter == null) {
aapsLogger.error("Unable to obtain a BluetoothAdapter."); aapsLogger.error("Unable to obtain a BluetoothAdapter.");
RileyLinkUtil.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.NoBluetoothAdapter); rileyLinkServiceData.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.NoBluetoothAdapter);
} else { } else {
if (!bluetoothAdapter.isEnabled()) { if (!bluetoothAdapter.isEnabled()) {
aapsLogger.error("Bluetooth is not enabled."); aapsLogger.error("Bluetooth is not enabled.");
RileyLinkUtil.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.BluetoothDisabled); rileyLinkServiceData.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.BluetoothDisabled);
} else { } else {
RileyLinkUtil.setServiceState(RileyLinkServiceState.BluetoothReady); rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.BluetoothReady);
return true; return true;
} }
} }
@ -166,12 +162,7 @@ public abstract class RileyLinkService extends DaggerService {
// returns true if our Rileylink configuration changed // returns true if our Rileylink configuration changed
public boolean reconfigureRileyLink(String deviceAddress) { public boolean reconfigureRileyLink(String deviceAddress) {
if (rileyLinkBLE == null) { rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.RileyLinkInitializing);
RileyLinkUtil.setServiceState(RileyLinkServiceState.BluetoothInitializing);
return false;
}
RileyLinkUtil.setServiceState(RileyLinkServiceState.RileyLinkInitializing);
if (rileyLinkBLE.isConnected()) { if (rileyLinkBLE.isConnected()) {
if (deviceAddress.equals(rileyLinkServiceData.rileylinkAddress)) { if (deviceAddress.equals(rileyLinkServiceData.rileylinkAddress)) {
@ -192,10 +183,10 @@ public abstract class RileyLinkService extends DaggerService {
} else { } else {
aapsLogger.debug(LTag.PUMPCOMM, "Using RL " + deviceAddress); aapsLogger.debug(LTag.PUMPCOMM, "Using RL " + deviceAddress);
if (RileyLinkUtil.getServiceState() == RileyLinkServiceState.NotStarted) { if (rileyLinkServiceData.getRileyLinkServiceState() == RileyLinkServiceState.NotStarted) {
if (!bluetoothInit()) { if (!bluetoothInit()) {
aapsLogger.error("RileyLink can't get activated, Bluetooth is not functioning correctly. {}", aapsLogger.error("RileyLink can't get activated, Bluetooth is not functioning correctly. {}",
RileyLinkUtil.getError() != null ? RileyLinkUtil.getError().name() : "Unknown error (null)"); getError() != null ? getError().name() : "Unknown error (null)");
return false; return false;
} }
} }
@ -214,8 +205,8 @@ public abstract class RileyLinkService extends DaggerService {
// FIXME: This needs to be run in a session so that is interruptable, has a separate thread, etc. // FIXME: This needs to be run in a session so that is interruptable, has a separate thread, etc.
public void doTuneUpDevice() { public void doTuneUpDevice() {
RileyLinkUtil.setServiceState(RileyLinkServiceState.TuneUpDevice); rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.TuneUpDevice);
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Sleeping); medtronicPumpStatus.setPumpDeviceState(PumpDeviceState.Sleeping);
double lastGoodFrequency = 0.0d; double lastGoodFrequency = 0.0d;
@ -239,25 +230,27 @@ public abstract class RileyLinkService extends DaggerService {
if (newFrequency == 0.0d) { if (newFrequency == 0.0d) {
// error tuning pump, pump not present ?? // error tuning pump, pump not present ??
RileyLinkUtil rileyLinkServiceData.setServiceState(RileyLinkServiceState.PumpConnectorError, RileyLinkError.TuneUpOfDeviceFailed);
.setServiceState(RileyLinkServiceState.PumpConnectorError, RileyLinkError.TuneUpOfDeviceFailed);
} else { } else {
getRileyLinkCommunicationManager().clearNotConnectedCount(); getDeviceCommunicationManager().clearNotConnectedCount();
RileyLinkUtil.setServiceState(RileyLinkServiceState.PumpConnectorReady); rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.PumpConnectorReady);
} }
} }
public void disconnectRileyLink() { public void disconnectRileyLink() {
if (this.rileyLinkBLE != null && this.rileyLinkBLE.isConnected()) { if (rileyLinkBLE.isConnected()) {
this.rileyLinkBLE.disconnect(); rileyLinkBLE.disconnect();
rileyLinkServiceData.rileylinkAddress = null; rileyLinkServiceData.rileylinkAddress = null;
} }
RileyLinkUtil.setServiceState(RileyLinkServiceState.BluetoothReady); rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.BluetoothReady);
} }
@NotNull public RileyLinkBLE getRileyLinkBLE() {
return rileyLinkBLE;
}
/** /**
* Get Target Device for Service * Get Target Device for Service
@ -272,4 +265,11 @@ public abstract class RileyLinkService extends DaggerService {
rfspy.setRileyLinkEncoding(encodingType); rfspy.setRileyLinkEncoding(encodingType);
} }
} }
public RileyLinkError getError() {
if (rileyLinkServiceData != null)
return rileyLinkServiceData.rileyLinkError;
else
return null;
}
} }

View file

@ -1,21 +1,39 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service; package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service;
import javax.inject.Inject;
import javax.inject.Singleton;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkFirmwareVersion; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkFirmwareVersion;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkTargetFrequency;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice;
import info.nightscout.androidaps.plugins.pump.medtronic.events.EventMedtronicDeviceStatusChange;
/** /**
* Created by andy on 16/05/2018. * Created by andy on 16/05/2018.
*/ */
@Singleton
public class RileyLinkServiceData { public class RileyLinkServiceData {
public boolean tuneUpDone = false; @Inject AAPSLogger aapsLogger;
public RileyLinkError errorCode; @Inject RileyLinkUtil rileyLinkUtil;
public RileyLinkServiceState serviceState = RileyLinkServiceState.NotStarted; @Inject RxBusWrapper rxBus;
boolean tuneUpDone = false;
public RileyLinkError rileyLinkError;
public RileyLinkServiceState rileyLinkServiceState = RileyLinkServiceState.NotStarted;
public RileyLinkFirmwareVersion firmwareVersion;
public RileyLinkTargetFrequency rileyLinkTargetFrequency;
public String rileylinkAddress; public String rileylinkAddress;
public long lastTuneUpTime = 0L; long lastTuneUpTime = 0L;
public Double lastGoodFrequency; public Double lastGoodFrequency;
// bt version // bt version
@ -29,15 +47,45 @@ public class RileyLinkServiceData {
public String pumpID; public String pumpID;
public byte[] pumpIDBytes; public byte[] pumpIDBytes;
@Inject
public RileyLinkServiceData(RileyLinkTargetDevice targetDevice) { public RileyLinkServiceData() {}
this.targetDevice = targetDevice;
}
public void setPumpID(String pumpId, byte[] pumpIdBytes) { public void setPumpID(String pumpId, byte[] pumpIdBytes) {
this.pumpID = pumpId; this.pumpID = pumpId;
this.pumpIDBytes = pumpIdBytes; this.pumpIDBytes = pumpIdBytes;
} }
public void setRileyLinkServiceState(RileyLinkServiceState newState) {
setServiceState(newState, null);
}
public RileyLinkServiceState getRileyLinkServiceState() {
return workWithServiceState(null, null, false);
}
public void setServiceState(RileyLinkServiceState newState, RileyLinkError errorCode) {
workWithServiceState(newState, errorCode, true);
}
private synchronized RileyLinkServiceState workWithServiceState(RileyLinkServiceState newState, RileyLinkError errorCode, boolean set) {
if (set) {
rileyLinkServiceState = newState;
this.rileyLinkError = errorCode;
aapsLogger.info(LTag.PUMP, "RileyLink State Changed: {} {}", newState, errorCode == null ? "" : " - Error State: " + errorCode.name());
rileyLinkUtil.getRileyLinkHistory().add(new RLHistoryItem(rileyLinkServiceState, errorCode, targetDevice));
rxBus.send(new EventMedtronicDeviceStatusChange(newState, errorCode));
return null;
} else {
return rileyLinkServiceState;
}
}
} }

View file

@ -1,20 +1,28 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks; package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks;
import javax.inject.Inject;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin;
/** /**
* Created by geoff on 7/9/16. * Created by geoff on 7/9/16.
*/ */
public class DiscoverGattServicesTask extends ServiceTask { public class DiscoverGattServicesTask extends ServiceTask {
@Inject MedtronicPumpPlugin medtronicPumpPlugin;
public boolean needToConnect = false; public boolean needToConnect = false;
public DiscoverGattServicesTask() { public DiscoverGattServicesTask(HasAndroidInjector injector) {
super(injector);
} }
public DiscoverGattServicesTask(boolean needToConnect) { public DiscoverGattServicesTask(HasAndroidInjector injector, boolean needToConnect) {
super(injector);
this.needToConnect = needToConnect; this.needToConnect = needToConnect;
} }
@ -23,8 +31,8 @@ public class DiscoverGattServicesTask extends ServiceTask {
public void run() { public void run() {
if (needToConnect) if (needToConnect)
RileyLinkUtil.getRileyLinkBLE().connectGatt(); medtronicPumpPlugin.getRileyLinkService().getRileyLinkBLE().connectGatt();
RileyLinkUtil.getRileyLinkBLE().discoverServices(); medtronicPumpPlugin.getRileyLinkService().getRileyLinkBLE().discoverServices();
} }
} }

View file

@ -1,20 +1,22 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks; package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks;
import android.util.Log; import android.content.Context;
import org.slf4j.Logger; import javax.inject.Inject;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.logging.L; import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.pump.common.PumpPluginAbstract;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkCommunicationManager;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceTransport; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceTransport;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicConst; import info.nightscout.androidaps.utils.sharedPreferences.SP;
import info.nightscout.androidaps.utils.SP;
/** /**
* Created by geoff on 7/9/16. * Created by geoff on 7/9/16.
@ -23,62 +25,66 @@ import info.nightscout.androidaps.utils.SP;
*/ */
public class InitializePumpManagerTask extends ServiceTask { public class InitializePumpManagerTask extends ServiceTask {
private static final String TAG = "InitPumpManagerTask"; @Inject AAPSLogger aapsLogger;
private RileyLinkTargetDevice targetDevice; @Inject ActivePluginProvider activePlugin;
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPCOMM); @Inject SP sp;
@Inject RileyLinkServiceData rileyLinkServiceData;
@Inject RileyLinkUtil rileyLinkUtil;
public InitializePumpManagerTask(RileyLinkTargetDevice targetDevice) { private final Context context;
super();
this.targetDevice = targetDevice; public InitializePumpManagerTask(HasAndroidInjector injector, Context context) {
super(injector);
this.context = context;
} }
public InitializePumpManagerTask(HasAndroidInjector injector, Context context, ServiceTransport transport) {
public InitializePumpManagerTask(ServiceTransport transport) { super(injector, transport);
super(transport); this.context = context;
} }
@Override @Override
public void run() { public void run() {
double lastGoodFrequency = 0.0d; double lastGoodFrequency;
if (RileyLinkUtil.getRileyLinkServiceData().lastGoodFrequency==null) { if (rileyLinkServiceData.lastGoodFrequency == null) {
lastGoodFrequency = SP.getDouble(RileyLinkConst.Prefs.LastGoodDeviceFrequency, 0.0d); lastGoodFrequency = sp.getDouble(RileyLinkConst.Prefs.LastGoodDeviceFrequency, 0.0d);
lastGoodFrequency = Math.round(lastGoodFrequency * 1000d) / 1000d; lastGoodFrequency = Math.round(lastGoodFrequency * 1000d) / 1000d;
RileyLinkUtil.getRileyLinkServiceData().lastGoodFrequency = lastGoodFrequency; rileyLinkServiceData.lastGoodFrequency = lastGoodFrequency;
// if (RileyLinkUtil.getRileyLinkTargetFrequency() == null) { // if (RileyLinkUtil.getRileyLinkTargetFrequency() == null) {
// String pumpFrequency = SP.getString(MedtronicConst.Prefs.PumpFrequency, null); // String pumpFrequency = SP.getString(MedtronicConst.Prefs.PumpFrequency, null);
// } // }
} else { } else {
lastGoodFrequency = RileyLinkUtil.getRileyLinkServiceData().lastGoodFrequency; lastGoodFrequency = rileyLinkServiceData.lastGoodFrequency;
} }
RileyLinkCommunicationManager rileyLinkCommunicationManager = ((PumpPluginAbstract) activePlugin.getActivePump()).getRileyLinkService().getDeviceCommunicationManager();
if ((lastGoodFrequency > 0.0d) if ((lastGoodFrequency > 0.0d)
&& RileyLinkUtil.getRileyLinkCommunicationManager().isValidFrequency(lastGoodFrequency)) { && rileyLinkCommunicationManager.isValidFrequency(lastGoodFrequency)) {
RileyLinkUtil.setServiceState(RileyLinkServiceState.RileyLinkReady); rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.RileyLinkReady);
if (L.isEnabled(L.PUMPCOMM)) aapsLogger.info(LTag.PUMPCOMM, "Setting radio frequency to {} MHz", lastGoodFrequency);
LOG.info("Setting radio frequency to {} MHz", lastGoodFrequency);
RileyLinkUtil.getRileyLinkCommunicationManager().setRadioFrequencyForPump(lastGoodFrequency); rileyLinkCommunicationManager.setRadioFrequencyForPump(lastGoodFrequency);
boolean foundThePump = RileyLinkUtil.getRileyLinkCommunicationManager().tryToConnectToDevice(); boolean foundThePump = rileyLinkCommunicationManager.tryToConnectToDevice();
if (foundThePump) { if (foundThePump) {
RileyLinkUtil.setServiceState(RileyLinkServiceState.PumpConnectorReady); rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.PumpConnectorReady);
} else { } else {
RileyLinkUtil.setServiceState(RileyLinkServiceState.PumpConnectorError, rileyLinkServiceData.setServiceState(RileyLinkServiceState.PumpConnectorError,
RileyLinkError.NoContactWithDevice); RileyLinkError.NoContactWithDevice);
RileyLinkUtil.sendBroadcastMessage(RileyLinkConst.IPC.MSG_PUMP_tunePump); rileyLinkUtil.sendBroadcastMessage(RileyLinkConst.IPC.MSG_PUMP_tunePump, context);
} }
} else { } else {
RileyLinkUtil.sendBroadcastMessage(RileyLinkConst.IPC.MSG_PUMP_tunePump); rileyLinkUtil.sendBroadcastMessage(RileyLinkConst.IPC.MSG_PUMP_tunePump, context);
} }
} }
} }

View file

@ -1,5 +1,6 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks; package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceTransport; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceTransport;
/** /**
@ -7,12 +8,12 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.
*/ */
public class PumpTask extends ServiceTask { public class PumpTask extends ServiceTask {
public PumpTask() { public PumpTask(HasAndroidInjector injector) {
super(); super(injector);
} }
public PumpTask(ServiceTransport transport) { public PumpTask(HasAndroidInjector injector, ServiceTransport transport) {
super(transport); super(injector, transport);
} }
} }

View file

@ -1,6 +1,13 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks; package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks;
import javax.inject.Inject;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.pump.common.PumpPluginAbstract;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceTransport; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceTransport;
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin; import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin;
import info.nightscout.androidaps.plugins.pump.medtronic.events.EventRefreshButtonState; import info.nightscout.androidaps.plugins.pump.medtronic.events.EventRefreshButtonState;
@ -11,25 +18,30 @@ import info.nightscout.androidaps.plugins.pump.medtronic.service.RileyLinkMedtro
*/ */
public class ResetRileyLinkConfigurationTask extends PumpTask { public class ResetRileyLinkConfigurationTask extends PumpTask {
@Inject ActivePluginProvider activePlugin;
@Inject RxBusWrapper rxBus;
private static final String TAG = "ResetRileyLinkTask"; private static final String TAG = "ResetRileyLinkTask";
public ResetRileyLinkConfigurationTask() { public ResetRileyLinkConfigurationTask(HasAndroidInjector injector) {
super(injector);
} }
public ResetRileyLinkConfigurationTask(ServiceTransport transport) { public ResetRileyLinkConfigurationTask(HasAndroidInjector injector, ServiceTransport transport) {
super(transport); super(injector, transport);
} }
@Override @Override
public void run() { public void run() {
RxBus.Companion.getINSTANCE().send(new EventRefreshButtonState(false)); PumpPluginAbstract pump = (PumpPluginAbstract) activePlugin.getActivePump();
rxBus.send(new EventRefreshButtonState(false));
MedtronicPumpPlugin.isBusy = true; MedtronicPumpPlugin.isBusy = true;
RileyLinkMedtronicService.getInstance().resetRileyLinkConfiguration(); pump.resetRileyLinkConfiguration();
MedtronicPumpPlugin.isBusy = false; MedtronicPumpPlugin.isBusy = false;
RxBus.Companion.getINSTANCE().send(new EventRefreshButtonState(true)); rxBus.send(new EventRefreshButtonState(true));
} }
} }

View file

@ -1,5 +1,6 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks; package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceTransport; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceTransport;
/** /**
@ -7,17 +8,21 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.
*/ */
public class ServiceTask implements Runnable { public class ServiceTask implements Runnable {
private static final String TAG = "ServiceTask(base)";
public boolean completed = false; public boolean completed = false;
protected ServiceTransport mTransport; protected ServiceTransport mTransport;
protected HasAndroidInjector injector;
public ServiceTask() { public ServiceTask(HasAndroidInjector injector) {
this.injector = injector;
injector.androidInjector().inject(this);
init(new ServiceTransport()); init(new ServiceTransport());
} }
public ServiceTask(ServiceTransport transport) { public ServiceTask(HasAndroidInjector injector, ServiceTransport transport) {
this.injector = injector;
injector.androidInjector().inject(this);
init(transport); init(transport);
} }

View file

@ -4,46 +4,40 @@ import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import android.util.Log; import javax.inject.Inject;
import javax.inject.Singleton;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
/** /**
* Created by geoff on 7/9/16. * Created by geoff on 7/9/16.
*/ */
@Singleton
public class ServiceTaskExecutor extends ThreadPoolExecutor { public class ServiceTaskExecutor extends ThreadPoolExecutor {
private static final String TAG = "ServiceTaskExecutor"; @Inject RileyLinkUtil rileyLinkUtil;
private static ServiceTaskExecutor instance; @Inject AAPSLogger aapsLogger;
private static LinkedBlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<>(); private static LinkedBlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<>();
static { @Inject
instance = new ServiceTaskExecutor(); public ServiceTaskExecutor() {
}
private ServiceTaskExecutor() {
super(1, 1, 10000, TimeUnit.MILLISECONDS, taskQueue); super(1, 1, 10000, TimeUnit.MILLISECONDS, taskQueue);
} }
public ServiceTask startTask(ServiceTask task) {
public static ServiceTaskExecutor getInstance() { execute(task); // task will be run on async thread from pool.
return instance;
}
public static ServiceTask startTask(ServiceTask task) {
instance.execute(task); // task will be run on async thread from pool.
return task; return task;
} }
// FIXME // FIXME
protected void beforeExecute(Thread t, Runnable r) { protected void beforeExecute(Thread t, Runnable r) {
// This is run on either caller UI thread or Service UI thread. // This is run on either caller UI thread or Service UI thread.
ServiceTask task = (ServiceTask)r; ServiceTask task = (ServiceTask) r;
Log.v(TAG, "About to run task " + task.getClass().getSimpleName()); aapsLogger.debug(LTag.PUMPBTCOMM, "About to run task " + task.getClass().getSimpleName());
RileyLinkUtil.setCurrentTask(task); rileyLinkUtil.setCurrentTask(task);
task.preOp(); task.preOp();
} }
@ -51,9 +45,9 @@ public class ServiceTaskExecutor extends ThreadPoolExecutor {
// FIXME // FIXME
protected void afterExecute(Runnable r, Throwable t) { protected void afterExecute(Runnable r, Throwable t) {
// This is run on either caller UI thread or Service UI thread. // This is run on either caller UI thread or Service UI thread.
ServiceTask task = (ServiceTask)r; ServiceTask task = (ServiceTask) r;
task.postOp(); task.postOp();
Log.v(TAG, "Finishing task " + task.getClass().getSimpleName()); aapsLogger.debug(LTag.PUMPBTCOMM, "Finishing task " + task.getClass().getSimpleName());
RileyLinkUtil.finishCurrentTask(task); rileyLinkUtil.finishCurrentTask(task);
} }
} }

View file

@ -1,34 +1,43 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks; package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks;
import info.nightscout.androidaps.plugins.bus.RxBus; import javax.inject.Inject;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.pump.common.PumpPluginAbstract;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceTransport; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceTransport;
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin; import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin;
import info.nightscout.androidaps.plugins.pump.medtronic.events.EventRefreshButtonState; import info.nightscout.androidaps.plugins.pump.medtronic.events.EventRefreshButtonState;
import info.nightscout.androidaps.plugins.pump.medtronic.service.RileyLinkMedtronicService;
/** /**
* Created by geoff on 7/16/16. * Created by geoff on 7/16/16.
*/ */
public class WakeAndTuneTask extends PumpTask { public class WakeAndTuneTask extends PumpTask {
@Inject ActivePluginProvider activePlugin;
@Inject RxBusWrapper rxBus;
private static final String TAG = "WakeAndTuneTask"; private static final String TAG = "WakeAndTuneTask";
public WakeAndTuneTask() { public WakeAndTuneTask(HasAndroidInjector injector) {
super(injector);
} }
public WakeAndTuneTask(ServiceTransport transport) { public WakeAndTuneTask(HasAndroidInjector injector, ServiceTransport transport) {
super(transport); super(injector, transport);
} }
@Override @Override
public void run() { public void run() {
RxBus.Companion.getINSTANCE().send(new EventRefreshButtonState(false)); PumpPluginAbstract pump = (PumpPluginAbstract) activePlugin.getActivePump();
rxBus.send(new EventRefreshButtonState(false));
MedtronicPumpPlugin.isBusy = true; MedtronicPumpPlugin.isBusy = true;
RileyLinkMedtronicService.getInstance().doTuneUpDevice(); pump.doTuneUpDevice();
MedtronicPumpPlugin.isBusy = false; MedtronicPumpPlugin.isBusy = false;
RxBus.Companion.getINSTANCE().send(new EventRefreshButtonState(true)); rxBus.send(new EventRefreshButtonState(true));
} }
} }

View file

@ -1,40 +0,0 @@
package info.nightscout.androidaps.plugins.pump.common.ui;
import android.content.Context;
import androidx.preference.Preference;
import android.util.AttributeSet;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
import info.nightscout.androidaps.utils.SP;
/**
* Created by andy on 10/18/18.
*/
public class RileyLinkSelectPreference extends Preference {
public RileyLinkSelectPreference(Context context) {
super(context);
setInitialSummaryValue();
MedtronicUtil.setRileyLinkSelectPreference(this);
}
public RileyLinkSelectPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setInitialSummaryValue();
MedtronicUtil.setRileyLinkSelectPreference(this);
}
private void setInitialSummaryValue() {
String value = SP.getString("pref_rileylink_mac_address", null);
setSummary(value == null ? MainApp.gs(R.string.rileylink_error_address_not_set_short) : value);
}
}

View file

@ -1,5 +1,6 @@
package info.nightscout.androidaps.plugins.pump.common.utils; package info.nightscout.androidaps.plugins.pump.common.utils;
import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -28,6 +29,14 @@ public class ByteUtil {
return (b < 0) ? b + 256 : b; return (b < 0) ? b + 256 : b;
} }
public static byte[] getBytesFromInt16(int value) {
byte[] array = getBytesFromInt(value);
return new byte[] {array[2], array[3]};
}
public static byte[] getBytesFromInt(int value) {
return ByteBuffer.allocate(4).putInt(value).array();
}
/* For Reference: static void System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length) */ /* For Reference: static void System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length) */
@ -107,6 +116,21 @@ public class ByteUtil {
return rval; return rval;
} }
public static String shortHexStringWithoutSpaces(byte[] byteArray) {
String hexString = "";
if (byteArray == null) {
return hexString;
}
if (byteArray.length == 0) {
return hexString;
}
for (byte b : byteArray) {
hexString = hexString + HEX_DIGITS[(b & 0xF0) >> 4];
hexString = hexString + HEX_DIGITS[(b & 0x0F)];
}
return hexString;
}
public static String shortHexString(List<Byte> list) { public static String shortHexString(List<Byte> list) {
byte[] abyte0 = getByteArrayFromList(list); byte[] abyte0 = getByteArrayFromList(list);

View file

@ -20,14 +20,13 @@ import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
*/ */
public class DateTimeUtil { public class DateTimeUtil {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPCOMM);
/** /**
* DateTime is packed as long: yyyymmddHHMMss * DateTime is packed as long: yyyymmddHHMMss
* *
* @param atechDateTime * @param atechDateTime
* @return * @return
*/ */
@Deprecated // use joda instead
public static LocalDateTime toLocalDateTime(long atechDateTime) { public static LocalDateTime toLocalDateTime(long atechDateTime) {
int year = (int) (atechDateTime / 10000000000L); int year = (int) (atechDateTime / 10000000000L);
atechDateTime -= year * 10000000000L; atechDateTime -= year * 10000000000L;
@ -49,8 +48,7 @@ public class DateTimeUtil {
try { try {
return new LocalDateTime(year, month, dayOfMonth, hourOfDay, minute, second); return new LocalDateTime(year, month, dayOfMonth, hourOfDay, minute, second);
} catch (Exception ex) { } catch (Exception ex) {
if (L.isEnabled(L.PUMPCOMM)) //LOG.error("Error creating LocalDateTime from values [atechDateTime={}, year={}, month={}, day={}, hour={}, minute={}, second={}]. Exception: {}", atechDateTime, year, month, dayOfMonth, hourOfDay, minute, second, ex.getMessage());
LOG.error("Error creating LocalDateTime from values [atechDateTime={}, year={}, month={}, day={}, hour={}, minute={}, second={}]. Exception: {}", atechDateTime, year, month, dayOfMonth, hourOfDay, minute, second, ex.getMessage());
//return null; //return null;
throw ex; throw ex;
} }
@ -63,6 +61,7 @@ public class DateTimeUtil {
* @param atechDateTime * @param atechDateTime
* @return * @return
*/ */
@Deprecated // use joda instead
public static GregorianCalendar toGregorianCalendar(long atechDateTime) { public static GregorianCalendar toGregorianCalendar(long atechDateTime) {
int year = (int) (atechDateTime / 10000000000L); int year = (int) (atechDateTime / 10000000000L);
atechDateTime -= year * 10000000000L; atechDateTime -= year * 10000000000L;
@ -84,8 +83,7 @@ public class DateTimeUtil {
try { try {
return new GregorianCalendar(year, month - 1, dayOfMonth, hourOfDay, minute, second); return new GregorianCalendar(year, month - 1, dayOfMonth, hourOfDay, minute, second);
} catch (Exception ex) { } catch (Exception ex) {
if (L.isEnabled(L.PUMPCOMM)) //LOG.error("DateTimeUtil", String.format("Error creating GregorianCalendar from values [atechDateTime=%d, year=%d, month=%d, day=%d, hour=%d, minute=%d, second=%d]", atechDateTime, year, month, dayOfMonth, hourOfDay, minute, second));
LOG.error("DateTimeUtil", String.format("Error creating GregorianCalendar from values [atechDateTime=%d, year=%d, month=%d, day=%d, hour=%d, minute=%d, second=%d]", atechDateTime, year, month, dayOfMonth, hourOfDay, minute, second));
//return null; //return null;
throw ex; throw ex;
} }
@ -120,6 +118,14 @@ public class DateTimeUtil {
} }
public static long toATechDate(long timeInMillis) {
GregorianCalendar gc = new GregorianCalendar();
gc.setTimeInMillis(timeInMillis);
return toATechDate(gc);
}
public static boolean isSameDay(LocalDateTime ldt1, LocalDateTime ldt2) { public static boolean isSameDay(LocalDateTime ldt1, LocalDateTime ldt2) {
return (ldt1.getYear() == ldt2.getYear() && // return (ldt1.getYear() == ldt2.getYear() && //
@ -276,4 +282,21 @@ public class DateTimeUtil {
} }
public static long getTimeInFutureFromMinutes(long startTime, int minutes) {
return startTime + getTimeInMs(minutes);
}
public static long getTimeInFutureFromMinutes(int minutes) {
return System.currentTimeMillis() + getTimeInMs(minutes);
}
public static long getTimeInMs(int minutes) {
return getTimeInS(minutes) * 1000L;
}
public static int getTimeInS(int minutes) {
return minutes * 60;
}
} }

View file

@ -0,0 +1,54 @@
package info.nightscout.androidaps.plugins.pump.common.utils;
import java.util.Locale;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
public class ProfileUtil {
public static String getProfileDisplayable(Profile profile, PumpType pumpType) {
StringBuilder stringBuilder = new StringBuilder();
for (Profile.ProfileValue basalValue : profile.getBasalValues()) {
double basalValueValue = pumpType.determineCorrectBasalSize(basalValue.value);
int hour = basalValue.timeAsSeconds / (60 * 60);
stringBuilder.append((hour < 10 ? "0" : "") + hour + ":00");
stringBuilder.append(String.format(Locale.ENGLISH, "%.3f", basalValueValue));
stringBuilder.append(", ");
}
if (stringBuilder.length() > 3)
return stringBuilder.toString().substring(0, stringBuilder.length() - 2);
else
return stringBuilder.toString();
}
public static String getBasalProfilesDisplayable(Profile.ProfileValue[] profiles, PumpType pumpType) {
StringBuilder stringBuilder = new StringBuilder();
for (Profile.ProfileValue basalValue : profiles) {
double basalValueValue = pumpType.determineCorrectBasalSize(basalValue.value);
int hour = basalValue.timeAsSeconds / (60 * 60);
stringBuilder.append((hour < 10 ? "0" : "") + hour + ":00");
stringBuilder.append(String.format(Locale.ENGLISH, "%.3f", basalValueValue));
stringBuilder.append(", ");
}
if (stringBuilder.length() > 3)
return stringBuilder.toString().substring(0, stringBuilder.length() - 2);
else
return stringBuilder.toString();
}
}

View file

@ -7,6 +7,8 @@ import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import info.nightscout.androidaps.utils.DateUtil;
/** /**
* Created by geoff on 4/28/15. * Created by geoff on 4/28/15.
* modified by Andy * modified by Andy
@ -83,7 +85,8 @@ public class StringUtil {
public static String toDateTimeString(LocalDateTime localDateTime) { public static String toDateTimeString(LocalDateTime localDateTime) {
return localDateTime.toString("dd.MM.yyyy HH:mm:ss"); return DateUtil.dateAndTimeAndSecondsString(localDateTime.toDateTime().getMillis());
//return localDateTime.toString("dd.MM.yyyy HH:mm:ss");
} }

View file

@ -42,6 +42,7 @@ import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.Round; import info.nightscout.androidaps.utils.Round;
import info.nightscout.androidaps.utils.TimeChangeType;
import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP; import info.nightscout.androidaps.utils.sharedPreferences.SP;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
@ -515,7 +516,6 @@ public abstract class AbstractDanaRPlugin extends PumpPluginBase implements Pump
} }
@Override @Override
public void timeDateOrTimeZoneChanged() { public void timezoneOrDSTChanged(TimeChangeType timeChangeType) {
} }
} }

View file

@ -170,15 +170,15 @@ class DanaRSPlugin @Inject constructor(
// DanaR interface // DanaR interface
override fun loadHistory(type: Byte): PumpEnactResult { override fun loadHistory(type: Byte): PumpEnactResult {
return danaRSService?.loadHistory(type) ?: PumpEnactResult(injector).success(false) return danaRSService?.loadHistory(type) ?: PumpEnactResult(injector).success(false)
} }
override fun loadEvents(): PumpEnactResult { override fun loadEvents(): PumpEnactResult {
return danaRSService?.loadEvents() ?: PumpEnactResult(injector).success(false) return danaRSService?.loadEvents() ?: PumpEnactResult(injector).success(false)
} }
override fun setUserOptions(): PumpEnactResult { override fun setUserOptions(): PumpEnactResult {
return danaRSService?.setUserSettings() ?: PumpEnactResult(injector).success(false) return danaRSService?.setUserSettings() ?: PumpEnactResult(injector).success(false)
} }
// Constraints interface // Constraints interface
@ -300,7 +300,8 @@ class DanaRSPlugin @Inject constructor(
val t = Treatment() val t = Treatment()
t.isSMB = detailedBolusInfo.isSMB t.isSMB = detailedBolusInfo.isSMB
var connectionOK = false var connectionOK = false
if (detailedBolusInfo.insulin > 0 || carbs > 0) connectionOK = danaRSService?.bolus(detailedBolusInfo.insulin, carbs.toInt(), DateUtil.now() + T.mins(carbTime.toLong()).msecs(), t) ?: false if (detailedBolusInfo.insulin > 0 || carbs > 0) connectionOK = danaRSService?.bolus(detailedBolusInfo.insulin, carbs.toInt(), DateUtil.now() + T.mins(carbTime.toLong()).msecs(), t)
?: false
val result = PumpEnactResult(injector) val result = PumpEnactResult(injector)
result.success = connectionOK && abs(detailedBolusInfo.insulin - t.insulin) < pumpDesc.bolusStep result.success = connectionOK && abs(detailedBolusInfo.insulin - t.insulin) < pumpDesc.bolusStep
result.bolusDelivered = t.insulin result.bolusDelivered = t.insulin
@ -428,7 +429,8 @@ class DanaRSPlugin @Inject constructor(
} }
val connectionOK: Boolean val connectionOK: Boolean
connectionOK = if (durationInMinutes == 15 || durationInMinutes == 30) { connectionOK = if (durationInMinutes == 15 || durationInMinutes == 30) {
danaRSService?.tempBasalShortDuration(percentAfterConstraint, durationInMinutes) ?: false danaRSService?.tempBasalShortDuration(percentAfterConstraint, durationInMinutes)
?: false
} else { } else {
val durationInHours = max(durationInMinutes / 60, 1) val durationInHours = max(durationInMinutes / 60, 1)
danaRSService?.tempBasal(percentAfterConstraint, durationInHours) ?: false danaRSService?.tempBasal(percentAfterConstraint, durationInHours) ?: false
@ -493,7 +495,8 @@ class DanaRSPlugin @Inject constructor(
aapsLogger.debug(LTag.PUMP, "setExtendedBolus: Correct extended bolus already set. Current: " + pump.extendedBolusAmount + " Asked: " + insulinAfterConstraint) aapsLogger.debug(LTag.PUMP, "setExtendedBolus: Correct extended bolus already set. Current: " + pump.extendedBolusAmount + " Asked: " + insulinAfterConstraint)
return result return result
} }
val connectionOK = danaRSService?.extendedBolus(insulinAfterConstraint, durationInHalfHours) ?: false val connectionOK = danaRSService?.extendedBolus(insulinAfterConstraint, durationInHalfHours)
?: false
if (connectionOK && pump.isExtendedInProgress && abs(pump.extendedBolusAbsoluteRate - insulinAfterConstraint) < pumpDescription.extendedBolusStep) { if (connectionOK && pump.isExtendedInProgress && abs(pump.extendedBolusAbsoluteRate - insulinAfterConstraint) < pumpDescription.extendedBolusStep) {
result.enacted = true result.enacted = true
result.success = true result.success = true
@ -654,5 +657,5 @@ class DanaRSPlugin @Inject constructor(
override fun getCustomActions(): List<CustomAction>? = null override fun getCustomActions(): List<CustomAction>? = null
override fun executeCustomAction(customActionType: CustomActionType) {} override fun executeCustomAction(customActionType: CustomActionType) {}
override fun canHandleDST(): Boolean = false override fun canHandleDST(): Boolean = false
override fun timeDateOrTimeZoneChanged() {} override fun timezoneOrDSTChanged(timeChangeType: TimeChangeType?) {}
} }

View file

@ -135,6 +135,7 @@ import info.nightscout.androidaps.plugins.pump.insight.utils.ParameterBlockUtil;
import info.nightscout.androidaps.plugins.treatments.Treatment; import info.nightscout.androidaps.plugins.treatments.Treatment;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.TimeChangeType;
import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP; import info.nightscout.androidaps.utils.sharedPreferences.SP;
@ -1684,8 +1685,7 @@ public class LocalInsightPlugin extends PumpPluginBase implements PumpInterface,
} }
@Override @Override
public void timeDateOrTimeZoneChanged() { public void timezoneOrDSTChanged(TimeChangeType changeType) {
} }
} }

View file

@ -32,6 +32,7 @@ import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.InstanceId; import info.nightscout.androidaps.utils.InstanceId;
import info.nightscout.androidaps.utils.TimeChangeType;
import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.resources.ResourceHelper;
@ -289,7 +290,7 @@ public class MDIPlugin extends PumpPluginBase implements PumpInterface {
} }
@Override @Override
public void timeDateOrTimeZoneChanged() { public void timezoneOrDSTChanged(TimeChangeType changeType) {
} }

View file

@ -19,10 +19,10 @@ import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusActivity import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusActivity
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData
import info.nightscout.androidaps.plugins.pump.medtronic.defs.BatteryType import info.nightscout.androidaps.plugins.pump.medtronic.defs.BatteryType
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType
import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState
@ -37,9 +37,9 @@ import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.events.EventQueueChanged import info.nightscout.androidaps.queue.events.EventQueueChanged
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.WarnColors import info.nightscout.androidaps.utils.WarnColors
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.extensions.plusAssign import info.nightscout.androidaps.utils.extensions.plusAssign
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
@ -57,6 +57,10 @@ class MedtronicFragment : DaggerFragment() {
@Inject lateinit var activePlugin: ActivePluginProvider @Inject lateinit var activePlugin: ActivePluginProvider
@Inject lateinit var medtronicPumpPlugin: MedtronicPumpPlugin @Inject lateinit var medtronicPumpPlugin: MedtronicPumpPlugin
@Inject lateinit var warnColors: WarnColors @Inject lateinit var warnColors: WarnColors
@Inject lateinit var rileyLinkUtil: RileyLinkUtil
@Inject lateinit var medtronicUtil: MedtronicUtil
@Inject lateinit var medtronicPumpStatus: MedtronicPumpStatus
@Inject lateinit var rileyLinkServiceData: RileyLinkServiceData
private var disposable: CompositeDisposable = CompositeDisposable() private var disposable: CompositeDisposable = CompositeDisposable()
@ -85,7 +89,7 @@ class MedtronicFragment : DaggerFragment() {
medtronic_pump_status.text = "{fa-bed}" medtronic_pump_status.text = "{fa-bed}"
medtronic_history.setOnClickListener { medtronic_history.setOnClickListener {
if (MedtronicUtil.getPumpStatus().verifyConfiguration()) { if (medtronicPumpPlugin.rileyLinkService?.verifyConfiguration() == true) {
startActivity(Intent(context, MedtronicHistoryActivity::class.java)) startActivity(Intent(context, MedtronicHistoryActivity::class.java))
} else { } else {
displayNotConfiguredDialog() displayNotConfiguredDialog()
@ -93,7 +97,7 @@ class MedtronicFragment : DaggerFragment() {
} }
medtronic_refresh.setOnClickListener { medtronic_refresh.setOnClickListener {
if (!MedtronicUtil.getPumpStatus().verifyConfiguration()) { if (medtronicPumpPlugin.rileyLinkService?.verifyConfiguration() != true) {
displayNotConfiguredDialog() displayNotConfiguredDialog()
} else { } else {
medtronic_refresh.isEnabled = false medtronic_refresh.isEnabled = false
@ -107,7 +111,7 @@ class MedtronicFragment : DaggerFragment() {
} }
medtronic_stats.setOnClickListener { medtronic_stats.setOnClickListener {
if (MedtronicUtil.getPumpStatus().verifyConfiguration()) { if (medtronicPumpPlugin.rileyLinkService?.verifyConfiguration() == true) {
startActivity(Intent(context, RileyLinkStatusActivity::class.java)) startActivity(Intent(context, RileyLinkStatusActivity::class.java))
} else { } else {
displayNotConfiguredDialog() displayNotConfiguredDialog()
@ -147,7 +151,7 @@ class MedtronicFragment : DaggerFragment() {
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ .subscribe({
aapsLogger.debug(LTag.PUMP, "EventMedtronicPumpConfigurationChanged triggered") aapsLogger.debug(LTag.PUMP, "EventMedtronicPumpConfigurationChanged triggered")
MedtronicUtil.getPumpStatus().verifyConfiguration() medtronicPumpPlugin.rileyLinkService?.verifyConfiguration()
updateGUI() updateGUI()
}, { fabricPrivacy.logException(it) }) }, { fabricPrivacy.logException(it) })
disposable += rxBus disposable += rxBus
@ -171,33 +175,24 @@ class MedtronicFragment : DaggerFragment() {
@Synchronized @Synchronized
private fun setDeviceStatus() { private fun setDeviceStatus() {
val pumpStatus: MedtronicPumpStatus = MedtronicUtil.getPumpStatus() val resourceId = rileyLinkServiceData.rileyLinkServiceState.getResourceId(RileyLinkTargetDevice.MedtronicPump)
pumpStatus.rileyLinkServiceState = checkStatusSet(pumpStatus.rileyLinkServiceState, val rileyLinkError = medtronicPumpPlugin.rileyLinkService?.error
RileyLinkUtil.getServiceState()) as RileyLinkServiceState?
val resourceId = pumpStatus.rileyLinkServiceState.getResourceId(RileyLinkTargetDevice.MedtronicPump)
val rileyLinkError = RileyLinkUtil.getError()
medtronic_rl_status.text = medtronic_rl_status.text =
when { when {
pumpStatus.rileyLinkServiceState == RileyLinkServiceState.NotStarted -> resourceHelper.gs(resourceId) rileyLinkServiceData.rileyLinkServiceState == RileyLinkServiceState.NotStarted -> resourceHelper.gs(resourceId)
pumpStatus.rileyLinkServiceState.isConnecting -> "{fa-bluetooth-b spin} " + resourceHelper.gs(resourceId) rileyLinkServiceData.rileyLinkServiceState.isConnecting -> "{fa-bluetooth-b spin} " + resourceHelper.gs(resourceId)
pumpStatus.rileyLinkServiceState.isError && rileyLinkError == null -> "{fa-bluetooth-b} " + resourceHelper.gs(resourceId) rileyLinkServiceData.rileyLinkServiceState.isError && rileyLinkError == null -> "{fa-bluetooth-b} " + resourceHelper.gs(resourceId)
pumpStatus.rileyLinkServiceState.isError && rileyLinkError != null -> "{fa-bluetooth-b} " + resourceHelper.gs(rileyLinkError.getResourceId(RileyLinkTargetDevice.MedtronicPump)) rileyLinkServiceData.rileyLinkServiceState.isError && rileyLinkError != null -> "{fa-bluetooth-b} " + resourceHelper.gs(rileyLinkError.getResourceId(RileyLinkTargetDevice.MedtronicPump))
else -> "{fa-bluetooth-b} " + resourceHelper.gs(resourceId) else -> "{fa-bluetooth-b} " + resourceHelper.gs(resourceId)
} }
medtronic_rl_status.setTextColor(if (rileyLinkError != null) Color.RED else Color.WHITE) medtronic_rl_status.setTextColor(if (rileyLinkError != null) Color.RED else Color.WHITE)
pumpStatus.rileyLinkError = checkStatusSet(pumpStatus.rileyLinkError, RileyLinkUtil.getError()) as RileyLinkError?
medtronic_errors.text = medtronic_errors.text =
pumpStatus.rileyLinkError?.let { rileyLinkServiceData.rileyLinkError?.let {
resourceHelper.gs(it.getResourceId(RileyLinkTargetDevice.MedtronicPump)) resourceHelper.gs(it.getResourceId(RileyLinkTargetDevice.MedtronicPump))
} ?: "-" } ?: "-"
pumpStatus.pumpDeviceState = checkStatusSet(pumpStatus.pumpDeviceState, when (medtronicPumpStatus.pumpDeviceState) {
MedtronicUtil.getPumpDeviceState()) as PumpDeviceState?
when (pumpStatus.pumpDeviceState) {
null, null,
PumpDeviceState.Sleeping -> medtronic_pump_status.text = "{fa-bed} " // + pumpStatus.pumpDeviceState.name()); PumpDeviceState.Sleeping -> medtronic_pump_status.text = "{fa-bed} " // + pumpStatus.pumpDeviceState.name());
PumpDeviceState.NeverContacted, PumpDeviceState.NeverContacted,
@ -205,20 +200,20 @@ class MedtronicFragment : DaggerFragment() {
PumpDeviceState.PumpUnreachable, PumpDeviceState.PumpUnreachable,
PumpDeviceState.ErrorWhenCommunicating, PumpDeviceState.ErrorWhenCommunicating,
PumpDeviceState.TimeoutWhenCommunicating, PumpDeviceState.TimeoutWhenCommunicating,
PumpDeviceState.InvalidConfiguration -> medtronic_pump_status.text = " " + resourceHelper.gs(pumpStatus.pumpDeviceState.resourceId) PumpDeviceState.InvalidConfiguration -> medtronic_pump_status.text = " " + resourceHelper.gs(medtronicPumpStatus.pumpDeviceState.resourceId)
PumpDeviceState.Active -> { PumpDeviceState.Active -> {
val cmd = MedtronicUtil.getCurrentCommand() val cmd = medtronicUtil.getCurrentCommand()
if (cmd == null) if (cmd == null)
medtronic_pump_status.text = " " + resourceHelper.gs(pumpStatus.pumpDeviceState.resourceId) medtronic_pump_status.text = " " + resourceHelper.gs(medtronicPumpStatus.pumpDeviceState.resourceId)
else { else {
aapsLogger.debug(LTag.PUMP, "Command: " + cmd) aapsLogger.debug(LTag.PUMP, "Command: " + cmd)
val cmdResourceId = cmd.resourceId val cmdResourceId = cmd.resourceId
if (cmd == MedtronicCommandType.GetHistoryData) { if (cmd == MedtronicCommandType.GetHistoryData) {
medtronic_pump_status.text = MedtronicUtil.frameNumber?.let { medtronic_pump_status.text = medtronicUtil.frameNumber?.let {
resourceHelper.gs(cmdResourceId, MedtronicUtil.pageNumber, MedtronicUtil.frameNumber) resourceHelper.gs(cmdResourceId, medtronicUtil.pageNumber, medtronicUtil.frameNumber)
} }
?: resourceHelper.gs(R.string.medtronic_cmd_desc_get_history_request, MedtronicUtil.pageNumber) ?: resourceHelper.gs(R.string.medtronic_cmd_desc_get_history_request, medtronicUtil.pageNumber)
} else { } else {
medtronic_pump_status.text = " " + (cmdResourceId?.let { resourceHelper.gs(it) } medtronic_pump_status.text = " " + (cmdResourceId?.let { resourceHelper.gs(it) }
?: cmd.getCommandDescription()) ?: cmd.getCommandDescription())
@ -226,7 +221,7 @@ class MedtronicFragment : DaggerFragment() {
} }
} }
else -> aapsLogger.warn(LTag.PUMP, "Unknown pump state: " + pumpStatus.pumpDeviceState) else -> aapsLogger.warn(LTag.PUMP, "Unknown pump state: " + medtronicPumpStatus.pumpDeviceState)
} }
val status = commandQueue.spannedStatus() val status = commandQueue.spannedStatus()
@ -238,17 +233,6 @@ class MedtronicFragment : DaggerFragment() {
} }
} }
private fun checkStatusSet(object1: Any?, object2: Any?): Any? {
return if (object1 == null) {
object2
} else {
if (object1 != object2) {
object2
} else
object1
}
}
private fun displayNotConfiguredDialog() { private fun displayNotConfiguredDialog() {
context?.let { context?.let {
OKDialog.show(it, resourceHelper.gs(R.string.combo_warning), OKDialog.show(it, resourceHelper.gs(R.string.combo_warning),
@ -260,18 +244,17 @@ class MedtronicFragment : DaggerFragment() {
@Synchronized @Synchronized
fun updateGUI() { fun updateGUI() {
if (medtronic_rl_status == null) return if (medtronic_rl_status == null) return
val pumpStatus = MedtronicUtil.getPumpStatus()
setDeviceStatus() setDeviceStatus()
// last connection // last connection
if (pumpStatus.lastConnection != 0L) { if (medtronicPumpStatus.lastConnection != 0L) {
val minAgo = DateUtil.minAgo(resourceHelper, pumpStatus.lastConnection) val minAgo = DateUtil.minAgo(resourceHelper, medtronicPumpStatus.lastConnection)
val min = (System.currentTimeMillis() - pumpStatus.lastConnection) / 1000 / 60 val min = (System.currentTimeMillis() - medtronicPumpStatus.lastConnection) / 1000 / 60
if (pumpStatus.lastConnection + 60 * 1000 > System.currentTimeMillis()) { if (medtronicPumpStatus.lastConnection + 60 * 1000 > System.currentTimeMillis()) {
medtronic_lastconnection.setText(R.string.combo_pump_connected_now) medtronic_lastconnection.setText(R.string.combo_pump_connected_now)
medtronic_lastconnection.setTextColor(Color.WHITE) medtronic_lastconnection.setTextColor(Color.WHITE)
} else if (pumpStatus.lastConnection + 30 * 60 * 1000 < System.currentTimeMillis()) { } else if (medtronicPumpStatus.lastConnection + 30 * 60 * 1000 < System.currentTimeMillis()) {
if (min < 60) { if (min < 60) {
medtronic_lastconnection.text = resourceHelper.gs(R.string.minago, min) medtronic_lastconnection.text = resourceHelper.gs(R.string.minago, min)
@ -294,19 +277,19 @@ class MedtronicFragment : DaggerFragment() {
} }
// last bolus // last bolus
val bolus = pumpStatus.lastBolusAmount val bolus = medtronicPumpStatus.lastBolusAmount
val bolusTime = pumpStatus.lastBolusTime val bolusTime = medtronicPumpStatus.lastBolusTime
if (bolus != null && bolusTime != null) { if (bolus != null && bolusTime != null) {
val agoMsc = System.currentTimeMillis() - pumpStatus.lastBolusTime.time val agoMsc = System.currentTimeMillis() - medtronicPumpStatus.lastBolusTime.time
val bolusMinAgo = agoMsc.toDouble() / 60.0 / 1000.0 val bolusMinAgo = agoMsc.toDouble() / 60.0 / 1000.0
val unit = resourceHelper.gs(R.string.insulin_unit_shortname) val unit = resourceHelper.gs(R.string.insulin_unit_shortname)
val ago: String val ago: String
if (agoMsc < 60 * 1000) { if (agoMsc < 60 * 1000) {
ago = resourceHelper.gs(R.string.combo_pump_connected_now) ago = resourceHelper.gs(R.string.combo_pump_connected_now)
} else if (bolusMinAgo < 60) { } else if (bolusMinAgo < 60) {
ago = DateUtil.minAgo(resourceHelper, pumpStatus.lastBolusTime.time) ago = DateUtil.minAgo(resourceHelper, medtronicPumpStatus.lastBolusTime.time)
} else { } else {
ago = DateUtil.hourAgo(pumpStatus.lastBolusTime.time, resourceHelper) ago = DateUtil.hourAgo(medtronicPumpStatus.lastBolusTime.time, resourceHelper)
} }
medtronic_lastbolus.text = resourceHelper.gs(R.string.combo_last_bolus, bolus, unit, ago) medtronic_lastbolus.text = resourceHelper.gs(R.string.combo_last_bolus, bolus, unit, ago)
} else { } else {
@ -314,24 +297,25 @@ class MedtronicFragment : DaggerFragment() {
} }
// base basal rate // base basal rate
medtronic_basabasalrate.text = ("(" + pumpStatus.activeProfileName + ") " medtronic_basabasalrate.text = ("(" + medtronicPumpStatus.activeProfileName + ") "
+ resourceHelper.gs(R.string.pump_basebasalrate, medtronicPumpPlugin.baseBasalRate)) + resourceHelper.gs(R.string.pump_basebasalrate, medtronicPumpPlugin.baseBasalRate))
medtronic_tempbasal.text = activePlugin.activeTreatments.getTempBasalFromHistory(System.currentTimeMillis())?.toStringFull() medtronic_tempbasal.text = activePlugin.activeTreatments.getTempBasalFromHistory(System.currentTimeMillis())?.toStringFull()
?: "" ?: ""
// battery // battery
if (MedtronicUtil.getBatteryType() == BatteryType.None || pumpStatus.batteryVoltage == null) { if (medtronicPumpStatus.batteryType == BatteryType.None || medtronicPumpStatus.batteryVoltage == null) {
medtronic_pumpstate_battery.text = "{fa-battery-" + pumpStatus.batteryRemaining / 25 + "} " medtronic_pumpstate_battery.text = "{fa-battery-" + medtronicPumpStatus.batteryRemaining / 25 + "} "
} else { } else {
medtronic_pumpstate_battery.text = "{fa-battery-" + pumpStatus.batteryRemaining / 25 + "} " + pumpStatus.batteryRemaining + "%" + String.format(" (%.2f V)", pumpStatus.batteryVoltage) medtronic_pumpstate_battery.text = "{fa-battery-" + medtronicPumpStatus.batteryRemaining / 25 + "} " + medtronicPumpStatus.batteryRemaining + "%" + String.format(" (%.2f V)", medtronicPumpStatus.batteryVoltage)
} }
warnColors.setColorInverse(medtronic_pumpstate_battery, pumpStatus.batteryRemaining.toDouble(), 25.0, 10.0) warnColors.setColorInverse(medtronic_pumpstate_battery, medtronicPumpStatus.batteryRemaining.toDouble(), 25.0, 10.0)
// reservoir // reservoir
medtronic_reservoir.text = resourceHelper.gs(R.string.reservoirvalue, pumpStatus.reservoirRemainingUnits, pumpStatus.reservoirFullUnits) medtronic_reservoir.text = resourceHelper.gs(R.string.reservoirvalue, medtronicPumpStatus.reservoirRemainingUnits, medtronicPumpStatus.reservoirFullUnits)
warnColors.setColorInverse(medtronic_reservoir, pumpStatus.reservoirRemainingUnits, 50.0, 20.0) warnColors.setColorInverse(medtronic_reservoir, medtronicPumpStatus.reservoirRemainingUnits, 50.0, 20.0)
medtronic_errors.text = pumpStatus.errorInfo medtronicPumpPlugin.rileyLinkService?.verifyConfiguration()
medtronic_errors.text = medtronicPumpStatus.errorInfo
} }
} }

View file

@ -8,7 +8,10 @@ import android.os.IBinder;
import android.os.SystemClock; import android.os.SystemClock;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
import org.jetbrains.annotations.NotNull;
import org.joda.time.LocalDateTime; import org.joda.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
@ -34,7 +37,6 @@ import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.events.EventCustomActionsChanged;
import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.interfaces.ActivePluginProvider; import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.interfaces.CommandQueueProvider; import info.nightscout.androidaps.interfaces.CommandQueueProvider;
@ -50,18 +52,19 @@ import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType;
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification; import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
import info.nightscout.androidaps.plugins.pump.common.PumpPluginAbstract; import info.nightscout.androidaps.plugins.pump.common.PumpPluginAbstract;
import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState; import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ResetRileyLinkConfigurationTask; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ResetRileyLinkConfigurationTask;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTaskExecutor; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTaskExecutor;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.WakeAndTuneTask; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.WakeAndTuneTask;
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil; import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager;
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry; import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry;
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryResult; import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryResult;
import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUIComm;
import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUITask; import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUITask;
import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryData; import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryData;
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BasalProfile; import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BasalProfile;
@ -81,10 +84,10 @@ import info.nightscout.androidaps.plugins.pump.medtronic.service.RileyLinkMedtro
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicConst; import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicConst;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil; import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.TimeChangeType;
import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP; import info.nightscout.androidaps.utils.sharedPreferences.SP;
import static info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil.sendNotification;
/** /**
* Created by andy on 23.04.18. * Created by andy on 23.04.18.
@ -95,19 +98,21 @@ import static info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUt
public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInterface { public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInterface {
private final SP sp; private final SP sp;
private final RileyLinkUtil rileyLinkUtil;
private final MedtronicUtil medtronicUtil;
private final MedtronicPumpStatus medtronicPumpStatus;
private final MedtronicHistoryData medtronicHistoryData;
private final RileyLinkServiceData rileyLinkServiceData;
private final ServiceTaskExecutor serviceTaskExecutor;
protected static MedtronicPumpPlugin plugin = null; protected static MedtronicPumpPlugin plugin = null;
private RileyLinkMedtronicService medtronicService; private RileyLinkMedtronicService rileyLinkMedtronicService;
private MedtronicPumpStatus pumpStatusLocal = null;
private MedtronicUIComm medtronicUIComm;
// variables for handling statuses and history // variables for handling statuses and history
private boolean firstRun = true; private boolean firstRun = true;
private boolean isRefresh = false; private boolean isRefresh = false;
private Map<MedtronicStatusRefreshType, Long> statusRefreshMap = new HashMap<>(); private Map<MedtronicStatusRefreshType, Long> statusRefreshMap = new HashMap<>();
private boolean isInitialized = false; private boolean isInitialized = false;
private MedtronicHistoryData medtronicHistoryData;
private MedtronicCommunicationManager medtronicCommunicationManager;
private PumpHistoryEntry lastPumpHistoryEntry; private PumpHistoryEntry lastPumpHistoryEntry;
public static boolean isBusy = false; public static boolean isBusy = false;
@ -125,7 +130,13 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
ActivePluginProvider activePlugin, ActivePluginProvider activePlugin,
SP sp, SP sp,
CommandQueueProvider commandQueue, CommandQueueProvider commandQueue,
FabricPrivacy fabricPrivacy FabricPrivacy fabricPrivacy,
RileyLinkUtil rileyLinkUtil,
MedtronicUtil medtronicUtil,
MedtronicPumpStatus medtronicPumpStatus,
MedtronicHistoryData medtronicHistoryData,
RileyLinkServiceData rileyLinkServiceData,
ServiceTaskExecutor serviceTaskExecutor
) { ) {
super(new PluginDescription() // super(new PluginDescription() //
@ -133,14 +144,20 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
.fragmentClass(MedtronicFragment.class.getName()) // .fragmentClass(MedtronicFragment.class.getName()) //
.pluginName(R.string.medtronic_name) // .pluginName(R.string.medtronic_name) //
.shortName(R.string.medtronic_name_short) // .shortName(R.string.medtronic_name_short) //
.preferencesId(R.xml.pref_medtronic).description(R.string.description_pump_medtronic), // .preferencesId(R.xml.pref_medtronic)
.description(R.string.description_pump_medtronic), //
PumpType.Medtronic_522_722, // we default to most basic model, correct model from config is loaded later PumpType.Medtronic_522_722, // we default to most basic model, correct model from config is loaded later
injector, resourceHelper, aapsLogger, commandQueue, rxBus, activePlugin, context, fabricPrivacy injector, resourceHelper, aapsLogger, commandQueue, rxBus, activePlugin, sp, context, fabricPrivacy
); );
this.plugin = this; this.plugin = this;
this.rxBus = rxBus; this.rileyLinkUtil = rileyLinkUtil;
this.medtronicUtil = medtronicUtil;
this.sp = sp; this.sp = sp;
this.medtronicPumpStatus = medtronicPumpStatus;
this.medtronicHistoryData = medtronicHistoryData;
this.rileyLinkServiceData = rileyLinkServiceData;
this.serviceTaskExecutor = serviceTaskExecutor;
displayConnectionMessages = false; displayConnectionMessages = false;
@ -148,24 +165,22 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
public void onServiceDisconnected(ComponentName name) { public void onServiceDisconnected(ComponentName name) {
aapsLogger.debug(LTag.PUMP, "RileyLinkMedtronicService is disconnected"); aapsLogger.debug(LTag.PUMP, "RileyLinkMedtronicService is disconnected");
medtronicService = null; rileyLinkMedtronicService = null;
} }
public void onServiceConnected(ComponentName name, IBinder service) { public void onServiceConnected(ComponentName name, IBinder service) {
aapsLogger.debug(LTag.PUMP, "RileyLinkMedtronicService is connected"); aapsLogger.debug(LTag.PUMP, "RileyLinkMedtronicService is connected");
RileyLinkMedtronicService.LocalBinder mLocalBinder = (RileyLinkMedtronicService.LocalBinder) service; RileyLinkMedtronicService.LocalBinder mLocalBinder = (RileyLinkMedtronicService.LocalBinder) service;
medtronicService = mLocalBinder.getServiceInstance(); rileyLinkMedtronicService = mLocalBinder.getServiceInstance();
new Thread(() -> { new Thread(() -> {
for (int i = 0; i < 20; i++) { for (int i = 0; i < 20; i++) {
SystemClock.sleep(5000); SystemClock.sleep(5000);
if (MedtronicUtil.getPumpStatus() != null) { aapsLogger.debug(LTag.PUMP, "Starting Medtronic-RileyLink service");
aapsLogger.debug(LTag.PUMP, "Starting Medtronic-RileyLink service"); if (rileyLinkMedtronicService.setNotInPreInit()) {
if (MedtronicUtil.getPumpStatus().setNotInPreInit()) { break;
break;
}
} }
} }
}).start(); }).start();
@ -177,8 +192,6 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
@Override @Override
protected void onStart() { protected void onStart() {
super.onStart(); super.onStart();
medtronicUIComm = new MedtronicUIComm(aapsLogger, rxBus, getResourceHelper());
medtronicHistoryData = new MedtronicHistoryData(aapsLogger, sp, activePlugin);
} }
@Deprecated @Deprecated
@ -189,34 +202,33 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
} }
@Override
public void updatePreferenceSummary(@NotNull Preference pref) {
super.updatePreferenceSummary(pref);
if (pref.getKey().equals(getResourceHelper().gs(R.string.key_rileylink_mac_address))) {
String value = sp.getStringOrNull(R.string.key_rileylink_mac_address, null);
pref.setSummary(value == null ? getResourceHelper().gs(R.string.rileylink_error_address_not_set_short) : value);
}
}
private String getLogPrefix() { private String getLogPrefix() {
return "MedtronicPumpPlugin::"; return "MedtronicPumpPlugin::";
} }
public MedtronicHistoryData getMedtronicHistoryData() {
return this.medtronicHistoryData;
}
@Override @Override
public void initPumpStatusData() { public void initPumpStatusData() {
this.pumpStatusLocal = new MedtronicPumpStatus(pumpDescription); medtronicPumpStatus.lastConnection = sp.getLong(RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L);
MedtronicUtil.setPumpStatus(pumpStatusLocal); medtronicPumpStatus.lastDataTime = medtronicPumpStatus.lastConnection;
medtronicPumpStatus.previousConnection = medtronicPumpStatus.lastConnection;
pumpStatusLocal.lastConnection = sp.getLong(RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L); if (rileyLinkMedtronicService != null) rileyLinkMedtronicService.verifyConfiguration();
pumpStatusLocal.lastDataTime = new LocalDateTime(pumpStatusLocal.lastConnection);
pumpStatusLocal.previousConnection = pumpStatusLocal.lastConnection;
pumpStatusLocal.refreshConfiguration(); aapsLogger.debug(LTag.PUMP, "initPumpStatusData: " + this.medtronicPumpStatus);
aapsLogger.debug(LTag.PUMP, "initPumpStatusData: " + this.pumpStatusLocal);
this.pumpStatus = pumpStatusLocal;
// this is only thing that can change, by being configured // this is only thing that can change, by being configured
pumpDescription.maxTempAbsolute = (pumpStatusLocal.maxBasal != null) ? pumpStatusLocal.maxBasal : 35.0d; pumpDescription.maxTempAbsolute = (medtronicPumpStatus.maxBasal != null) ? medtronicPumpStatus.maxBasal : 35.0d;
// set first Medtronic Pump Start // set first Medtronic Pump Start
if (!sp.contains(MedtronicConst.Statistics.FirstPumpStart)) { if (!sp.contains(MedtronicConst.Statistics.FirstPumpStart)) {
@ -227,6 +239,15 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
} }
@Override
public void resetRileyLinkConfiguration() {
rileyLinkMedtronicService.resetRileyLinkConfiguration();
}
@Override public void doTuneUpDevice() {
rileyLinkMedtronicService.doTuneUpDevice();
}
private void migrateSettings() { private void migrateSettings() {
if ("US (916 MHz)".equals(sp.getString(MedtronicConst.Prefs.PumpFrequency, "US (916 MHz)"))) { if ("US (916 MHz)".equals(sp.getString(MedtronicConst.Prefs.PumpFrequency, "US (916 MHz)"))) {
@ -277,6 +298,9 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
return RileyLinkMedtronicService.class; return RileyLinkMedtronicService.class;
} }
@Override public PumpStatus getPumpStatusData() {
return medtronicPumpStatus;
}
@Override @Override
public String deviceID() { public String deviceID() {
@ -299,9 +323,13 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
// Pump Plugin // Pump Plugin
private boolean isServiceSet() { private boolean isServiceSet() {
return medtronicService != null; return rileyLinkMedtronicService != null;
} }
@Nullable
public RileyLinkMedtronicService getRileyLinkService() {
return rileyLinkMedtronicService;
}
@Override @Override
public boolean isInitialized() { public boolean isInitialized() {
@ -366,7 +394,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
public boolean isConnected() { public boolean isConnected() {
if (displayConnectionMessages) if (displayConnectionMessages)
aapsLogger.debug(LTag.PUMP, "MedtronicPumpPlugin::isConnected"); aapsLogger.debug(LTag.PUMP, "MedtronicPumpPlugin::isConnected");
return isServiceSet() && medtronicService.isInitialized(); return isServiceSet() && rileyLinkMedtronicService.isInitialized();
} }
@ -374,15 +402,13 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
public boolean isConnecting() { public boolean isConnecting() {
if (displayConnectionMessages) if (displayConnectionMessages)
aapsLogger.debug(LTag.PUMP, "MedtronicPumpPlugin::isConnecting"); aapsLogger.debug(LTag.PUMP, "MedtronicPumpPlugin::isConnecting");
return !isServiceSet() || !medtronicService.isInitialized(); return !isServiceSet() || !rileyLinkMedtronicService.isInitialized();
} }
@Override @Override
public void getPumpStatus() { public void getPumpStatus() {
getMDTPumpStatus();
if (firstRun) { if (firstRun) {
initializePump(!isRefresh); initializePump(!isRefresh);
} else { } else {
@ -401,7 +427,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
private boolean isPumpNotReachable() { private boolean isPumpNotReachable() {
RileyLinkServiceState rileyLinkServiceState = MedtronicUtil.getServiceState(); RileyLinkServiceState rileyLinkServiceState = rileyLinkServiceData.rileyLinkServiceState;
if (rileyLinkServiceState == null) { if (rileyLinkServiceState == null) {
aapsLogger.debug(LTag.PUMP, "RileyLink unreachable. RileyLinkServiceState is null."); aapsLogger.debug(LTag.PUMP, "RileyLink unreachable. RileyLinkServiceState is null.");
@ -415,7 +441,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
return false; return false;
} }
return (!medtronicCommunicationManager.isDeviceReachable()); return (!rileyLinkMedtronicService.getDeviceCommunicationManager().isDeviceReachable());
} }
@ -432,12 +458,12 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
if (isPumpNotReachable()) { if (isPumpNotReachable()) {
aapsLogger.error("Pump unreachable."); aapsLogger.error("Pump unreachable.");
MedtronicUtil.sendNotification(MedtronicNotificationType.PumpUnreachable, getResourceHelper(), rxBus); medtronicUtil.sendNotification(MedtronicNotificationType.PumpUnreachable, getResourceHelper(), rxBus);
return; return;
} }
MedtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus); medtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus);
if (hasTimeDateOrTimeZoneChanged) { if (hasTimeDateOrTimeZoneChanged) {
@ -471,14 +497,14 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
case BatteryStatus: case BatteryStatus:
case RemainingInsulin: { case RemainingInsulin: {
medtronicUIComm.executeCommand(refreshType.getKey().getCommandType()); rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(refreshType.getKey().getCommandType(medtronicUtil.getMedtronicPumpModel()));
refreshTypesNeededToReschedule.add(refreshType.getKey()); refreshTypesNeededToReschedule.add(refreshType.getKey());
resetTime = true; resetTime = true;
} }
break; break;
case Configuration: { case Configuration: {
medtronicUIComm.executeCommand(refreshType.getKey().getCommandType()); rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(refreshType.getKey().getCommandType(medtronicUtil.getMedtronicPumpModel()));
resetTime = true; resetTime = true;
} }
break; break;
@ -493,7 +519,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
} }
if (resetTime) if (resetTime)
pumpStatusLocal.setLastCommunicationToNow(); medtronicPumpStatus.setLastCommunicationToNow();
} }
@ -520,35 +546,30 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
aapsLogger.info(LTag.PUMP, getLogPrefix() + "initializePump - start"); aapsLogger.info(LTag.PUMP, getLogPrefix() + "initializePump - start");
if (medtronicCommunicationManager == null) { rileyLinkMedtronicService.getDeviceCommunicationManager().setDoWakeUpBeforeCommand(false);
medtronicCommunicationManager = MedtronicCommunicationManager.getInstance();
medtronicCommunicationManager.setDoWakeUpBeforeCommand(false);
}
setRefreshButtonEnabled(false); setRefreshButtonEnabled(false);
getMDTPumpStatus();
if (isRefresh) { if (isRefresh) {
if (isPumpNotReachable()) { if (isPumpNotReachable()) {
aapsLogger.error(getLogPrefix() + "initializePump::Pump unreachable."); aapsLogger.error(getLogPrefix() + "initializePump::Pump unreachable.");
MedtronicUtil.sendNotification(MedtronicNotificationType.PumpUnreachable, getResourceHelper(), rxBus); medtronicUtil.sendNotification(MedtronicNotificationType.PumpUnreachable, getResourceHelper(), rxBus);
setRefreshButtonEnabled(true); setRefreshButtonEnabled(true);
return; return;
} }
MedtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus); medtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus);
} }
// model (once) // model (once)
if (MedtronicUtil.getMedtronicPumpModel() == null) { if (medtronicUtil.getMedtronicPumpModel() == null) {
medtronicUIComm.executeCommand(MedtronicCommandType.PumpModel); rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.PumpModel);
} else { } else {
if (pumpStatusLocal.medtronicDeviceType != MedtronicUtil.getMedtronicPumpModel()) { if (medtronicPumpStatus.medtronicDeviceType != medtronicUtil.getMedtronicPumpModel()) {
aapsLogger.warn(LTag.PUMP, getLogPrefix() + "Configured pump is not the same as one detected."); aapsLogger.warn(LTag.PUMP, getLogPrefix() + "Configured pump is not the same as one detected.");
MedtronicUtil.sendNotification(MedtronicNotificationType.PumpTypeNotSame, getResourceHelper(), rxBus); medtronicUtil.sendNotification(MedtronicNotificationType.PumpTypeNotSame, getResourceHelper(), rxBus);
} }
} }
@ -560,29 +581,29 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
readPumpHistory(); readPumpHistory();
// remaining insulin (>50 = 4h; 50-20 = 1h; 15m) // remaining insulin (>50 = 4h; 50-20 = 1h; 15m)
medtronicUIComm.executeCommand(MedtronicCommandType.GetRemainingInsulin); rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.GetRemainingInsulin);
scheduleNextRefresh(MedtronicStatusRefreshType.RemainingInsulin, 10); scheduleNextRefresh(MedtronicStatusRefreshType.RemainingInsulin, 10);
// remaining power (1h) // remaining power (1h)
medtronicUIComm.executeCommand(MedtronicCommandType.GetBatteryStatus); rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.GetBatteryStatus);
scheduleNextRefresh(MedtronicStatusRefreshType.BatteryStatus, 20); scheduleNextRefresh(MedtronicStatusRefreshType.BatteryStatus, 20);
// configuration (once and then if history shows config changes) // configuration (once and then if history shows config changes)
medtronicUIComm.executeCommand(MedtronicCommandType.getSettings(MedtronicUtil.getMedtronicPumpModel())); rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.getSettings(medtronicUtil.getMedtronicPumpModel()));
// read profile (once, later its controlled by isThisProfileSet method) // read profile (once, later its controlled by isThisProfileSet method)
getBasalProfiles(); getBasalProfiles();
int errorCount = medtronicUIComm.getInvalidResponsesCount(); int errorCount = rileyLinkMedtronicService.getMedtronicUIComm().getInvalidResponsesCount();
if (errorCount >= 5) { if (errorCount >= 5) {
aapsLogger.error("Number of error counts was 5 or more. Starting tunning."); aapsLogger.error("Number of error counts was 5 or more. Starting tunning.");
setRefreshButtonEnabled(true); setRefreshButtonEnabled(true);
ServiceTaskExecutor.startTask(new WakeAndTuneTask()); serviceTaskExecutor.startTask(new WakeAndTuneTask(getInjector()));
return; return;
} }
pumpStatusLocal.setLastCommunicationToNow(); medtronicPumpStatus.setLastCommunicationToNow();
setRefreshButtonEnabled(true); setRefreshButtonEnabled(true);
if (!isRefresh) { if (!isRefresh) {
@ -597,42 +618,37 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
private void getBasalProfiles() { private void getBasalProfiles() {
MedtronicUITask medtronicUITask = medtronicUIComm.executeCommand(MedtronicCommandType.GetBasalProfileSTD); MedtronicUITask medtronicUITask = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.GetBasalProfileSTD);
if (medtronicUITask.getResponseType() == MedtronicUIResponseType.Error) { if (medtronicUITask.getResponseType() == MedtronicUIResponseType.Error) {
medtronicUIComm.executeCommand(MedtronicCommandType.GetBasalProfileSTD); rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.GetBasalProfileSTD);
} }
} }
@Override @Override
public boolean isThisProfileSet(Profile profile) { public boolean isThisProfileSet(Profile profile) {
MedtronicPumpStatus mdtPumpStatus = getMDTPumpStatus(); aapsLogger.debug(LTag.PUMP, "isThisProfileSet: basalInitalized=" + medtronicPumpStatus.basalProfileStatus);
aapsLogger.debug(LTag.PUMP, "isThisProfileSet: basalInitalized=" + mdtPumpStatus.basalProfileStatus);
if (!isInitialized) if (!isInitialized)
return true; return true;
if (mdtPumpStatus.basalProfileStatus == BasalProfileStatus.NotInitialized) { if (medtronicPumpStatus.basalProfileStatus == BasalProfileStatus.NotInitialized) {
// this shouldn't happen, but if there was problem we try again // this shouldn't happen, but if there was problem we try again
getBasalProfiles(); getBasalProfiles();
return isProfileSame(profile); return isProfileSame(profile);
} else if (mdtPumpStatus.basalProfileStatus == BasalProfileStatus.ProfileChanged) { } else if (medtronicPumpStatus.basalProfileStatus == BasalProfileStatus.ProfileChanged) {
return false; return false;
} else {
} }
return (medtronicPumpStatus.basalProfileStatus != BasalProfileStatus.ProfileOK) || isProfileSame(profile);
return (getMDTPumpStatus().basalProfileStatus != BasalProfileStatus.ProfileOK) || isProfileSame(profile);
} }
private boolean isProfileSame(Profile profile) { private boolean isProfileSame(Profile profile) {
boolean invalid = false; boolean invalid = false;
Double[] basalsByHour = getMDTPumpStatus().basalsByHour; Double[] basalsByHour = medtronicPumpStatus.basalsByHour;
PumpType pumpType = getMDTPumpStatus().getPumpType();
aapsLogger.debug(LTag.PUMP, "Current Basals (h): " aapsLogger.debug(LTag.PUMP, "Current Basals (h): "
+ (basalsByHour == null ? "null" : BasalProfile.getProfilesByHourToString(basalsByHour))); + (basalsByHour == null ? "null" : BasalProfile.getProfilesByHourToString(basalsByHour)));
@ -646,11 +662,11 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
for (Profile.ProfileValue basalValue : profile.getBasalValues()) { for (Profile.ProfileValue basalValue : profile.getBasalValues()) {
double basalValueValue = pumpType.determineCorrectBasalSize(basalValue.value); double basalValueValue = pumpDescription.pumpType.determineCorrectBasalSize(basalValue.value);
int hour = basalValue.timeAsSeconds / (60 * 60); int hour = basalValue.timeAsSeconds / (60 * 60);
if (!MedtronicUtil.isSame(basalsByHour[hour], basalValueValue)) { if (!medtronicUtil.isSame(basalsByHour[hour], basalValueValue)) {
invalid = true; invalid = true;
} }
@ -672,10 +688,9 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
@Override @Override
public long lastDataTime() { public long lastDataTime() {
getMDTPumpStatus();
if (pumpStatusLocal.lastConnection != 0) { if (medtronicPumpStatus.lastConnection != 0) {
return pumpStatusLocal.lastConnection; return medtronicPumpStatus.lastConnection;
} }
return System.currentTimeMillis(); return System.currentTimeMillis();
@ -684,33 +699,21 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
@Override @Override
public double getBaseBasalRate() { public double getBaseBasalRate() {
return getMDTPumpStatus().getBasalProfileForHour(); return medtronicPumpStatus.getBasalProfileForHour();
} }
@Override @Override
public double getReservoirLevel() { public double getReservoirLevel() {
return getMDTPumpStatus().reservoirRemainingUnits; return medtronicPumpStatus.reservoirRemainingUnits;
} }
@Override @Override
public int getBatteryLevel() { public int getBatteryLevel() {
return getMDTPumpStatus().batteryRemaining; return medtronicPumpStatus.batteryRemaining;
} }
private MedtronicPumpStatus getMDTPumpStatus() {
if (pumpStatusLocal == null) {
// FIXME I don't know why this happens
aapsLogger.warn(LTag.PUMP, "!!!! Reset Pump Status Local");
pumpStatusLocal = MedtronicUtil.getPumpStatus();
}
return pumpStatusLocal;
}
protected void triggerUIChange() { protected void triggerUIChange() {
rxBus.send(new EventMedtronicPumpValuesChanged()); rxBus.send(new EventMedtronicPumpValuesChanged());
} }
@ -737,16 +740,16 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
return; return;
} }
MedtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus); medtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus);
medtronicUIComm.executeCommand(MedtronicCommandType.GetRealTimeClock); rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.GetRealTimeClock);
ClockDTO clock = MedtronicUtil.getPumpTime(); ClockDTO clock = medtronicUtil.getPumpTime();
if (clock == null) { // retry if (clock == null) { // retry
medtronicUIComm.executeCommand(MedtronicCommandType.GetRealTimeClock); rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.GetRealTimeClock);
clock = MedtronicUtil.getPumpTime(); clock = medtronicUtil.getPumpTime();
} }
if (clock == null) if (clock == null)
@ -760,7 +763,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
aapsLogger.info(LTag.PUMP, "MedtronicPumpPlugin::checkTimeAndOptionallySetTime - Time difference is {} s. Set time on pump." + timeDiff); aapsLogger.info(LTag.PUMP, "MedtronicPumpPlugin::checkTimeAndOptionallySetTime - Time difference is {} s. Set time on pump." + timeDiff);
medtronicUIComm.executeCommand(MedtronicCommandType.SetRealTimeClock); rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.SetRealTimeClock);
if (clock.timeDifference == 0) { if (clock.timeDifference == 0) {
Notification notification = new Notification(Notification.INSIGHT_DATE_TIME_UPDATED, getResourceHelper().gs(R.string.pump_time_updated), Notification.INFO, 60); Notification notification = new Notification(Notification.INSIGHT_DATE_TIME_UPDATED, getResourceHelper().gs(R.string.pump_time_updated), Notification.INFO, 60);
@ -769,7 +772,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
} else { } else {
if ((clock.localDeviceTime.getYear() > 2015)) { if ((clock.localDeviceTime.getYear() > 2015)) {
aapsLogger.error("MedtronicPumpPlugin::checkTimeAndOptionallySetTime - Time difference over 24h requested [diff={}]. Doing nothing." + timeDiff); aapsLogger.error("MedtronicPumpPlugin::checkTimeAndOptionallySetTime - Time difference over 24h requested [diff={}]. Doing nothing." + timeDiff);
sendNotification(MedtronicNotificationType.TimeChangeOver24h, getResourceHelper(), rxBus); medtronicUtil.sendNotification(MedtronicNotificationType.TimeChangeOver24h, getResourceHelper(), rxBus);
} }
} }
@ -788,14 +791,12 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
setRefreshButtonEnabled(false); setRefreshButtonEnabled(false);
MedtronicPumpStatus mdtPumpStatus = getMDTPumpStatus(); if (detailedBolusInfo.insulin > medtronicPumpStatus.reservoirRemainingUnits) {
if (detailedBolusInfo.insulin > mdtPumpStatus.reservoirRemainingUnits) {
return new PumpEnactResult(getInjector()) // return new PumpEnactResult(getInjector()) //
.success(false) // .success(false) //
.enacted(false) // .enacted(false) //
.comment(getResourceHelper().gs(R.string.medtronic_cmd_bolus_could_not_be_delivered_no_insulin, .comment(getResourceHelper().gs(R.string.medtronic_cmd_bolus_could_not_be_delivered_no_insulin,
mdtPumpStatus.reservoirRemainingUnits, medtronicPumpStatus.reservoirRemainingUnits,
detailedBolusInfo.insulin)); detailedBolusInfo.insulin));
} }
@ -806,7 +807,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
return setNotReachable(true, false); return setNotReachable(true, false);
} }
MedtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus); medtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus);
if (bolusDeliveryType == BolusDeliveryType.CancelDelivery) { if (bolusDeliveryType == BolusDeliveryType.CancelDelivery) {
// LOG.debug("MedtronicPumpPlugin::deliverBolus - Delivery Canceled."); // LOG.debug("MedtronicPumpPlugin::deliverBolus - Delivery Canceled.");
@ -832,7 +833,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
// LOG.debug("MedtronicPumpPlugin::deliverBolus - Start delivery"); // LOG.debug("MedtronicPumpPlugin::deliverBolus - Start delivery");
MedtronicUITask responseTask = medtronicUIComm.executeCommand(MedtronicCommandType.SetBolus, MedtronicUITask responseTask = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.SetBolus,
detailedBolusInfo.insulin); detailedBolusInfo.insulin);
Boolean response = (Boolean) responseTask.returnData; Boolean response = (Boolean) responseTask.returnData;
@ -871,7 +872,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
activePlugin.getActiveTreatments().addToHistoryTreatment(detailedBolusInfo, true); activePlugin.getActiveTreatments().addToHistoryTreatment(detailedBolusInfo, true);
// we subtract insulin, exact amount will be visible with next remainingInsulin update. // we subtract insulin, exact amount will be visible with next remainingInsulin update.
getMDTPumpStatus().reservoirRemainingUnits -= detailedBolusInfo.insulin; medtronicPumpStatus.reservoirRemainingUnits -= detailedBolusInfo.insulin;
incrementStatistics(detailedBolusInfo.isSMB ? MedtronicConst.Statistics.SMBBoluses incrementStatistics(detailedBolusInfo.isSMB ? MedtronicConst.Statistics.SMBBoluses
: MedtronicConst.Statistics.StandardBoluses); : MedtronicConst.Statistics.StandardBoluses);
@ -957,9 +958,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
.comment(getResourceHelper().gs(R.string.medtronic_pump_status_pump_unreachable)); .comment(getResourceHelper().gs(R.string.medtronic_pump_status_pump_unreachable));
} }
MedtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus); medtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus);
getMDTPumpStatus();
aapsLogger.info(LTag.PUMP, getLogPrefix() + "setTempBasalAbsolute: rate: " + absoluteRate + ", duration=" + durationInMinutes); aapsLogger.info(LTag.PUMP, getLogPrefix() + "setTempBasalAbsolute: rate: " + absoluteRate + ", duration=" + durationInMinutes);
@ -977,10 +976,10 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
if (!enforceNew) { if (!enforceNew) {
if (MedtronicUtil.isSame(tbrCurrent.getInsulinRate(), absoluteRate)) { if (medtronicUtil.isSame(tbrCurrent.getInsulinRate(), absoluteRate)) {
boolean sameRate = true; boolean sameRate = true;
if (MedtronicUtil.isSame(0.0d, absoluteRate) && durationInMinutes > 0) { if (medtronicUtil.isSame(0.0d, absoluteRate) && durationInMinutes > 0) {
// if rate is 0.0 and duration>0 then the rate is not the same // if rate is 0.0 and duration>0 then the rate is not the same
sameRate = false; sameRate = false;
} }
@ -1000,7 +999,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
// CANCEL // CANCEL
MedtronicUITask responseTask2 = medtronicUIComm.executeCommand(MedtronicCommandType.CancelTBR); MedtronicUITask responseTask2 = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.CancelTBR);
Boolean response = (Boolean) responseTask2.returnData; Boolean response = (Boolean) responseTask2.returnData;
@ -1017,7 +1016,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
} }
// now start new TBR // now start new TBR
MedtronicUITask responseTask = medtronicUIComm.executeCommand(MedtronicCommandType.SetTemporaryBasal, MedtronicUITask responseTask = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.SetTemporaryBasal,
absoluteRate, durationInMinutes); absoluteRate, durationInMinutes);
Boolean response = (Boolean) responseTask.returnData; Boolean response = (Boolean) responseTask.returnData;
@ -1026,9 +1025,9 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
if (response) { if (response) {
// FIXME put this into UIPostProcessor // FIXME put this into UIPostProcessor
pumpStatusLocal.tempBasalStart = new Date(); medtronicPumpStatus.tempBasalStart = new Date();
pumpStatusLocal.tempBasalAmount = absoluteRate; medtronicPumpStatus.tempBasalAmount = absoluteRate;
pumpStatusLocal.tempBasalLength = durationInMinutes; medtronicPumpStatus.tempBasalLength = durationInMinutes;
TemporaryBasal tempStart = new TemporaryBasal(getInjector()) // TemporaryBasal tempStart = new TemporaryBasal(getInjector()) //
.date(System.currentTimeMillis()) // .date(System.currentTimeMillis()) //
@ -1062,8 +1061,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
return setTempBasalAbsolute(0.0d, durationInMinutes, profile, enforceNew); return setTempBasalAbsolute(0.0d, durationInMinutes, profile, enforceNew);
} else { } else {
double absoluteValue = profile.getBasal() * (percent / 100.0d); double absoluteValue = profile.getBasal() * (percent / 100.0d);
getMDTPumpStatus(); absoluteValue = pumpDescription.pumpType.determineCorrectBasalSize(absoluteValue);
absoluteValue = pumpStatusLocal.pumpType.determineCorrectBasalSize(absoluteValue);
aapsLogger.warn(LTag.PUMP, "setTempBasalPercent [MedtronicPumpPlugin] - You are trying to use setTempBasalPercent with percent other then 0% (" + percent + "). This will start setTempBasalAbsolute, with calculated value (" + absoluteValue + "). Result might not be 100% correct."); aapsLogger.warn(LTag.PUMP, "setTempBasalPercent [MedtronicPumpPlugin] - You are trying to use setTempBasalPercent with percent other then 0% (" + percent + "). This will start setTempBasalAbsolute, with calculated value (" + absoluteValue + "). Result might not be 100% correct.");
return setTempBasalAbsolute(absoluteValue, durationInMinutes, profile, enforceNew); return setTempBasalAbsolute(absoluteValue, durationInMinutes, profile, enforceNew);
} }
@ -1098,9 +1096,9 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
scheduleNextRefresh(MedtronicStatusRefreshType.PumpTime, -1); scheduleNextRefresh(MedtronicStatusRefreshType.PumpTime, -1);
} }
if (this.getMDTPumpStatus().basalProfileStatus != BasalProfileStatus.NotInitialized if (this.medtronicPumpStatus.basalProfileStatus != BasalProfileStatus.NotInitialized
&& medtronicHistoryData.hasBasalProfileChanged()) { && medtronicHistoryData.hasBasalProfileChanged()) {
medtronicHistoryData.processLastBasalProfileChange(getMDTPumpStatus()); medtronicHistoryData.processLastBasalProfileChange(pumpDescription.pumpType, medtronicPumpStatus);
} }
PumpDriverState previousState = this.pumpState; PumpDriverState previousState = this.pumpState;
@ -1163,7 +1161,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
aapsLogger.debug(LTag.PUMP, getLogPrefix() + "readPumpHistoryLogic(): targetDate: " + targetDate); aapsLogger.debug(LTag.PUMP, getLogPrefix() + "readPumpHistoryLogic(): targetDate: " + targetDate);
} }
} else { } else {
aapsLogger.debug(LTag.PUMP, getLogPrefix() + "readPumpHistoryLogic(): lastPumpHistoryEntry: not null - " + MedtronicUtil.gsonInstance.toJson(lastPumpHistoryEntry)); aapsLogger.debug(LTag.PUMP, getLogPrefix() + "readPumpHistoryLogic(): lastPumpHistoryEntry: not null - " + medtronicUtil.gsonInstance.toJson(lastPumpHistoryEntry));
medtronicHistoryData.setIsInInit(false); medtronicHistoryData.setIsInInit(false);
// medtronicHistoryData.setLastHistoryRecordTime(lastPumpHistoryEntry.atechDateTime); // medtronicHistoryData.setLastHistoryRecordTime(lastPumpHistoryEntry.atechDateTime);
@ -1172,7 +1170,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
aapsLogger.debug(LTag.PUMP, "HST: Target Date: " + targetDate); aapsLogger.debug(LTag.PUMP, "HST: Target Date: " + targetDate);
MedtronicUITask responseTask2 = medtronicUIComm.executeCommand(MedtronicCommandType.GetHistoryData, MedtronicUITask responseTask2 = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.GetHistoryData,
lastPumpHistoryEntry, targetDate); lastPumpHistoryEntry, targetDate);
aapsLogger.debug(LTag.PUMP, "HST: After task"); aapsLogger.debug(LTag.PUMP, "HST: After task");
@ -1248,7 +1246,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
switch (refreshType) { switch (refreshType) {
case RemainingInsulin: { case RemainingInsulin: {
double remaining = pumpStatusLocal.reservoirRemainingUnits; double remaining = medtronicPumpStatus.reservoirRemainingUnits;
int min; int min;
if (remaining > 50) if (remaining > 50)
min = 4 * 60; min = 4 * 60;
@ -1312,7 +1310,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
private TempBasalPair readTBR() { private TempBasalPair readTBR() {
MedtronicUITask responseTask = medtronicUIComm.executeCommand(MedtronicCommandType.ReadTemporaryBasal); MedtronicUITask responseTask = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.ReadTemporaryBasal);
if (responseTask.hasData()) { if (responseTask.hasData()) {
TempBasalPair tbr = (TempBasalPair) responseTask.returnData; TempBasalPair tbr = (TempBasalPair) responseTask.returnData;
@ -1344,7 +1342,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
.comment(getResourceHelper().gs(R.string.medtronic_pump_status_pump_unreachable)); .comment(getResourceHelper().gs(R.string.medtronic_pump_status_pump_unreachable));
} }
MedtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus); medtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus);
setRefreshButtonEnabled(false); setRefreshButtonEnabled(false);
TempBasalPair tbrCurrent = readTBR(); TempBasalPair tbrCurrent = readTBR();
@ -1362,7 +1360,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
.comment(getResourceHelper().gs(R.string.medtronic_cmd_cant_read_tbr)); .comment(getResourceHelper().gs(R.string.medtronic_cmd_cant_read_tbr));
} }
MedtronicUITask responseTask2 = medtronicUIComm.executeCommand(MedtronicCommandType.CancelTBR); MedtronicUITask responseTask2 = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.CancelTBR);
Boolean response = (Boolean) responseTask2.returnData; Boolean response = (Boolean) responseTask2.returnData;
@ -1390,17 +1388,17 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
@NonNull @Override @NonNull @Override
public ManufacturerType manufacturer() { public ManufacturerType manufacturer() {
return getMDTPumpStatus().pumpType.getManufacturer(); return pumpDescription.pumpType.getManufacturer();
} }
@NonNull @Override @NonNull @Override
public PumpType model() { public PumpType model() {
return getMDTPumpStatus().pumpType; return pumpDescription.pumpType;
} }
@NonNull @Override @NonNull @Override
public String serialNumber() { public String serialNumber() {
return getMDTPumpStatus().serialNumber; return medtronicPumpStatus.serialNumber;
} }
@NonNull @Override @NonNull @Override
@ -1427,7 +1425,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
.comment(getResourceHelper().gs(R.string.medtronic_pump_status_pump_unreachable)); .comment(getResourceHelper().gs(R.string.medtronic_pump_status_pump_unreachable));
} }
MedtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus); medtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus);
BasalProfile basalProfile = convertProfileToMedtronicProfile(profile); BasalProfile basalProfile = convertProfileToMedtronicProfile(profile);
@ -1440,7 +1438,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
.comment(getResourceHelper().gs(R.string.medtronic_cmd_set_profile_pattern_overflow, profileInvalid)); .comment(getResourceHelper().gs(R.string.medtronic_cmd_set_profile_pattern_overflow, profileInvalid));
} }
MedtronicUITask responseTask = medtronicUIComm.executeCommand(MedtronicCommandType.SetBasalProfileSTD, MedtronicUITask responseTask = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.SetBasalProfileSTD,
basalProfile); basalProfile);
Boolean response = (Boolean) responseTask.returnData; Boolean response = (Boolean) responseTask.returnData;
@ -1460,14 +1458,12 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
MedtronicPumpStatus pumpStatus = getMDTPumpStatus(); if (medtronicPumpStatus.maxBasal == null)
if (pumpStatus.maxBasal == null)
return null; return null;
for (BasalProfileEntry profileEntry : basalProfile.getEntries()) { for (BasalProfileEntry profileEntry : basalProfile.getEntries()) {
if (profileEntry.rate > pumpStatus.maxBasal) { if (profileEntry.rate > medtronicPumpStatus.maxBasal) {
stringBuilder.append(profileEntry.startTime.toString("HH:mm")); stringBuilder.append(profileEntry.startTime.toString("HH:mm"));
stringBuilder.append("="); stringBuilder.append("=");
stringBuilder.append(profileEntry.rate); stringBuilder.append(profileEntry.rate);
@ -1481,16 +1477,12 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
@NonNull @NonNull
private BasalProfile convertProfileToMedtronicProfile(Profile profile) { private BasalProfile convertProfileToMedtronicProfile(Profile profile) {
MedtronicPumpStatus pumpStatus = getMDTPumpStatus(); BasalProfile basalProfile = new BasalProfile(aapsLogger);
PumpType pumpType = pumpStatus.pumpType;
BasalProfile basalProfile = new BasalProfile();
for (int i = 0; i < 24; i++) { for (int i = 0; i < 24; i++) {
double rate = profile.getBasalTimeFromMidnight(i * 60 * 60); double rate = profile.getBasalTimeFromMidnight(i * 60 * 60);
double v = pumpType.determineCorrectBasalSize(rate); double v = pumpDescription.pumpType.determineCorrectBasalSize(rate);
BasalProfileEntry basalEntry = new BasalProfileEntry(v, i, 0); BasalProfileEntry basalEntry = new BasalProfileEntry(v, i, 0);
basalProfile.addEntry(basalEntry); basalProfile.addEntry(basalEntry);
@ -1537,8 +1529,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
switch (mcat) { switch (mcat) {
case WakeUpAndTune: { case WakeUpAndTune: {
if (MedtronicUtil.getPumpStatus().verifyConfiguration()) { if (rileyLinkMedtronicService.verifyConfiguration()) {
ServiceTaskExecutor.startTask(new WakeAndTuneTask()); serviceTaskExecutor.startTask(new WakeAndTuneTask(getInjector()));
} else { } else {
Intent i = new Intent(context, ErrorHelperActivity.class); Intent i = new Intent(context, ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror); i.putExtra("soundid", R.raw.boluserror);
@ -1558,7 +1550,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
break; break;
case ResetRileyLinkConfiguration: { case ResetRileyLinkConfiguration: {
ServiceTaskExecutor.startTask(new ResetRileyLinkConfigurationTask()); serviceTaskExecutor.startTask(new ResetRileyLinkConfigurationTask(getInjector()));
} }
break; break;
@ -1569,19 +1561,15 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
} }
@Override @Override
public void timeDateOrTimeZoneChanged() { public void timezoneOrDSTChanged(TimeChangeType changeType) {
aapsLogger.warn(LTag.PUMP, getLogPrefix() + "Time, Date and/or TimeZone changed. "); aapsLogger.warn(LTag.PUMP, getLogPrefix() + "Time or TimeZone changed. ");
this.hasTimeDateOrTimeZoneChanged = true; this.hasTimeDateOrTimeZoneChanged = true;
} }
private void refreshCustomActionsList() {
rxBus.send(new EventCustomActionsChanged());
}
private void setEnableCustomAction(MedtronicCustomActionType customAction, boolean isEnabled) {
public void setEnableCustomAction(MedtronicCustomActionType customAction, boolean isEnabled) {
if (customAction == MedtronicCustomActionType.ClearBolusBlock) { if (customAction == MedtronicCustomActionType.ClearBolusBlock) {
this.customActionClearBolusBlock.setEnabled(isEnabled); this.customActionClearBolusBlock.setEnabled(isEnabled);
@ -1591,6 +1579,4 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
refreshCustomActionsList(); refreshCustomActionsList();
} }
} }

View file

@ -1,19 +1,20 @@
package info.nightscout.androidaps.plugins.pump.medtronic.comm; package info.nightscout.androidaps.plugins.pump.medtronic.comm;
import android.content.Context;
import android.os.SystemClock; import android.os.SystemClock;
import org.joda.time.LocalDateTime; import org.joda.time.LocalDateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Calendar; import java.util.Calendar;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import info.nightscout.androidaps.logging.L; import javax.inject.Inject;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkCommunicationManager; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkCommunicationManager;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RFSpy; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RFSpy;
@ -23,10 +24,12 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RLMe
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RadioPacket; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RadioPacket;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RadioResponse; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RadioResponse;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RLMessageType; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RLMessageType;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTaskExecutor; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTaskExecutor;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.WakeAndTuneTask; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.WakeAndTuneTask;
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil; import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin;
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.RawHistoryPage; import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.RawHistoryPage;
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.MedtronicPumpHistoryDecoder; import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.MedtronicPumpHistoryDecoder;
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry; import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry;
@ -46,8 +49,8 @@ import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.TempBasalPair;
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType; import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType;
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType; import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType;
import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState; import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState;
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil; import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
import info.nightscout.androidaps.utils.SP;
/** /**
* Original file created by geoff on 5/30/16. * Original file created by geoff on 5/30/16.
@ -58,53 +61,43 @@ import info.nightscout.androidaps.utils.SP;
*/ */
public class MedtronicCommunicationManager extends RileyLinkCommunicationManager { public class MedtronicCommunicationManager extends RileyLinkCommunicationManager {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPCOMM); @Inject AAPSLogger aapsLogger;
private static final int MAX_COMMAND_TRIES = 3; @Inject MedtronicPumpStatus medtronicPumpStatus;
private static final int DEFAULT_TIMEOUT = 2000; @Inject MedtronicPumpPlugin medtronicPumpPlugin;
private static final long RILEYLINK_TIMEOUT = 15 * 60 * 1000; // 15 min @Inject MedtronicConverter medtronicConverter;
@Inject MedtronicUtil medtronicUtil;
@Inject MedtronicPumpHistoryDecoder medtronicPumpHistoryDecoder;
@Inject RileyLinkServiceData rileyLinkServiceData;
@Inject ServiceTaskExecutor serviceTaskExecutor;
static MedtronicCommunicationManager medtronicCommunicationManager; private final int MAX_COMMAND_TRIES = 3;
String errorMessage; private final int DEFAULT_TIMEOUT = 2000;
private MedtronicConverter medtronicConverter; private final long RILEYLINK_TIMEOUT = 15 * 60 * 1000; // 15 min
private String errorMessage;
private boolean debugSetCommands = false; private boolean debugSetCommands = false;
private MedtronicPumpHistoryDecoder pumpHistoryDecoder;
private boolean doWakeUpBeforeCommand = true; private boolean doWakeUpBeforeCommand = true;
public MedtronicCommunicationManager(Context context, RFSpy rfspy) { public MedtronicCommunicationManager(HasAndroidInjector injector, RFSpy rfspy) {
super(context, rfspy); super(injector, rfspy);
medtronicCommunicationManager = this; medtronicPumpStatus.previousConnection = sp.getLong(
this.medtronicConverter = new MedtronicConverter();
this.pumpHistoryDecoder = new MedtronicPumpHistoryDecoder();
MedtronicUtil.getPumpStatus().previousConnection = SP.getLong(
RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L); RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L);
} }
public static MedtronicCommunicationManager getInstance() {
return medtronicCommunicationManager;
}
@Override
protected void configurePumpSpecificSettings() {
pumpStatus = MedtronicUtil.getPumpStatus();
}
@Override @Override
public <E extends RLMessage> E createResponseMessage(byte[] payload, Class<E> clazz) { public <E extends RLMessage> E createResponseMessage(byte[] payload, Class<E> clazz) {
PumpMessage pumpMessage = new PumpMessage(payload); PumpMessage pumpMessage = new PumpMessage(aapsLogger, payload);
return (E) pumpMessage; return (E) pumpMessage;
} }
public void setDoWakeUpBeforeCommand(boolean doWakeUp) { public void setDoWakeUpBeforeCommand(boolean doWakeUp) {
this.doWakeUpBeforeCommand = doWakeUp; this.doWakeUpBeforeCommand = doWakeUp;
} }
@Override
public boolean isDeviceReachable() { public boolean isDeviceReachable() {
return isDeviceReachable(false); return isDeviceReachable(false);
} }
@ -118,15 +111,14 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
*/ */
public boolean isDeviceReachable(boolean canPreventTuneUp) { public boolean isDeviceReachable(boolean canPreventTuneUp) {
PumpDeviceState state = MedtronicUtil.getPumpDeviceState(); PumpDeviceState state = medtronicPumpStatus.getPumpDeviceState();
if (state != PumpDeviceState.PumpUnreachable) if (state != PumpDeviceState.PumpUnreachable)
MedtronicUtil.setPumpDeviceState(PumpDeviceState.WakingUp); medtronicPumpStatus.setPumpDeviceState(PumpDeviceState.WakingUp);
for (int retry = 0; retry < 5; retry++) { for (int retry = 0; retry < 5; retry++) {
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "isDeviceReachable. Waking pump... " + (retry != 0 ? " (retry " + retry + ")" : ""));
LOG.debug("isDeviceReachable. Waking pump... " + (retry != 0 ? " (retry " + retry + ")" : ""));
boolean connected = connectToDevice(); boolean connected = connectToDevice();
@ -138,14 +130,14 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
} }
if (state != PumpDeviceState.PumpUnreachable) if (state != PumpDeviceState.PumpUnreachable)
MedtronicUtil.setPumpDeviceState(PumpDeviceState.PumpUnreachable); medtronicPumpStatus.setPumpDeviceState(PumpDeviceState.PumpUnreachable);
if (!canPreventTuneUp) { if (!canPreventTuneUp) {
long diff = System.currentTimeMillis() - MedtronicUtil.getPumpStatus().lastConnection; long diff = System.currentTimeMillis() - medtronicPumpStatus.lastConnection;
if (diff > RILEYLINK_TIMEOUT) { if (diff > RILEYLINK_TIMEOUT) {
ServiceTaskExecutor.startTask(new WakeAndTuneTask()); serviceTaskExecutor.startTask(new WakeAndTuneTask(injector));
} }
} }
@ -155,18 +147,17 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
private boolean connectToDevice() { private boolean connectToDevice() {
PumpDeviceState state = MedtronicUtil.getPumpDeviceState(); PumpDeviceState state = medtronicPumpStatus.getPumpDeviceState();
byte[] pumpMsgContent = createPumpMessageContent(RLMessageType.ReadSimpleData); // simple byte[] pumpMsgContent = createPumpMessageContent(RLMessageType.ReadSimpleData); // simple
RFSpyResponse rfSpyResponse = rfspy.transmitThenReceive(new RadioPacket(pumpMsgContent), (byte) 0, (byte) 200, RFSpyResponse rfSpyResponse = rfspy.transmitThenReceive(new RadioPacket(injector, pumpMsgContent), (byte) 0, (byte) 200,
(byte) 0, (byte) 0, 25000, (byte) 0); (byte) 0, (byte) 0, 25000, (byte) 0);
if (isLogEnabled()) aapsLogger.info(LTag.PUMPCOMM, "wakeup: raw response is " + ByteUtil.shortHexString(rfSpyResponse.getRaw()));
LOG.info("wakeup: raw response is " + ByteUtil.shortHexString(rfSpyResponse.getRaw()));
if (rfSpyResponse.wasTimeout()) { if (rfSpyResponse.wasTimeout()) {
LOG.error("isDeviceReachable. Failed to find pump (timeout)."); aapsLogger.error(LTag.PUMPCOMM, "isDeviceReachable. Failed to find pump (timeout).");
} else if (rfSpyResponse.looksLikeRadioPacket()) { } else if (rfSpyResponse.looksLikeRadioPacket()) {
RadioResponse radioResponse = new RadioResponse(); RadioResponse radioResponse = new RadioResponse(injector);
try { try {
@ -177,30 +168,29 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
PumpMessage pumpResponse = createResponseMessage(radioResponse.getPayload(), PumpMessage.class); PumpMessage pumpResponse = createResponseMessage(radioResponse.getPayload(), PumpMessage.class);
if (!pumpResponse.isValid()) { if (!pumpResponse.isValid()) {
LOG.warn("Response is invalid ! [interrupted={}, timeout={}]", rfSpyResponse.wasInterrupted(), aapsLogger.warn(LTag.PUMPCOMM, "Response is invalid ! [interrupted={}, timeout={}]", rfSpyResponse.wasInterrupted(),
rfSpyResponse.wasTimeout()); rfSpyResponse.wasTimeout());
} else { } else {
// radioResponse.rssi; // radioResponse.rssi;
Object dataResponse = medtronicConverter.convertResponse(MedtronicCommandType.PumpModel, Object dataResponse = medtronicConverter.convertResponse(medtronicPumpPlugin.getPumpDescription().pumpType, MedtronicCommandType.PumpModel,
pumpResponse.getRawContent()); pumpResponse.getRawContent());
MedtronicDeviceType pumpModel = (MedtronicDeviceType) dataResponse; MedtronicDeviceType pumpModel = (MedtronicDeviceType) dataResponse;
boolean valid = (pumpModel != MedtronicDeviceType.Unknown_Device); boolean valid = (pumpModel != MedtronicDeviceType.Unknown_Device);
if (MedtronicUtil.getMedtronicPumpModel() == null && valid) { if (medtronicUtil.getMedtronicPumpModel() == null && valid) {
MedtronicUtil.setMedtronicPumpModel(pumpModel); medtronicUtil.setMedtronicPumpModel(pumpModel);
} }
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "isDeviceReachable. PumpModel is {} - Valid: {} (rssi={})", pumpModel.name(), valid,
LOG.debug("isDeviceReachable. PumpModel is {} - Valid: {} (rssi={})", pumpModel.name(), valid, radioResponse.rssi);
radioResponse.rssi);
if (valid) { if (valid) {
if (state == PumpDeviceState.PumpUnreachable) if (state == PumpDeviceState.PumpUnreachable)
MedtronicUtil.setPumpDeviceState(PumpDeviceState.WakingUp); medtronicPumpStatus.setPumpDeviceState(PumpDeviceState.WakingUp);
else else
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Sleeping); medtronicPumpStatus.setPumpDeviceState(PumpDeviceState.Sleeping);
rememberLastGoodDeviceCommunicationTime(); rememberLastGoodDeviceCommunicationTime();
@ -208,23 +198,23 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
} else { } else {
if (state != PumpDeviceState.PumpUnreachable) if (state != PumpDeviceState.PumpUnreachable)
MedtronicUtil.setPumpDeviceState(PumpDeviceState.PumpUnreachable); medtronicPumpStatus.setPumpDeviceState(PumpDeviceState.PumpUnreachable);
} }
} }
} else { } else {
LOG.warn("isDeviceReachable. Failed to parse radio response: " aapsLogger.warn(LTag.PUMPCOMM, "isDeviceReachable. Failed to parse radio response: "
+ ByteUtil.shortHexString(rfSpyResponse.getRaw())); + ByteUtil.shortHexString(rfSpyResponse.getRaw()));
} }
} catch (RileyLinkCommunicationException e) { } catch (RileyLinkCommunicationException e) {
LOG.warn("isDeviceReachable. Failed to decode radio response: " aapsLogger.warn(LTag.PUMPCOMM, "isDeviceReachable. Failed to decode radio response: "
+ ByteUtil.shortHexString(rfSpyResponse.getRaw())); + ByteUtil.shortHexString(rfSpyResponse.getRaw()));
} }
} else { } else {
LOG.warn("isDeviceReachable. Unknown response: " + ByteUtil.shortHexString(rfSpyResponse.getRaw())); aapsLogger.warn(LTag.PUMPCOMM, "isDeviceReachable. Unknown response: " + ByteUtil.shortHexString(rfSpyResponse.getRaw()));
} }
return false; return false;
@ -240,7 +230,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
private PumpMessage runCommandWithArgs(PumpMessage msg) throws RileyLinkCommunicationException { private PumpMessage runCommandWithArgs(PumpMessage msg) throws RileyLinkCommunicationException {
if (debugSetCommands) if (debugSetCommands)
LOG.debug("Run command with Args: "); aapsLogger.debug(LTag.PUMPCOMM, "Run command with Args: ");
PumpMessage rval; PumpMessage rval;
PumpMessage shortMessage = makePumpMessage(msg.commandType, new CarelinkShortMessageBody(new byte[]{0})); PumpMessage shortMessage = makePumpMessage(msg.commandType, new CarelinkShortMessageBody(new byte[]{0}));
@ -248,17 +238,16 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
PumpMessage shortResponse = sendAndListen(shortMessage); PumpMessage shortResponse = sendAndListen(shortMessage);
if (shortResponse.commandType == MedtronicCommandType.CommandACK) { if (shortResponse.commandType == MedtronicCommandType.CommandACK) {
if (debugSetCommands) if (debugSetCommands)
LOG.debug("Run command with Args: Got ACK response"); aapsLogger.debug(LTag.PUMPCOMM, "Run command with Args: Got ACK response");
rval = sendAndListen(msg); rval = sendAndListen(msg);
if (debugSetCommands) if (debugSetCommands)
LOG.debug("2nd Response: {}", rval); aapsLogger.debug(LTag.PUMPCOMM, "2nd Response: {}", rval);
return rval; return rval;
} else { } else {
if (isLogEnabled()) aapsLogger.error(LTag.PUMPCOMM, "runCommandWithArgs: Pump did not ack Attention packet");
LOG.error("runCommandWithArgs: Pump did not ack Attention packet"); return new PumpMessage(aapsLogger, "No ACK after Attention packet.");
return new PumpMessage("No ACK after Attention packet.");
} }
} }
@ -266,8 +255,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
private PumpMessage runCommandWithFrames(MedtronicCommandType commandType, List<List<Byte>> frames) private PumpMessage runCommandWithFrames(MedtronicCommandType commandType, List<List<Byte>> frames)
throws RileyLinkCommunicationException { throws RileyLinkCommunicationException {
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "Run command with Frames: {}", commandType.name());
LOG.debug("Run command with Frames: {}", commandType.name());
PumpMessage rval = null; PumpMessage rval = null;
PumpMessage shortMessage = makePumpMessage(commandType, new CarelinkShortMessageBody(new byte[]{0})); PumpMessage shortMessage = makePumpMessage(commandType, new CarelinkShortMessageBody(new byte[]{0}));
@ -275,39 +263,36 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
PumpMessage shortResponse = sendAndListen(shortMessage); PumpMessage shortResponse = sendAndListen(shortMessage);
if (shortResponse.commandType != MedtronicCommandType.CommandACK) { if (shortResponse.commandType != MedtronicCommandType.CommandACK) {
if (isLogEnabled()) aapsLogger.error(LTag.PUMPCOMM, "runCommandWithFrames: Pump did not ack Attention packet");
LOG.error("runCommandWithFrames: Pump did not ack Attention packet");
return new PumpMessage("No ACK after start message."); return new PumpMessage(aapsLogger, "No ACK after start message.");
} else { } else {
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "Run command with Frames: Got ACK response for Attention packet");
LOG.debug("Run command with Frames: Got ACK response for Attention packet");
} }
int frameNr = 1; int frameNr = 1;
for (List<Byte> frame : frames) { for (List<Byte> frame : frames) {
byte[] frameData = MedtronicUtil.createByteArray(frame); byte[] frameData = medtronicUtil.createByteArray(frame);
// LOG.debug("Frame {} data:\n{}", frameNr, ByteUtil.getCompactString(frameData)); // aapsLogger.debug(LTag.PUMPCOMM,"Frame {} data:\n{}", frameNr, ByteUtil.getCompactString(frameData));
PumpMessage msg = makePumpMessage(commandType, new CarelinkLongMessageBody(frameData)); PumpMessage msg = makePumpMessage(commandType, new CarelinkLongMessageBody(frameData));
rval = sendAndListen(msg); rval = sendAndListen(msg);
// LOG.debug("PumpResponse: " + rval); // aapsLogger.debug(LTag.PUMPCOMM,"PumpResponse: " + rval);
if (rval.commandType != MedtronicCommandType.CommandACK) { if (rval.commandType != MedtronicCommandType.CommandACK) {
LOG.error("runCommandWithFrames: Pump did not ACK frame #{}", frameNr); aapsLogger.error(LTag.PUMPCOMM, "runCommandWithFrames: Pump did not ACK frame #{}", frameNr);
LOG.error("Run command with Frames FAILED (command={}, response={})", commandType.name(), aapsLogger.error(LTag.PUMPCOMM, "Run command with Frames FAILED (command={}, response={})", commandType.name(),
rval.toString()); rval.toString());
return new PumpMessage("No ACK after frame #" + frameNr); return new PumpMessage(aapsLogger, "No ACK after frame #" + frameNr);
} else { } else {
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "Run command with Frames: Got ACK response for frame #{}", (frameNr));
LOG.debug("Run command with Frames: Got ACK response for frame #{}", (frameNr));
} }
frameNr++; frameNr++;
@ -320,34 +305,32 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
public PumpHistoryResult getPumpHistory(PumpHistoryEntry lastEntry, LocalDateTime targetDate) { public PumpHistoryResult getPumpHistory(PumpHistoryEntry lastEntry, LocalDateTime targetDate) {
PumpHistoryResult pumpTotalResult = new PumpHistoryResult(lastEntry, targetDate == null ? null PumpHistoryResult pumpTotalResult = new PumpHistoryResult(aapsLogger, lastEntry, targetDate == null ? null
: DateTimeUtil.toATechDate(targetDate)); : DateTimeUtil.toATechDate(targetDate));
if (doWakeUpBeforeCommand) if (doWakeUpBeforeCommand)
wakeUp(receiverDeviceAwakeForMinutes, false); wakeUp(receiverDeviceAwakeForMinutes, false);
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "Current command: " + medtronicUtil.getCurrentCommand());
LOG.debug("Current command: " + MedtronicUtil.getCurrentCommand());
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Active); medtronicPumpStatus.setPumpDeviceState(PumpDeviceState.Active);
boolean doneWithError = false; boolean doneWithError = false;
for (int pageNumber = 0; pageNumber < 5; pageNumber++) { for (int pageNumber = 0; pageNumber < 5; pageNumber++) {
RawHistoryPage rawHistoryPage = new RawHistoryPage(); RawHistoryPage rawHistoryPage = new RawHistoryPage(aapsLogger);
// wakeUp(receiverDeviceAwakeForMinutes, false); // wakeUp(receiverDeviceAwakeForMinutes, false);
PumpMessage getHistoryMsg = makePumpMessage(MedtronicCommandType.GetHistoryData, PumpMessage getHistoryMsg = makePumpMessage(MedtronicCommandType.GetHistoryData,
new GetHistoryPageCarelinkMessageBody(pageNumber)); new GetHistoryPageCarelinkMessageBody(pageNumber));
if (isLogEnabled()) aapsLogger.info(LTag.PUMPCOMM, "getPumpHistory: Page {}", pageNumber);
LOG.info("getPumpHistory: Page {}", pageNumber); // aapsLogger.info(LTag.PUMPCOMM,"getPumpHistoryPage("+pageNumber+"): "+ByteUtil.shortHexString(getHistoryMsg.getTxData()));
// LOG.info("getPumpHistoryPage("+pageNumber+"): "+ByteUtil.shortHexString(getHistoryMsg.getTxData()));
// Ask the pump to transfer history (we get first frame?) // Ask the pump to transfer history (we get first frame?)
PumpMessage firstResponse = null; PumpMessage firstResponse = null;
boolean failed = false; boolean failed = false;
MedtronicUtil.setCurrentCommand(MedtronicCommandType.GetHistoryData, pageNumber, null); medtronicUtil.setCurrentCommand(MedtronicCommandType.GetHistoryData, pageNumber, null);
for (int retries = 0; retries < MAX_COMMAND_TRIES; retries++) { for (int retries = 0; retries < MAX_COMMAND_TRIES; retries++) {
@ -356,18 +339,17 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
failed = false; failed = false;
break; break;
} catch (RileyLinkCommunicationException e) { } catch (RileyLinkCommunicationException e) {
if (isLogEnabled()) aapsLogger.error(LTag.PUMPCOMM, "First call for PumpHistory failed (retry={})", retries);
LOG.error("First call for PumpHistory failed (retry={})", retries);
failed = true; failed = true;
} }
} }
if (failed) { if (failed) {
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Sleeping); medtronicPumpStatus.setPumpDeviceState(PumpDeviceState.Sleeping);
return pumpTotalResult; return pumpTotalResult;
} }
// LOG.info("getPumpHistoryPage("+pageNumber+"): " + ByteUtil.shortHexString(firstResponse.getContents())); // aapsLogger.info(LTag.PUMPCOMM,"getPumpHistoryPage("+pageNumber+"): " + ByteUtil.shortHexString(firstResponse.getContents()));
PumpMessage ackMsg = makePumpMessage(MedtronicCommandType.CommandACK, new PumpAckMessageBody()); PumpMessage ackMsg = makePumpMessage(MedtronicCommandType.CommandACK, new PumpAckMessageBody());
GetHistoryPageCarelinkMessageBody currentResponse = new GetHistoryPageCarelinkMessageBody(firstResponse GetHistoryPageCarelinkMessageBody currentResponse = new GetHistoryPageCarelinkMessageBody(firstResponse
@ -384,19 +366,17 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
&& currentResponse.getFrameNumber() == expectedFrameNum) { && currentResponse.getFrameNumber() == expectedFrameNum) {
// success! got a frame. // success! got a frame.
if (frameData.length != 64) { if (frameData.length != 64) {
if (isLogEnabled()) aapsLogger.warn(LTag.PUMPCOMM, "Expected frame of length 64, got frame of length " + frameData.length);
LOG.warn("Expected frame of length 64, got frame of length " + frameData.length);
// but append it anyway? // but append it anyway?
} }
// handle successful frame data // handle successful frame data
rawHistoryPage.appendData(currentResponse.getFrameData()); rawHistoryPage.appendData(currentResponse.getFrameData());
// RileyLinkMedtronicService.getInstance().announceProgress(((100 / 16) * // RileyLinkMedtronicService.getInstance().announceProgress(((100 / 16) *
// currentResponse.getFrameNumber() + 1)); // currentResponse.getFrameNumber() + 1));
MedtronicUtil.setCurrentCommand(MedtronicCommandType.GetHistoryData, pageNumber, medtronicUtil.setCurrentCommand(MedtronicCommandType.GetHistoryData, pageNumber,
currentResponse.getFrameNumber()); currentResponse.getFrameNumber());
if (isLogEnabled()) aapsLogger.info(LTag.PUMPCOMM, "getPumpHistory: Got frame {} of Page {}", currentResponse.getFrameNumber(), pageNumber);
LOG.info("getPumpHistory: Got frame {} of Page {}", currentResponse.getFrameNumber(), pageNumber);
// Do we need to ask for the next frame? // Do we need to ask for the next frame?
if (expectedFrameNum < 16) { // This number may not be correct for pumps other than 522/722 if (expectedFrameNum < 16) { // This number may not be correct for pumps other than 522/722
expectedFrameNum++; expectedFrameNum++;
@ -405,22 +385,18 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
} }
} else { } else {
if (frameData == null) { if (frameData == null) {
if (isLogEnabled()) aapsLogger.error(LTag.PUMPCOMM, "null frame data, retrying");
LOG.error("null frame data, retrying");
} else if (currentResponse.getFrameNumber() != expectedFrameNum) { } else if (currentResponse.getFrameNumber() != expectedFrameNum) {
if (isLogEnabled()) aapsLogger.warn(LTag.PUMPCOMM, "Expected frame number {}, received {} (retrying)", expectedFrameNum,
LOG.warn("Expected frame number {}, received {} (retrying)", expectedFrameNum, currentResponse.getFrameNumber());
currentResponse.getFrameNumber());
} else if (frameData.length == 0) { } else if (frameData.length == 0) {
if (isLogEnabled()) aapsLogger.warn(LTag.PUMPCOMM, "Frame has zero length, retrying");
LOG.warn("Frame has zero length, retrying");
} }
failures++; failures++;
if (failures == 6) { if (failures == 6) {
if (isLogEnabled()) aapsLogger.error(LTag.PUMPCOMM,
LOG.error( "getPumpHistory: 6 failures in attempting to download frame {} of page {}, giving up.",
"getPumpHistory: 6 failures in attempting to download frame {} of page {}, giving up.", expectedFrameNum, pageNumber);
expectedFrameNum, pageNumber);
done = true; // failure completion. done = true; // failure completion.
doneWithError = true; doneWithError = true;
} }
@ -436,59 +412,52 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
nextMsg = sendAndListen(ackMsg); nextMsg = sendAndListen(ackMsg);
break; break;
} catch (RileyLinkCommunicationException e) { } catch (RileyLinkCommunicationException e) {
if (isLogEnabled()) aapsLogger.error(LTag.PUMPCOMM, "Problem acknowledging frame response. (retry={})", retries);
LOG.error("Problem acknowledging frame response. (retry={})", retries);
} }
} }
if (nextMsg != null) if (nextMsg != null)
currentResponse = new GetHistoryPageCarelinkMessageBody(nextMsg.getMessageBody().getTxData()); currentResponse = new GetHistoryPageCarelinkMessageBody(nextMsg.getMessageBody().getTxData());
else { else {
if (isLogEnabled()) aapsLogger.error(LTag.PUMPCOMM, "We couldn't acknowledge frame from pump, aborting operation.");
LOG.error("We couldn't acknowledge frame from pump, aborting operation.");
} }
} }
} }
if (rawHistoryPage.getLength() != 1024) { if (rawHistoryPage.getLength() != 1024) {
if (isLogEnabled()) aapsLogger.warn(LTag.PUMPCOMM, "getPumpHistory: short page. Expected length of 1024, found length of "
LOG.warn("getPumpHistory: short page. Expected length of 1024, found length of " + rawHistoryPage.getLength());
+ rawHistoryPage.getLength());
doneWithError = true; doneWithError = true;
} }
if (!rawHistoryPage.isChecksumOK()) { if (!rawHistoryPage.isChecksumOK()) {
if (isLogEnabled()) aapsLogger.error(LTag.PUMPCOMM, "getPumpHistory: checksum is wrong");
LOG.error("getPumpHistory: checksum is wrong");
doneWithError = true; doneWithError = true;
} }
if (doneWithError) { if (doneWithError) {
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Sleeping); medtronicPumpStatus.setPumpDeviceState(PumpDeviceState.Sleeping);
return pumpTotalResult; return pumpTotalResult;
} }
rawHistoryPage.dumpToDebug(); rawHistoryPage.dumpToDebug();
List<PumpHistoryEntry> medtronicHistoryEntries = pumpHistoryDecoder List<PumpHistoryEntry> medtronicHistoryEntries = medtronicPumpHistoryDecoder.processPageAndCreateRecords(rawHistoryPage);
.processPageAndCreateRecords(rawHistoryPage);
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "getPumpHistory: Found {} history entries.", medtronicHistoryEntries.size());
LOG.debug("getPumpHistory: Found {} history entries.", medtronicHistoryEntries.size());
pumpTotalResult.addHistoryEntries(medtronicHistoryEntries, pageNumber); pumpTotalResult.addHistoryEntries(medtronicHistoryEntries, pageNumber);
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "getPumpHistory: Search status: Search finished: {}", pumpTotalResult.isSearchFinished());
LOG.debug("getPumpHistory: Search status: Search finished: {}", pumpTotalResult.isSearchFinished());
if (pumpTotalResult.isSearchFinished()) { if (pumpTotalResult.isSearchFinished()) {
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Sleeping); medtronicPumpStatus.setPumpDeviceState(PumpDeviceState.Sleeping);
return pumpTotalResult; return pumpTotalResult;
} }
} }
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Sleeping); medtronicPumpStatus.setPumpDeviceState(PumpDeviceState.Sleeping);
return pumpTotalResult; return pumpTotalResult;
@ -504,11 +473,11 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
public byte[] createPumpMessageContent(RLMessageType type) { public byte[] createPumpMessageContent(RLMessageType type) {
switch (type) { switch (type) {
case PowerOn: case PowerOn:
return MedtronicUtil.buildCommandPayload(MedtronicCommandType.RFPowerOn, // return medtronicUtil.buildCommandPayload(rileyLinkServiceData, MedtronicCommandType.RFPowerOn, //
new byte[]{2, 1, (byte) receiverDeviceAwakeForMinutes}); // maybe this is better FIXME new byte[]{2, 1, (byte) receiverDeviceAwakeForMinutes}); // maybe this is better FIXME
case ReadSimpleData: case ReadSimpleData:
return MedtronicUtil.buildCommandPayload(MedtronicCommandType.PumpModel, null); return medtronicUtil.buildCommandPayload(rileyLinkServiceData, MedtronicCommandType.PumpModel, null);
} }
return new byte[0]; return new byte[0];
} }
@ -526,7 +495,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
private PumpMessage makePumpMessage(MedtronicCommandType messageType, MessageBody messageBody) { private PumpMessage makePumpMessage(MedtronicCommandType messageType, MessageBody messageBody) {
PumpMessage msg = new PumpMessage(); PumpMessage msg = new PumpMessage(aapsLogger);
msg.init(PacketType.Carelink, rileyLinkServiceData.pumpIDBytes, messageType, messageBody); msg.init(PacketType.Carelink, rileyLinkServiceData.pumpIDBytes, messageType, messageBody);
return msg; return msg;
} }
@ -552,7 +521,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
if (doWakeUpBeforeCommand) if (doWakeUpBeforeCommand)
wakeUp(receiverDeviceAwakeForMinutes, false); wakeUp(receiverDeviceAwakeForMinutes, false);
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Active); medtronicPumpStatus.setPumpDeviceState(PumpDeviceState.Active);
// create message // create message
PumpMessage msg; PumpMessage msg;
@ -565,7 +534,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
// send and wait for response // send and wait for response
PumpMessage response = sendAndListen(msg, timeoutMs); PumpMessage response = sendAndListen(msg, timeoutMs);
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Sleeping); medtronicPumpStatus.setPumpDeviceState(PumpDeviceState.Sleeping);
return response; return response;
} }
@ -590,27 +559,22 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
private Object sendAndGetResponseWithCheck(MedtronicCommandType commandType, byte[] bodyData) { private Object sendAndGetResponseWithCheck(MedtronicCommandType commandType, byte[] bodyData) {
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "getDataFromPump: {}", commandType);
LOG.debug("getDataFromPump: {}", commandType);
for (int retries = 0; retries < MAX_COMMAND_TRIES; retries++) { for (int retries = 0; retries < MAX_COMMAND_TRIES; retries++) {
try { try {
PumpMessage response = null; PumpMessage response = sendAndGetResponse(commandType, bodyData, DEFAULT_TIMEOUT + (DEFAULT_TIMEOUT * retries));
response = sendAndGetResponse(commandType, bodyData, DEFAULT_TIMEOUT + (DEFAULT_TIMEOUT * retries)); String check = checkResponseContent(response, commandType.commandDescription, commandType.expectedLength);
String check = checkResponseContent(response, commandType.commandDescription,
commandType.expectedLength);
if (check == null) { if (check == null) {
Object dataResponse = medtronicConverter.convertResponse(commandType, response.getRawContent()); Object dataResponse = medtronicConverter.convertResponse(medtronicPumpPlugin.getPumpDescription().pumpType, commandType, response.getRawContent());
if (dataResponse != null) { if (dataResponse != null) {
this.errorMessage = null; this.errorMessage = null;
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "Converted response for {} is {}.", commandType.name(), dataResponse);
LOG.debug("Converted response for {} is {}.", commandType.name(), dataResponse);
return dataResponse; return dataResponse;
} else { } else {
@ -622,8 +586,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
} }
} catch (RileyLinkCommunicationException e) { } catch (RileyLinkCommunicationException e) {
if (isLogEnabled()) aapsLogger.warn(LTag.PUMPCOMM, "Error getting response from RileyLink (error={}, retry={})", e.getMessage(), retries + 1);
LOG.warn("Error getting response from RileyLink (error={}, retry={})", e.getMessage(), retries + 1);
} }
} }
@ -636,8 +599,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
if (!response.isValid()) { if (!response.isValid()) {
String responseData = String.format("%s: Invalid response.", method); String responseData = String.format("%s: Invalid response.", method);
if (isLogEnabled()) aapsLogger.warn(LTag.PUMPCOMM, responseData);
LOG.warn(responseData);
return responseData; return responseData;
} }
@ -645,7 +607,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
if (contents != null) { if (contents != null) {
if (contents.length >= expectedLength) { if (contents.length >= expectedLength) {
LOG.trace("{}: Content: {}", method, ByteUtil.shortHexString(contents)); aapsLogger.debug(LTag.PUMPCOMM, "{}: Content: {}", method, ByteUtil.shortHexString(contents));
return null; return null;
} else { } else {
@ -653,13 +615,12 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
"%s: Cannot return data. Data is too short [expected=%s, received=%s].", method, "" "%s: Cannot return data. Data is too short [expected=%s, received=%s].", method, ""
+ expectedLength, "" + contents.length); + expectedLength, "" + contents.length);
if (isLogEnabled()) aapsLogger.warn(LTag.PUMPCOMM, responseData);
LOG.warn(responseData);
return responseData; return responseData;
} }
} else { } else {
String responseData = String.format("%s: Cannot return data. Null response.", method); String responseData = String.format("%s: Cannot return data. Null response.", method);
LOG.warn(responseData); aapsLogger.warn(LTag.PUMPCOMM, responseData);
return responseData; return responseData;
} }
} }
@ -691,12 +652,11 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
MedtronicCommandType commandType = MedtronicCommandType.GetBasalProfileSTD; MedtronicCommandType commandType = MedtronicCommandType.GetBasalProfileSTD;
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "getDataFromPump: {}", commandType);
LOG.debug("getDataFromPump: {}", commandType);
MedtronicUtil.setCurrentCommand(commandType); medtronicUtil.setCurrentCommand(commandType);
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Active); medtronicPumpStatus.setPumpDeviceState(PumpDeviceState.Active);
for (int retries = 0; retries <= MAX_COMMAND_TRIES; retries++) { for (int retries = 0; retries <= MAX_COMMAND_TRIES; retries++) {
@ -707,12 +667,11 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
msg = makePumpMessage(commandType); msg = makePumpMessage(commandType);
// send and wait for response // send and wait for response
PumpMessage response = null;
response = sendAndListen(msg, DEFAULT_TIMEOUT + (DEFAULT_TIMEOUT * retries)); PumpMessage response = sendAndListen(msg, DEFAULT_TIMEOUT + (DEFAULT_TIMEOUT * retries));
// LOG.debug("1st Response: " + HexDump.toHexStringDisplayable(response.getRawContent())); // aapsLogger.debug(LTag.PUMPCOMM,"1st Response: " + HexDump.toHexStringDisplayable(response.getRawContent()));
// LOG.debug("1st Response: " + HexDump.toHexStringDisplayable(response.getMessageBody().getTxData())); // aapsLogger.debug(LTag.PUMPCOMM,"1st Response: " + HexDump.toHexStringDisplayable(response.getMessageBody().getTxData()));
String check = checkResponseContent(response, commandType.commandDescription, 1); String check = checkResponseContent(response, commandType.commandDescription, 1);
@ -728,8 +687,8 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
response = sendAndListen(ackMsg, DEFAULT_TIMEOUT + (DEFAULT_TIMEOUT * retries)); response = sendAndListen(ackMsg, DEFAULT_TIMEOUT + (DEFAULT_TIMEOUT * retries));
// LOG.debug("{} Response: {}", runs, HexDump.toHexStringDisplayable(response2.getRawContent())); // aapsLogger.debug(LTag.PUMPCOMM,"{} Response: {}", runs, HexDump.toHexStringDisplayable(response2.getRawContent()));
// LOG.debug("{} Response: {}", runs, // aapsLogger.debug(LTag.PUMPCOMM,"{} Response: {}", runs,
// HexDump.toHexStringDisplayable(response2.getMessageBody().getTxData())); // HexDump.toHexStringDisplayable(response2.getMessageBody().getTxData()));
String check2 = checkResponseContent(response, commandType.commandDescription, 1); String check2 = checkResponseContent(response, commandType.commandDescription, 1);
@ -740,7 +699,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
} else { } else {
this.errorMessage = check2; this.errorMessage = check2;
LOG.error("Error with response got GetProfile: " + check2); aapsLogger.error(LTag.PUMPCOMM, "Error with response got GetProfile: " + check2);
} }
} }
@ -748,26 +707,25 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
errorMessage = check; errorMessage = check;
} }
BasalProfile basalProfile = (BasalProfile) medtronicConverter.convertResponse(commandType, data); BasalProfile basalProfile = (BasalProfile) medtronicConverter.convertResponse(medtronicPumpPlugin.getPumpDescription().pumpType, commandType, data);
if (basalProfile != null) { if (basalProfile != null) {
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "Converted response for {} is {}.", commandType.name(), basalProfile);
LOG.debug("Converted response for {} is {}.", commandType.name(), basalProfile);
MedtronicUtil.setCurrentCommand(null); medtronicUtil.setCurrentCommand(null);
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Sleeping); medtronicPumpStatus.setPumpDeviceState(PumpDeviceState.Sleeping);
return basalProfile; return basalProfile;
} }
} catch (RileyLinkCommunicationException e) { } catch (RileyLinkCommunicationException e) {
LOG.error("Error getting response from RileyLink (error={}, retry={})", e.getMessage(), retries + 1); aapsLogger.error(LTag.PUMPCOMM, "Error getting response from RileyLink (error={}, retry={})", e.getMessage(), retries + 1);
} }
} }
LOG.warn("Error reading profile in max retries."); aapsLogger.warn(LTag.PUMPCOMM, "Error reading profile in max retries.");
MedtronicUtil.setCurrentCommand(null); medtronicUtil.setCurrentCommand(null);
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Sleeping); medtronicPumpStatus.setPumpDeviceState(PumpDeviceState.Sleeping);
return null; return null;
@ -783,7 +741,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
int last = responseRaw.length - 1; int last = responseRaw.length - 1;
LOG.debug("Length: " + data.length); aapsLogger.debug(LTag.PUMPCOMM, "Length: " + data.length);
if (data.length >= BasalProfile.MAX_RAW_DATA_SIZE) { if (data.length >= BasalProfile.MAX_RAW_DATA_SIZE) {
return false; return false;
@ -826,7 +784,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
public Map<String, PumpSettingDTO> getPumpSettings() { public Map<String, PumpSettingDTO> getPumpSettings() {
Object responseObject = sendAndGetResponseWithCheck(MedtronicCommandType.getSettings(MedtronicUtil Object responseObject = sendAndGetResponseWithCheck(MedtronicCommandType.getSettings(medtronicUtil
.getMedtronicPumpModel())); .getMedtronicPumpModel()));
return responseObject == null ? null : (Map<String, PumpSettingDTO>) responseObject; return responseObject == null ? null : (Map<String, PumpSettingDTO>) responseObject;
@ -835,18 +793,16 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
public Boolean setBolus(double units) { public Boolean setBolus(double units) {
if (isLogEnabled()) aapsLogger.info(LTag.PUMPCOMM, "setBolus: " + units);
LOG.info("setBolus: " + units);
return setCommand(MedtronicCommandType.SetBolus, MedtronicUtil.getBolusStrokes(units)); return setCommand(MedtronicCommandType.SetBolus, medtronicUtil.getBolusStrokes(units));
} }
public boolean setTBR(TempBasalPair tbr) { public boolean setTBR(TempBasalPair tbr) {
if (isLogEnabled()) aapsLogger.info(LTag.PUMPCOMM, "setTBR: " + tbr.getDescription());
LOG.info("setTBR: " + tbr.getDescription());
return setCommand(MedtronicCommandType.SetTemporaryBasal, tbr.getAsRawData()); return setCommand(MedtronicCommandType.SetTemporaryBasal, tbr.getAsRawData());
} }
@ -857,8 +813,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
GregorianCalendar gc = new GregorianCalendar(); GregorianCalendar gc = new GregorianCalendar();
gc.add(Calendar.SECOND, 5); gc.add(Calendar.SECOND, 5);
if (isLogEnabled()) aapsLogger.info(LTag.PUMPCOMM, "setPumpTime: " + DateTimeUtil.toString(gc));
LOG.info("setPumpTime: " + DateTimeUtil.toString(gc));
int i = 1; int i = 1;
byte[] data = new byte[8]; byte[] data = new byte[8];
@ -867,7 +822,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
data[i + 1] = (byte) gc.get(Calendar.MINUTE); data[i + 1] = (byte) gc.get(Calendar.MINUTE);
data[i + 2] = (byte) gc.get(Calendar.SECOND); data[i + 2] = (byte) gc.get(Calendar.SECOND);
byte[] yearByte = MedtronicUtil.getByteArrayFromUnsignedShort(gc.get(Calendar.YEAR), true); byte[] yearByte = medtronicUtil.getByteArrayFromUnsignedShort(gc.get(Calendar.YEAR), true);
data[i + 3] = yearByte[0]; data[i + 3] = yearByte[0];
data[i + 4] = yearByte[1]; data[i + 4] = yearByte[1];
@ -875,7 +830,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
data[i + 5] = (byte) (gc.get(Calendar.MONTH) + 1); data[i + 5] = (byte) (gc.get(Calendar.MONTH) + 1);
data[i + 6] = (byte) gc.get(Calendar.DAY_OF_MONTH); data[i + 6] = (byte) gc.get(Calendar.DAY_OF_MONTH);
//LOG.info("setPumpTime: Body: " + ByteUtil.getHex(data)); //aapsLogger.info(LTag.PUMPCOMM,"setPumpTime: Body: " + ByteUtil.getHex(data));
return setCommand(MedtronicCommandType.SetRealTimeClock, data); return setCommand(MedtronicCommandType.SetRealTimeClock, data);
@ -891,7 +846,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
wakeUp(false); wakeUp(false);
if (debugSetCommands) if (debugSetCommands)
LOG.debug("{}: Body - {}", commandType.getCommandDescription(), aapsLogger.debug(LTag.PUMPCOMM, "{}: Body - {}", commandType.getCommandDescription(),
ByteUtil.getHex(body)); ByteUtil.getHex(body));
PumpMessage msg = makePumpMessage(commandType, new CarelinkLongMessageBody(body)); PumpMessage msg = makePumpMessage(commandType, new CarelinkLongMessageBody(body));
@ -899,17 +854,16 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
PumpMessage pumpMessage = runCommandWithArgs(msg); PumpMessage pumpMessage = runCommandWithArgs(msg);
if (debugSetCommands) if (debugSetCommands)
LOG.debug("{}: {}", commandType.getCommandDescription(), pumpMessage.getResponseContent()); aapsLogger.debug(LTag.PUMPCOMM, "{}: {}", commandType.getCommandDescription(), pumpMessage.getResponseContent());
if (pumpMessage.commandType == MedtronicCommandType.CommandACK) { if (pumpMessage.commandType == MedtronicCommandType.CommandACK) {
return true; return true;
} else { } else {
LOG.warn("We received non-ACK response from pump: {}", pumpMessage.getResponseContent()); aapsLogger.warn(LTag.PUMPCOMM, "We received non-ACK response from pump: {}", pumpMessage.getResponseContent());
} }
} catch (RileyLinkCommunicationException e) { } catch (RileyLinkCommunicationException e) {
if (isLogEnabled()) aapsLogger.warn(LTag.PUMPCOMM, "Error getting response from RileyLink (error={}, retry={})", e.getMessage(), retries + 1);
LOG.warn("Error getting response from RileyLink (error={}, retry={})", e.getMessage(), retries + 1);
} }
} }
@ -932,7 +886,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
public Boolean setBasalProfile(BasalProfile basalProfile) { public Boolean setBasalProfile(BasalProfile basalProfile) {
List<List<Byte>> basalProfileFrames = MedtronicUtil.getBasalProfileFrames(basalProfile.getRawData()); List<List<Byte>> basalProfileFrames = medtronicUtil.getBasalProfileFrames(basalProfile.getRawData());
for (int retries = 0; retries <= MAX_COMMAND_TRIES; retries++) { for (int retries = 0; retries <= MAX_COMMAND_TRIES; retries++) {
@ -945,23 +899,20 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
return true; return true;
} catch (RileyLinkCommunicationException e) { } catch (RileyLinkCommunicationException e) {
LOG.warn("Error getting response from RileyLink (error={}, retry={})", e.getMessage(), retries + 1); aapsLogger.warn(LTag.PUMPCOMM, "Error getting response from RileyLink (error={}, retry={})", e.getMessage(), retries + 1);
} }
if (responseMessage != null) if (responseMessage != null)
LOG.warn("Set Basal Profile: Invalid response: commandType={},rawData={}", responseMessage.commandType, ByteUtil.shortHexString(responseMessage.getRawContent())); aapsLogger.warn(LTag.PUMPCOMM, "Set Basal Profile: Invalid response: commandType={},rawData={}", responseMessage.commandType, ByteUtil.shortHexString(responseMessage.getRawContent()));
else else
LOG.warn("Set Basal Profile: Null response."); aapsLogger.warn(LTag.PUMPCOMM, "Set Basal Profile: Null response.");
} }
return false; return false;
} }
@Override public PumpStatus getPumpStatus() {
private boolean isLogEnabled() { return medtronicPumpStatus;
return L.isEnabled(L.PUMPCOMM);
} }
} }

View file

@ -2,14 +2,16 @@ package info.nightscout.androidaps.plugins.pump.medtronic.comm;
import org.joda.time.IllegalFieldValueException; import org.joda.time.IllegalFieldValueException;
import org.joda.time.LocalDateTime; import org.joda.time.LocalDateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import info.nightscout.androidaps.logging.L; import javax.inject.Inject;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; import javax.inject.Singleton;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil; import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil;
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BasalProfile; import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BasalProfile;
@ -26,25 +28,30 @@ import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
* High level decoder for data returned through MedtroniUIComm * High level decoder for data returned through MedtroniUIComm
*/ */
@Singleton
public class MedtronicConverter { public class MedtronicConverter {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPCOMM); private final AAPSLogger aapsLogger;
private final MedtronicUtil medtronicUtil;
MedtronicDeviceType pumpModel; @Inject
public MedtronicConverter(
AAPSLogger aapsLogger,
MedtronicUtil medtronicUtil
) {
this.aapsLogger = aapsLogger;
this.medtronicUtil = medtronicUtil;
}
Object convertResponse(PumpType pumpType, MedtronicCommandType commandType, byte[] rawContent) {
public Object convertResponse(MedtronicCommandType commandType, byte[] rawContent) {
if ((rawContent == null || rawContent.length < 1) && commandType != MedtronicCommandType.PumpModel) { if ((rawContent == null || rawContent.length < 1) && commandType != MedtronicCommandType.PumpModel) {
LOG.warn("Content is empty or too short, no data to convert (type={},isNull={},length={})", aapsLogger.warn(LTag.PUMPCOMM, "Content is empty or too short, no data to convert (type={},isNull={},length={})",
commandType.name(), rawContent == null, rawContent == null ? "-" : rawContent.length); commandType.name(), rawContent == null, rawContent == null ? "-" : rawContent.length);
return null; return null;
} }
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "Raw response before convert: " + ByteUtil.shortHexString(rawContent));
LOG.debug("Raw response before convert: " + ByteUtil.shortHexString(rawContent));
this.pumpModel = MedtronicUtil.getMedtronicPumpModel();
switch (commandType) { switch (commandType) {
@ -67,12 +74,12 @@ public class MedtronicConverter {
case GetBasalProfileSTD: case GetBasalProfileSTD:
case GetBasalProfileA: case GetBasalProfileA:
case GetBasalProfileB: { case GetBasalProfileB: {
return decodeBasalProfile(rawContent); return decodeBasalProfile(pumpType, rawContent);
} }
case ReadTemporaryBasal: { case ReadTemporaryBasal: {
return new TempBasalPair(rawContent); // 5 return new TempBasalPair(aapsLogger, rawContent); // 5
} }
case Settings_512: { case Settings_512: {
@ -96,29 +103,28 @@ public class MedtronicConverter {
} }
private BasalProfile decodeBasalProfile(byte[] rawContent) { private BasalProfile decodeBasalProfile(PumpType pumpType, byte[] rawContent) {
BasalProfile basalProfile = new BasalProfile(rawContent); BasalProfile basalProfile = new BasalProfile(aapsLogger, rawContent);
return basalProfile.verify() ? basalProfile : null; return basalProfile.verify(pumpType) ? basalProfile : null;
} }
private MedtronicDeviceType decodeModel(byte[] rawContent) { private MedtronicDeviceType decodeModel(byte[] rawContent) {
if ((rawContent == null || rawContent.length < 4)) { if ((rawContent == null || rawContent.length < 4)) {
LOG.warn("Error reading PumpModel, returning Unknown_Device"); aapsLogger.warn(LTag.PUMPCOMM, "Error reading PumpModel, returning Unknown_Device");
return MedtronicDeviceType.Unknown_Device; return MedtronicDeviceType.Unknown_Device;
} }
String rawModel = StringUtil.fromBytes(ByteUtil.substring(rawContent, 1, 3)); String rawModel = StringUtil.fromBytes(ByteUtil.substring(rawContent, 1, 3));
MedtronicDeviceType pumpModel = MedtronicDeviceType.getByDescription(rawModel); MedtronicDeviceType pumpModel = MedtronicDeviceType.getByDescription(rawModel);
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "PumpModel: [raw={}, resolved={}]", rawModel, pumpModel.name());
LOG.debug("PumpModel: [raw={}, resolved={}]", rawModel, pumpModel.name());
if (pumpModel != MedtronicDeviceType.Unknown_Device) { if (pumpModel != MedtronicDeviceType.Unknown_Device) {
if (!MedtronicUtil.isModelSet()) { if (!medtronicUtil.isModelSet()) {
MedtronicUtil.setMedtronicPumpModel(pumpModel); medtronicUtil.setMedtronicPumpModel(pumpModel);
} }
} }
@ -154,10 +160,10 @@ public class MedtronicConverter {
} }
protected Float decodeRemainingInsulin(byte[] rawData) { private Float decodeRemainingInsulin(byte[] rawData) {
int startIdx = 0; int startIdx = 0;
this.pumpModel = MedtronicUtil.getMedtronicPumpModel(); MedtronicDeviceType pumpModel = medtronicUtil.getMedtronicPumpModel();
int strokes = pumpModel == null ? 10 : pumpModel.getBolusStrokes(); int strokes = pumpModel == null ? 10 : pumpModel.getBolusStrokes();
@ -167,8 +173,7 @@ public class MedtronicConverter {
float value = ByteUtil.toInt(rawData[startIdx], rawData[startIdx + 1]) / (1.0f * strokes); float value = ByteUtil.toInt(rawData[startIdx], rawData[startIdx + 1]) / (1.0f * strokes);
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "Remaining insulin: " + value);
LOG.debug("Remaining insulin: " + value);
return value; return value;
} }
@ -185,7 +190,7 @@ public class MedtronicConverter {
LocalDateTime pumpTime = new LocalDateTime(year, month, day, hours, minutes, seconds); LocalDateTime pumpTime = new LocalDateTime(year, month, day, hours, minutes, seconds);
return pumpTime; return pumpTime;
} catch (IllegalFieldValueException e) { } catch (IllegalFieldValueException e) {
LOG.error( aapsLogger.error(LTag.PUMPCOMM,
"decodeTime: Failed to parse pump time value: year=%d, month=%d, hours=%d, minutes=%d, seconds=%d", "decodeTime: Failed to parse pump time value: year=%d, month=%d, hours=%d, minutes=%d, seconds=%d",
year, month, day, hours, minutes, seconds); year, month, day, hours, minutes, seconds);
return null; return null;
@ -194,7 +199,7 @@ public class MedtronicConverter {
} }
public Map<String, PumpSettingDTO> decodeSettingsLoop(byte[] rd) { private Map<String, PumpSettingDTO> decodeSettingsLoop(byte[] rd) {
Map<String, PumpSettingDTO> map = new HashMap<>(); Map<String, PumpSettingDTO> map = new HashMap<>();
@ -271,7 +276,7 @@ public class MedtronicConverter {
addSettingToMap("CFG_BASE_CLOCK_MODE", rd[getSettingIndexTimeDisplayFormat()] == 0 ? "12h" : "24h", addSettingToMap("CFG_BASE_CLOCK_MODE", rd[getSettingIndexTimeDisplayFormat()] == 0 ? "12h" : "24h",
PumpConfigurationGroup.General, map); PumpConfigurationGroup.General, map);
if (MedtronicDeviceType.isSameDevice(pumpModel, MedtronicDeviceType.Medtronic_523andHigher)) { if (MedtronicDeviceType.isSameDevice(medtronicUtil.getMedtronicPumpModel(), MedtronicDeviceType.Medtronic_523andHigher)) {
addSettingToMap("PCFG_INSULIN_CONCENTRATION", "" + (rd[9] == 0 ? 50 : 100), PumpConfigurationGroup.Insulin, addSettingToMap("PCFG_INSULIN_CONCENTRATION", "" + (rd[9] == 0 ? 50 : 100), PumpConfigurationGroup.Insulin,
map); map);
// LOG.debug("Insulin concentration: " + rd[9]); // LOG.debug("Insulin concentration: " + rd[9]);
@ -323,7 +328,7 @@ public class MedtronicConverter {
} }
public void addSettingToMap(String key, String value, PumpConfigurationGroup group, Map<String, PumpSettingDTO> map) { private void addSettingToMap(String key, String value, PumpConfigurationGroup group, Map<String, PumpSettingDTO> map) {
map.put(key, new PumpSettingDTO(key, value, group)); map.put(key, new PumpSettingDTO(key, value, group));
} }
@ -339,7 +344,7 @@ public class MedtronicConverter {
addSettingToMap("CFG_MM_KEYPAD_LOCKED", parseResultEnable(rd[20]), PumpConfigurationGroup.Other, map); addSettingToMap("CFG_MM_KEYPAD_LOCKED", parseResultEnable(rd[20]), PumpConfigurationGroup.Other, map);
if (MedtronicDeviceType.isSameDevice(pumpModel, MedtronicDeviceType.Medtronic_523andHigher)) { if (MedtronicDeviceType.isSameDevice(medtronicUtil.getMedtronicPumpModel(), MedtronicDeviceType.Medtronic_523andHigher)) {
addSettingToMap("PCFG_BOLUS_SCROLL_STEP_SIZE", "" + rd[21], PumpConfigurationGroup.Bolus, map); addSettingToMap("PCFG_BOLUS_SCROLL_STEP_SIZE", "" + rd[21], PumpConfigurationGroup.Bolus, map);
addSettingToMap("PCFG_CAPTURE_EVENT_ENABLE", parseResultEnable(rd[22]), PumpConfigurationGroup.Other, map); addSettingToMap("PCFG_CAPTURE_EVENT_ENABLE", parseResultEnable(rd[22]), PumpConfigurationGroup.Other, map);
@ -352,7 +357,7 @@ public class MedtronicConverter {
} }
protected String parseResultEnable(int i) { private String parseResultEnable(int i) {
switch (i) { switch (i) {
case 0: case 0:
return "No"; return "No";
@ -364,19 +369,19 @@ public class MedtronicConverter {
} }
public float getStrokesPerUnit(boolean isBasal) { private float getStrokesPerUnit(boolean isBasal) {
return isBasal ? 40.0f : 10; // pumpModel.getBolusStrokes(); return isBasal ? 40.0f : 10; // pumpModel.getBolusStrokes();
} }
// 512 // 512
public void decodeInsulinActionSetting(byte[] ai, Map<String, PumpSettingDTO> map) { private void decodeInsulinActionSetting(byte[] ai, Map<String, PumpSettingDTO> map) {
if (MedtronicDeviceType.isSameDevice(pumpModel, MedtronicDeviceType.Medtronic_512_712)) { if (MedtronicDeviceType.isSameDevice(medtronicUtil.getMedtronicPumpModel(), MedtronicDeviceType.Medtronic_512_712)) {
addSettingToMap("PCFG_INSULIN_ACTION_TYPE", (ai[17] != 0 ? "Regular" : "Fast"), addSettingToMap("PCFG_INSULIN_ACTION_TYPE", (ai[17] != 0 ? "Regular" : "Fast"),
PumpConfigurationGroup.Insulin, map); PumpConfigurationGroup.Insulin, map);
} else { } else {
int i = ai[17]; int i = ai[17];
String s = ""; String s;
if ((i == 0) || (i == 1)) { if ((i == 0) || (i == 1)) {
s = ai[17] != 0 ? "Regular" : "Fast"; s = ai[17] != 0 ? "Regular" : "Fast";
@ -392,12 +397,12 @@ public class MedtronicConverter {
} }
public double decodeBasalInsulin(int i) { private double decodeBasalInsulin(int i) {
return (double) i / (double) getStrokesPerUnit(true); return (double) i / (double) getStrokesPerUnit(true);
} }
public double decodeBolusInsulin(int i) { private double decodeBolusInsulin(int i) {
return (double) i / (double) getStrokesPerUnit(false); return (double) i / (double) getStrokesPerUnit(false);
} }
@ -413,19 +418,13 @@ public class MedtronicConverter {
} }
public double decodeMaxBolus(byte[] ai) { private double decodeMaxBolus(byte[] ai) {
return is523orHigher() ? decodeBolusInsulin(ByteUtil.toInt(ai[5], ai[6])) : decodeBolusInsulin(ByteUtil return is523orHigher() ? decodeBolusInsulin(ByteUtil.toInt(ai[5], ai[6])) : decodeBolusInsulin(ByteUtil
.asUINT8(ai[5])); .asUINT8(ai[5]));
} }
private boolean is523orHigher() { private boolean is523orHigher() {
return (MedtronicDeviceType.isSameDevice(pumpModel, MedtronicDeviceType.Medtronic_523andHigher)); return (MedtronicDeviceType.isSameDevice(medtronicUtil.getMedtronicPumpModel(), MedtronicDeviceType.Medtronic_523andHigher));
} }
private boolean isLogEnabled() {
return L.isEnabled(L.PUMPCOMM);
}
} }

View file

@ -1,32 +1,32 @@
package info.nightscout.androidaps.plugins.pump.medtronic.comm.history; package info.nightscout.androidaps.plugins.pump.medtronic.comm.history;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import info.nightscout.androidaps.logging.L; import javax.inject.Inject;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil; import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil;
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil; import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
/** /**
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes * This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
* management and modified/extended for AAPS. * management and modified/extended for AAPS.
* * <p>
* Author: Andy {andy.rozman@gmail.com} * Author: Andy {andy.rozman@gmail.com}
*/ */
public abstract class MedtronicHistoryDecoder<T extends MedtronicHistoryEntry> implements MedtronicHistoryDecoderInterface<T> { public abstract class MedtronicHistoryDecoder<T extends MedtronicHistoryEntry> implements MedtronicHistoryDecoderInterface<T> {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPCOMM); @Inject AAPSLogger aapsLogger;
@Inject MedtronicUtil medtronicUtil;
protected ByteUtil bitUtils; protected ByteUtil bitUtils;
@ -34,7 +34,6 @@ public abstract class MedtronicHistoryDecoder<T extends MedtronicHistoryEntry> i
protected boolean statisticsEnabled = true; protected boolean statisticsEnabled = true;
protected Map<Integer, Integer> unknownOpCodes; protected Map<Integer, Integer> unknownOpCodes;
protected Map<RecordDecodeStatus, Map<String, String>> mapStatistics; protected Map<RecordDecodeStatus, Map<String, String>> mapStatistics;
protected MedtronicDeviceType deviceType;
public MedtronicHistoryDecoder() { public MedtronicHistoryDecoder() {
@ -62,8 +61,8 @@ public abstract class MedtronicHistoryDecoder<T extends MedtronicHistoryEntry> i
// return byteList; // return byteList;
// } // }
if (MedtronicUtil.getMedtronicPumpModel() == null) { if (medtronicUtil.getMedtronicPumpModel() == null) {
LOG.error("Device Type is not defined."); aapsLogger.error(LTag.PUMPCOMM, "Device Type is not defined.");
return byteList; return byteList;
} }
@ -86,17 +85,16 @@ public abstract class MedtronicHistoryDecoder<T extends MedtronicHistoryEntry> i
if (!statisticsEnabled) if (!statisticsEnabled)
return; return;
unknownOpCodes = new HashMap<Integer, Integer>(); unknownOpCodes = new HashMap<>();
mapStatistics = new HashMap<RecordDecodeStatus, Map<String, String>>(); mapStatistics = new HashMap<>();
for (RecordDecodeStatus stat : RecordDecodeStatus.values()) { for (RecordDecodeStatus stat : RecordDecodeStatus.values()) {
mapStatistics.put(stat, new HashMap<String, String>()); mapStatistics.put(stat, new HashMap<>());
} }
} }
protected void addToStatistics(MedtronicHistoryEntryInterface pumpHistoryEntry, RecordDecodeStatus status, protected void addToStatistics(MedtronicHistoryEntryInterface pumpHistoryEntry, RecordDecodeStatus status, Integer opCode) {
Integer opCode) {
if (!statisticsEnabled) if (!statisticsEnabled)
return; return;
@ -120,11 +118,10 @@ public abstract class MedtronicHistoryDecoder<T extends MedtronicHistoryEntry> i
StringUtil.appendToStringBuilder(sb, "" + unknownEntry.getKey(), ", "); StringUtil.appendToStringBuilder(sb, "" + unknownEntry.getKey(), ", ");
} }
if (isLogEnabled()) aapsLogger.error(LTag.PUMPCOMM, "STATISTICS OF PUMP DECODE");
LOG.debug("STATISTICS OF PUMP DECODE");
if (unknownOpCodes.size() > 0) { if (unknownOpCodes.size() > 0) {
LOG.warn("Unknown Op Codes: {}", sb.toString()); aapsLogger.warn(LTag.PUMPCOMM, "Unknown Op Codes: {}", sb.toString());
} }
for (Map.Entry<RecordDecodeStatus, Map<String, String>> entry : mapStatistics.entrySet()) { for (Map.Entry<RecordDecodeStatus, Map<String, String>> entry : mapStatistics.entrySet()) {
@ -140,12 +137,9 @@ public abstract class MedtronicHistoryDecoder<T extends MedtronicHistoryEntry> i
String spaces = StringUtils.repeat(" ", 14 - entry.getKey().name().length()); String spaces = StringUtils.repeat(" ", 14 - entry.getKey().name().length());
if (isLogEnabled()) aapsLogger.error(LTag.PUMPCOMM, " {}{} - {}. Elements: {}", entry.getKey().name(), spaces, entry.getValue().size(), sb.toString());
LOG.debug(" {}{} - {}. Elements: {}", entry.getKey().name(), spaces, entry.getValue().size(),
sb.toString());
} else { } else {
if (isLogEnabled()) aapsLogger.error(LTag.PUMPCOMM, " {} - {}", entry.getKey().name(), entry.getValue().size());
LOG.debug(" {} - {}", entry.getKey().name(), entry.getValue().size());
} }
} }
} }
@ -184,9 +178,4 @@ public abstract class MedtronicHistoryDecoder<T extends MedtronicHistoryEntry> i
return records; return records;
} }
protected boolean isLogEnabled() {
return L.isEnabled(L.PUMPCOMM);
}
} }

View file

@ -2,11 +2,8 @@ package info.nightscout.androidaps.plugins.pump.medtronic.comm.history;
import java.util.Arrays; import java.util.Arrays;
import org.slf4j.Logger; import info.nightscout.androidaps.logging.AAPSLogger;
import org.slf4j.LoggerFactory; import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
import info.nightscout.androidaps.plugins.pump.common.utils.CRC; import info.nightscout.androidaps.plugins.pump.common.utils.CRC;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil; import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
@ -16,12 +13,13 @@ import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
*/ */
public class RawHistoryPage { public class RawHistoryPage {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPBTCOMM); private final AAPSLogger aapsLogger;
private byte[] data = new byte[0]; private byte[] data = new byte[0];
public RawHistoryPage() { public RawHistoryPage(AAPSLogger aapsLogger) {
this.aapsLogger = aapsLogger;
} }
@ -35,7 +33,7 @@ public class RawHistoryPage {
} }
public byte[] getOnlyData() { byte[] getOnlyData() {
return Arrays.copyOfRange(data, 0, 1022); return Arrays.copyOfRange(data, 0, 1022);
} }
@ -55,11 +53,11 @@ public class RawHistoryPage {
int crcStored = ByteUtil.toInt(data[1022], data[1023]); int crcStored = ByteUtil.toInt(data[1022], data[1023]);
if (crcCalculated != crcStored) { if (crcCalculated != crcStored) {
LOG.error("Stored CRC ({}) is different than calculated ({}), but ignored for now.", crcStored, aapsLogger.error(LTag.PUMPBTCOMM, "Stored CRC ({}) is different than calculated ({}), but ignored for now.", crcStored,
crcCalculated); crcCalculated);
} else { } else {
if (MedtronicUtil.isLowLevelDebug()) if (MedtronicUtil.isLowLevelDebug())
LOG.debug("CRC ok."); aapsLogger.debug(LTag.PUMPBTCOMM, "CRC ok.");
} }
return crcCalculated == crcStored; return crcCalculated == crcStored;
@ -70,7 +68,7 @@ public class RawHistoryPage {
int linesize = 80; int linesize = 80;
int offset = 0; int offset = 0;
StringBuffer sb = new StringBuffer(); StringBuilder sb = new StringBuilder();
while (offset < data.length) { while (offset < data.length) {
int bytesToLog = linesize; int bytesToLog = linesize;
@ -83,7 +81,6 @@ public class RawHistoryPage {
offset += linesize; offset += linesize;
} }
LOG.debug("History Page Data:\n{}", sb.toString()); aapsLogger.debug(LTag.PUMPBTCOMM, "History Page Data:\n{}", sb.toString());
} }
} }

View file

@ -17,7 +17,7 @@ import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.RecordDeco
/** /**
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes * This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
* management and modified/extended for AAPS. * management and modified/extended for AAPS.
* * <p>
* Author: Andy {andy.rozman@gmail.com} * Author: Andy {andy.rozman@gmail.com}
*/ */
@ -209,8 +209,7 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder<CGMSHis
entry.setDateTime(dateTime, getIndex); entry.setDateTime(dateTime, getIndex);
} }
if (isLogEnabled()) LOG.debug("Record: {}", entry);
LOG.debug("Record: {}", entry);
} }
return reversedOutList; return reversedOutList;

View file

@ -1,16 +1,14 @@
package info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump; package info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump;
import android.util.Log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import info.nightscout.androidaps.logging.L; import javax.inject.Inject;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; import javax.inject.Singleton;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil; import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.MedtronicHistoryDecoder; import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.MedtronicHistoryDecoder;
@ -27,21 +25,26 @@ import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
/** /**
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes * This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
* management and modified/extended for AAPS. * management and modified/extended for AAPS.
* * <p>
* Author: Andy {andy.rozman@gmail.com} * Author: Andy {andy.rozman@gmail.com}
*/ */
@Singleton
public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHistoryEntry> { public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHistoryEntry> {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPCOMM); private final AAPSLogger aapsLogger;
private final MedtronicUtil medtronicUtil;
private PumpHistoryEntry tbrPreviousRecord; private PumpHistoryEntry tbrPreviousRecord;
private PumpHistoryEntry changeTimeRecord; private PumpHistoryEntry changeTimeRecord;
private MedtronicDeviceType deviceType;
private static final String TAG = "MdtPumpHistoryDecoder";
@Inject
public MedtronicPumpHistoryDecoder() { public MedtronicPumpHistoryDecoder(
AAPSLogger aapsLogger,
MedtronicUtil medtronicUtil
) {
this.aapsLogger = aapsLogger;
this.medtronicUtil = medtronicUtil;
} }
@ -50,15 +53,13 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
int counter = 0; int counter = 0;
int record = 0; int record = 0;
boolean incompletePacket = false; boolean incompletePacket;
deviceType = MedtronicUtil.getMedtronicPumpModel();
List<PumpHistoryEntry> outList = new ArrayList<PumpHistoryEntry>(); List<PumpHistoryEntry> outList = new ArrayList<>();
String skipped = null; String skipped = null;
int elementStart = 0;
if (dataClear.size() == 0) { if (dataClear.size() == 0) {
Log.e(TAG, "Empty page."); aapsLogger.error(LTag.PUMPBTCOMM, "Empty page.");
return outList; return outList;
} }
@ -76,7 +77,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
continue; continue;
} else { } else {
if (skipped != null) { if (skipped != null) {
Log.w(TAG, " ... Skipped " + skipped); aapsLogger.warn(LTag.PUMPBTCOMM, " ... Skipped " + skipped);
skipped = null; skipped = null;
} }
} }
@ -84,7 +85,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
PumpHistoryEntryType entryType = PumpHistoryEntryType.getByCode(opCode); PumpHistoryEntryType entryType = PumpHistoryEntryType.getByCode(opCode);
PumpHistoryEntry pe = new PumpHistoryEntry(); PumpHistoryEntry pe = new PumpHistoryEntry();
pe.setEntryType(entryType); pe.setEntryType(medtronicUtil.getMedtronicPumpModel(), entryType);
pe.setOffset(counter); pe.setOffset(counter);
counter++; counter++;
@ -93,11 +94,11 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
break; break;
} }
List<Byte> listRawData = new ArrayList<Byte>(); List<Byte> listRawData = new ArrayList<>();
listRawData.add((byte) opCode); listRawData.add((byte) opCode);
if (entryType == PumpHistoryEntryType.UnabsorbedInsulin if (entryType == PumpHistoryEntryType.UnabsorbedInsulin
|| entryType == PumpHistoryEntryType.UnabsorbedInsulin512) { || entryType == PumpHistoryEntryType.UnabsorbedInsulin512) {
int elements = dataClear.get(counter); int elements = dataClear.get(counter);
listRawData.add((byte) elements); listRawData.add((byte) elements);
counter++; counter++;
@ -105,20 +106,20 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
int els = getUnsignedInt(elements); int els = getUnsignedInt(elements);
for (int k = 0; k < (els - 2); k++) { for (int k = 0; k < (els - 2); k++) {
listRawData.add((byte) dataClear.get(counter)); listRawData.add(dataClear.get(counter));
counter++; counter++;
} }
special = true; special = true;
} else { } else {
for (int j = 0; j < (entryType.getTotalLength() - 1); j++) { for (int j = 0; j < (entryType.getTotalLength(medtronicUtil.getMedtronicPumpModel()) - 1); j++) {
try { try {
listRawData.add(dataClear.get(counter)); listRawData.add(dataClear.get(counter));
counter++; counter++;
} catch (Exception ex) { } catch (Exception ex) {
LOG.error("OpCode: " + ByteUtil.shortHexString((byte) opCode) + ", Invalid package: " aapsLogger.error(LTag.PUMPBTCOMM, "OpCode: " + ByteUtil.shortHexString((byte) opCode) + ", Invalid package: "
+ ByteUtil.getHex(listRawData)); + ByteUtil.getHex(listRawData));
// throw ex; // throw ex;
incompletePacket = true; incompletePacket = true;
@ -133,14 +134,14 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
} }
if (entryType == PumpHistoryEntryType.None) { if (entryType == PumpHistoryEntryType.None) {
LOG.error("Error in code. We should have not come into this branch."); aapsLogger.error(LTag.PUMPBTCOMM, "Error in code. We should have not come into this branch.");
} else { } else {
if (pe.getEntryType() == PumpHistoryEntryType.UnknownBasePacket) { if (pe.getEntryType() == PumpHistoryEntryType.UnknownBasePacket) {
pe.setOpCode(opCode); pe.setOpCode(opCode);
} }
if (entryType.getHeadLength() == 0) if (entryType.getHeadLength(medtronicUtil.getMedtronicPumpModel()) == 0)
special = true; special = true;
pe.setData(listRawData, special); pe.setData(listRawData, special);
@ -150,7 +151,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
if ((decoded == RecordDecodeStatus.OK) || (decoded == RecordDecodeStatus.Ignored)) { if ((decoded == RecordDecodeStatus.OK) || (decoded == RecordDecodeStatus.Ignored)) {
//Log.i(TAG, "#" + record + " " + decoded.getDescription() + " " + pe); //Log.i(TAG, "#" + record + " " + decoded.getDescription() + " " + pe);
} else { } else {
Log.w(TAG, "#" + record + " " + decoded.getDescription() + " " + pe); aapsLogger.warn(LTag.PUMPBTCOMM, "#" + record + " " + decoded.getDescription() + " " + pe);
} }
addToStatistics(pe, decoded, null); addToStatistics(pe, decoded, null);
@ -173,13 +174,13 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
try { try {
return decodeRecord(record, false); return decodeRecord(record, false);
} catch (Exception ex) { } catch (Exception ex) {
LOG.error(" Error decoding: type={}, ex={}", record.getEntryType().name(), ex.getMessage(), ex); aapsLogger.error(LTag.PUMPBTCOMM, " Error decoding: type={}, ex={}", record.getEntryType().name(), ex.getMessage(), ex);
return RecordDecodeStatus.Error; return RecordDecodeStatus.Error;
} }
} }
public RecordDecodeStatus decodeRecord(PumpHistoryEntry entry, boolean x) { private RecordDecodeStatus decodeRecord(PumpHistoryEntry entry, boolean x) {
if (entry.getDateTimeLength() > 0) { if (entry.getDateTimeLength() > 0) {
decodeDateTime(entry); decodeDateTime(entry);
@ -260,7 +261,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
case EventUnknown_0x4d: case EventUnknown_0x4d:
case EventUnknown_MM522_0x25: case EventUnknown_MM522_0x25:
case EventUnknown_MM522_0x05: case EventUnknown_MM522_0x05:
LOG.debug(" -- ignored Unknown Pump Entry: " + entry); aapsLogger.debug(LTag.PUMPBTCOMM, " -- ignored Unknown Pump Entry: " + entry);
return RecordDecodeStatus.Ignored; return RecordDecodeStatus.Ignored;
case UnabsorbedInsulin: case UnabsorbedInsulin:
@ -340,7 +341,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
return RecordDecodeStatus.Error; return RecordDecodeStatus.Error;
default: { default: {
LOG.debug("Not supported: " + entry.getEntryType()); aapsLogger.debug(LTag.PUMPBTCOMM, "Not supported: " + entry.getEntryType());
return RecordDecodeStatus.NotSupported; return RecordDecodeStatus.NotSupported;
} }
@ -367,7 +368,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
// LOG.debug("decodeBasalProfile: {}", entry); // LOG.debug("decodeBasalProfile: {}", entry);
BasalProfile basalProfile = new BasalProfile(); BasalProfile basalProfile = new BasalProfile(aapsLogger);
basalProfile.setRawDataFromHistory(entry.getBody()); basalProfile.setRawDataFromHistory(entry.getBody());
// LOG.debug("decodeBasalProfile BasalProfile: {}", basalProfile); // LOG.debug("decodeBasalProfile BasalProfile: {}", basalProfile);
@ -396,7 +397,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
} }
public static String getFormattedValue(float value, int decimals) { private static String getFormattedValue(float value, int decimals) {
return String.format(Locale.ENGLISH, "%." + decimals + "f", value); return String.format(Locale.ENGLISH, "%." + decimals + "f", value);
} }
@ -408,16 +409,14 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
Float rate = null; Float rate = null;
int index = entry.getHead()[0]; int index = entry.getHead()[0];
if (MedtronicDeviceType.isSameDevice(MedtronicUtil.getMedtronicPumpModel(), if (MedtronicDeviceType.isSameDevice(medtronicUtil.getMedtronicPumpModel(), MedtronicDeviceType.Medtronic_523andHigher)) {
MedtronicDeviceType.Medtronic_523andHigher)) {
rate = body[1] * 0.025f; rate = body[1] * 0.025f;
} }
//LOG.info("Basal Profile Start: offset={}, rate={}, index={}, body_raw={}", offset, rate, index, body); //LOG.info("Basal Profile Start: offset={}, rate={}, index={}, body_raw={}", offset, rate, index, body);
if (rate == null) { if (rate == null) {
LOG.warn("Basal Profile Start (ERROR): offset={}, rate={}, index={}, body_raw={}", offset, rate, index, aapsLogger.warn(LTag.PUMPBTCOMM, "Basal Profile Start (ERROR): offset={}, rate={}, index={}, body_raw={}", offset, rate, index, body);
body);
return RecordDecodeStatus.Error; return RecordDecodeStatus.Error;
} else { } else {
entry.addDecodedData("Value", getFormattedFloat(rate, 3)); entry.addDecodedData("Value", getFormattedFloat(rate, 3));
@ -435,8 +434,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
float bolusStrokes = 10.0f; float bolusStrokes = 10.0f;
if (MedtronicDeviceType.isSameDevice(MedtronicUtil.getMedtronicPumpModel(), if (MedtronicDeviceType.isSameDevice(medtronicUtil.getMedtronicPumpModel(), MedtronicDeviceType.Medtronic_523andHigher)) {
MedtronicDeviceType.Medtronic_523andHigher)) {
// https://github.com/ps2/minimed_rf/blob/master/lib/minimed_rf/log_entries/bolus_wizard.rb#L102 // https://github.com/ps2/minimed_rf/blob/master/lib/minimed_rf/log_entries/bolus_wizard.rb#L102
bolusStrokes = 40.0f; bolusStrokes = 40.0f;
@ -447,19 +445,19 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
// carb_ratio (?) = (((self.body[2] & 0x07) << 8) + self.body[3]) / // carb_ratio (?) = (((self.body[2] & 0x07) << 8) + self.body[3]) /
// 10.0s // 10.0s
dto.insulinSensitivity = new Float(body[4]); dto.insulinSensitivity = new Float(body[4]);
dto.bgTargetLow = (int)body[5]; dto.bgTargetLow = (int) body[5];
dto.bgTargetHigh = (int)body[14]; dto.bgTargetHigh = (int) body[14];
dto.correctionEstimate = (((body[9] & 0x38) << 5) + body[6]) / bolusStrokes; dto.correctionEstimate = (((body[9] & 0x38) << 5) + body[6]) / bolusStrokes;
dto.foodEstimate = ((body[7] << 8) + body[8]) / bolusStrokes; dto.foodEstimate = ((body[7] << 8) + body[8]) / bolusStrokes;
dto.unabsorbedInsulin = ((body[10] << 8) + body[11]) / bolusStrokes; dto.unabsorbedInsulin = ((body[10] << 8) + body[11]) / bolusStrokes;
dto.bolusTotal = ((body[12] << 8) + body[13]) / bolusStrokes; dto.bolusTotal = ((body[12] << 8) + body[13]) / bolusStrokes;
} else { } else {
dto.bloodGlucose = (((body[1] & 0x0F) << 8) | entry.getHead()[0]); dto.bloodGlucose = (((body[1] & 0x0F) << 8) | entry.getHead()[0]);
dto.carbs = (int)body[0]; dto.carbs = (int) body[0];
dto.carbRatio = Float.valueOf(body[2]); dto.carbRatio = Float.valueOf(body[2]);
dto.insulinSensitivity = new Float(body[3]); dto.insulinSensitivity = new Float(body[3]);
dto.bgTargetLow = (int)body[4]; dto.bgTargetLow = (int) body[4];
dto.bgTargetHigh = (int)body[12]; dto.bgTargetHigh = (int) body[12];
dto.bolusTotal = body[11] / bolusStrokes; dto.bolusTotal = body[11] / bolusStrokes;
dto.foodEstimate = body[6] / bolusStrokes; dto.foodEstimate = body[6] / bolusStrokes;
dto.unabsorbedInsulin = body[9] / bolusStrokes; dto.unabsorbedInsulin = body[9] / bolusStrokes;
@ -490,7 +488,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
dto.carbs = (body[1] & 0xC) << 6 | body[0]; // (int)body[0]; dto.carbs = (body[1] & 0xC) << 6 | body[0]; // (int)body[0];
dto.carbRatio = Float.valueOf(body[2]); dto.carbRatio = Float.valueOf(body[2]);
dto.insulinSensitivity = new Float(body[3]); dto.insulinSensitivity = new Float(body[3]);
dto.bgTargetLow = (int)body[4]; dto.bgTargetLow = (int) body[4];
dto.foodEstimate = body[6] / 10.0f; dto.foodEstimate = body[6] / 10.0f;
dto.correctionEstimate = (body[7] + (body[5] & 0x0F)) / bolusStrokes; dto.correctionEstimate = (body[7] + (body[5] & 0x0F)) / bolusStrokes;
dto.unabsorbedInsulin = body[9] / bolusStrokes; dto.unabsorbedInsulin = body[9] / bolusStrokes;
@ -570,8 +568,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
byte[] data = entry.getHead(); byte[] data = entry.getHead();
if (MedtronicDeviceType.isSameDevice(MedtronicUtil.getMedtronicPumpModel(), if (MedtronicDeviceType.isSameDevice(medtronicUtil.getMedtronicPumpModel(), MedtronicDeviceType.Medtronic_523andHigher)) {
MedtronicDeviceType.Medtronic_523andHigher)) {
bolus.setRequestedAmount(ByteUtil.toInt(data[0], data[1]) / 40.0d); bolus.setRequestedAmount(ByteUtil.toInt(data[0], data[1]) / 40.0d);
bolus.setDeliveredAmount(ByteUtil.toInt(data[2], data[3]) / 40.0d); bolus.setDeliveredAmount(ByteUtil.toInt(data[2], data[3]) / 40.0d);
bolus.setInsulinOnBoard(ByteUtil.toInt(data[4], data[5]) / 40.0d); bolus.setInsulinOnBoard(ByteUtil.toInt(data[4], data[5]) / 40.0d);
@ -606,7 +603,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
} }
public static void decodeTempBasal(PumpHistoryEntry tbrPreviousRecord, PumpHistoryEntry entry) { public void decodeTempBasal(PumpHistoryEntry tbrPreviousRecord, PumpHistoryEntry entry) {
PumpHistoryEntry tbrRate = null, tbrDuration = null; PumpHistoryEntry tbrRate = null, tbrDuration = null;
@ -639,7 +636,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
byte[] dt = entry.getDatetime(); byte[] dt = entry.getDatetime();
if (dt == null) { if (dt == null) {
LOG.warn("DateTime not set."); aapsLogger.warn(LTag.PUMPBTCOMM, "DateTime not set.");
} }
if (entry.getDateTimeLength() == 5) { if (entry.getDateTimeLength() == 5) {
@ -673,7 +670,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
//LOG.debug("DT: {} {} {}", year, month, dayOfMonth); //LOG.debug("DT: {} {} {}", year, month, dayOfMonth);
if (dayOfMonth == 32) { if (dayOfMonth == 32) {
LOG.warn("Entry: Day 32 {} = [{}] {}", entry.getEntryType().name(), aapsLogger.warn(LTag.PUMPBTCOMM, "Entry: Day 32 {} = [{}] {}", entry.getEntryType().name(),
ByteUtil.getHex(entry.getRawData()), entry); ByteUtil.getHex(entry.getRawData()), entry);
} }
@ -686,7 +683,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
entry.setAtechDateTime(DateTimeUtil.toATechDate(year, month, dayOfMonth, hour, minutes, seconds)); entry.setAtechDateTime(DateTimeUtil.toATechDate(year, month, dayOfMonth, hour, minutes, seconds));
} else { } else {
LOG.warn("Unknown datetime format: " + entry.getDateTimeLength()); aapsLogger.warn(LTag.PUMPBTCOMM, "Unknown datetime format: " + entry.getDateTimeLength());
} }
} }

View file

@ -2,15 +2,12 @@ package info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump;
import com.google.gson.annotations.Expose; import com.google.gson.annotations.Expose;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Objects; import java.util.Objects;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil; import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil;
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.MedtronicHistoryEntry; import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.MedtronicHistoryEntry;
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType;
/** /**
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes * This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
@ -21,8 +18,6 @@ import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.MedtronicH
public class PumpHistoryEntry extends MedtronicHistoryEntry { public class PumpHistoryEntry extends MedtronicHistoryEntry {
private static Logger LOG = StacktraceLoggerWrapper.getLogger(PumpHistoryEntry.class);
@Expose @Expose
private PumpHistoryEntryType entryType; private PumpHistoryEntryType entryType;
private Integer opCode; // this is set only when we have unknown entry... private Integer opCode; // this is set only when we have unknown entry...
@ -35,12 +30,12 @@ public class PumpHistoryEntry extends MedtronicHistoryEntry {
} }
public void setEntryType(PumpHistoryEntryType entryType) { public void setEntryType(MedtronicDeviceType medtronicDeviceType, PumpHistoryEntryType entryType) {
this.entryType = entryType; this.entryType = entryType;
this.sizes[0] = entryType.getHeadLength(); this.sizes[0] = entryType.getHeadLength(medtronicDeviceType);
this.sizes[1] = entryType.getDateLength(); this.sizes[1] = entryType.getDateLength();
this.sizes[2] = entryType.getBodyLength(); this.sizes[2] = entryType.getBodyLength(medtronicDeviceType);
if (this.entryType != null && this.atechDateTime != null) if (this.entryType != null && this.atechDateTime != null)
setPumpId(); setPumpId();

View file

@ -5,13 +5,13 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpHistoryEntryGroup;
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType; import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
/** /**
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes * This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
* management and modified/extended for AAPS. * management and modified/extended for AAPS.
* * <p>
* Author: Andy {andy.rozman@gmail.com} * Author: Andy {andy.rozman@gmail.com}
*/ */
@ -158,8 +158,7 @@ public enum PumpHistoryEntryType // implements CodeEnum
TempBasalCombined(0xfe, "TBR", PumpHistoryEntryGroup.Basal), // TempBasalCombined(0xfe, "TBR", PumpHistoryEntryGroup.Basal), //
UnknownBasePacket(0xff, "Unknown Base Packet", PumpHistoryEntryGroup.Unknown); UnknownBasePacket(0xff, "Unknown Base Packet", PumpHistoryEntryGroup.Unknown);
private static Map<Integer, PumpHistoryEntryType> opCodeMap = new HashMap<Integer, PumpHistoryEntryType>(); private static Map<Integer, PumpHistoryEntryType> opCodeMap = new HashMap<>();
private static PumpHistoryEntryType tddType;
static { static {
for (PumpHistoryEntryType type : values()) { for (PumpHistoryEntryType type : values()) {
@ -171,7 +170,7 @@ public enum PumpHistoryEntryType // implements CodeEnum
private int opCode; private int opCode;
private String description; private String description;
private int headLength = 0; private int headLength;
private int dateLength; private int dateLength;
// private MinimedDeviceType deviceType; // private MinimedDeviceType deviceType;
private int bodyLength; private int bodyLength;
@ -181,8 +180,7 @@ public enum PumpHistoryEntryType // implements CodeEnum
private List<SpecialRule> specialRulesHead; private List<SpecialRule> specialRulesHead;
private List<SpecialRule> specialRulesBody; private List<SpecialRule> specialRulesBody;
private boolean hasSpecialRules = false; private boolean hasSpecialRules = false;
private PumpHistoryEntryGroup group = PumpHistoryEntryGroup.Unknown; private PumpHistoryEntryGroup group;
private static Object TDDType;
PumpHistoryEntryType(int opCode, String name, PumpHistoryEntryGroup group) { PumpHistoryEntryType(int opCode, String name, PumpHistoryEntryGroup group) {
@ -288,9 +286,9 @@ public enum PumpHistoryEntryType // implements CodeEnum
} }
public int getTotalLength() { public int getTotalLength(MedtronicDeviceType medtronicDeviceType) {
if (hasSpecialRules()) { if (hasSpecialRules()) {
return getHeadLength() + getBodyLength() + getDateLength(); return getHeadLength(medtronicDeviceType) + getBodyLength(medtronicDeviceType) + getDateLength();
} else { } else {
return totalLength; return totalLength;
} }
@ -304,7 +302,7 @@ public enum PumpHistoryEntryType // implements CodeEnum
void addSpecialRuleHead(SpecialRule rule) { void addSpecialRuleHead(SpecialRule rule) {
if (isEmpty(specialRulesHead)) { if (isEmpty(specialRulesHead)) {
specialRulesHead = new ArrayList<SpecialRule>(); specialRulesHead = new ArrayList<>();
} }
specialRulesHead.add(rule); specialRulesHead.add(rule);
@ -314,7 +312,7 @@ public enum PumpHistoryEntryType // implements CodeEnum
void addSpecialRuleBody(SpecialRule rule) { void addSpecialRuleBody(SpecialRule rule) {
if (isEmpty(specialRulesBody)) { if (isEmpty(specialRulesBody)) {
specialRulesBody = new ArrayList<SpecialRule>(); specialRulesBody = new ArrayList<>();
} }
specialRulesBody.add(rule); specialRulesBody.add(rule);
@ -332,10 +330,10 @@ public enum PumpHistoryEntryType // implements CodeEnum
} }
public int getHeadLength() { public int getHeadLength(MedtronicDeviceType medtronicDeviceType) {
if (hasSpecialRules) { if (hasSpecialRules) {
if (isNotEmpty(specialRulesHead)) { if (isNotEmpty(specialRulesHead)) {
return determineSizeByRule(headLength, specialRulesHead); return determineSizeByRule(medtronicDeviceType, headLength, specialRulesHead);
} else { } else {
return headLength; return headLength;
} }
@ -350,10 +348,10 @@ public enum PumpHistoryEntryType // implements CodeEnum
} }
public int getBodyLength() { public int getBodyLength(MedtronicDeviceType medtronicDeviceType) {
if (hasSpecialRules) { if (hasSpecialRules) {
if (isNotEmpty(specialRulesBody)) { if (isNotEmpty(specialRulesBody)) {
return determineSizeByRule(bodyLength, specialRulesBody); return determineSizeByRule(medtronicDeviceType, bodyLength, specialRulesBody);
} else { } else {
return bodyLength; return bodyLength;
} }
@ -375,11 +373,11 @@ public enum PumpHistoryEntryType // implements CodeEnum
// byte[] dh = { 2, 3 }; // byte[] dh = { 2, 3 };
private int determineSizeByRule(int defaultValue, List<SpecialRule> rules) { private int determineSizeByRule(MedtronicDeviceType medtronicDeviceType, int defaultValue, List<SpecialRule> rules) {
int size = defaultValue; int size = defaultValue;
for (SpecialRule rule : rules) { for (SpecialRule rule : rules) {
if (MedtronicDeviceType.isSameDevice(MedtronicUtil.getMedtronicPumpModel(), rule.deviceType)) { if (MedtronicDeviceType.isSameDevice(medtronicDeviceType, rule.deviceType)) {
size = rule.size; size = rule.size;
break; break;
} }
@ -394,36 +392,13 @@ public enum PumpHistoryEntryType // implements CodeEnum
return group; return group;
} }
enum DateFormat {
None(0), //
LongDate(5), //
ShortDate(2);
private int length;
DateFormat(int length) {
this.length = length;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
}
public static class SpecialRule { public static class SpecialRule {
MedtronicDeviceType deviceType; MedtronicDeviceType deviceType;
int size; int size;
public SpecialRule(MedtronicDeviceType deviceType, int size) { SpecialRule(MedtronicDeviceType deviceType, int size) {
this.deviceType = deviceType; this.deviceType = deviceType;
this.size = size; this.size = size;
} }

View file

@ -1,24 +1,21 @@
package info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump; package info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil; import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
/** /**
* History page contains data, sorted from newest to oldest (0=newest..n=oldest) * History page contains data, sorted from newest to oldest (0=newest..n=oldest)
* * <p>
* Created by andy on 9/23/18. * Created by andy on 9/23/18.
*/ */
public class PumpHistoryResult { public class PumpHistoryResult {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPCOMM); private final AAPSLogger aapsLogger;
private boolean searchFinished = false; private boolean searchFinished = false;
private PumpHistoryEntry searchEntry = null; private PumpHistoryEntry searchEntry = null;
@ -28,23 +25,22 @@ public class PumpHistoryResult {
public List<PumpHistoryEntry> validEntries; public List<PumpHistoryEntry> validEntries;
public PumpHistoryResult(PumpHistoryEntry searchEntry, Long targetDate) { public PumpHistoryResult(AAPSLogger aapsLogger, PumpHistoryEntry searchEntry, Long targetDate) {
this.aapsLogger = aapsLogger;
if (searchEntry != null) { if (searchEntry != null) {
/* /*
* this.searchEntry = searchEntry; * this.searchEntry = searchEntry;
* this.searchType = SearchType.LastEntry; * this.searchType = SearchType.LastEntry;
* LOG.debug("PumpHistoryResult. Search parameters: Last Entry: " + searchEntry.atechDateTime + " type=" * aapsLogger.debug(LTag.PUMPCOMM,"PumpHistoryResult. Search parameters: Last Entry: " + searchEntry.atechDateTime + " type="
* + searchEntry.getEntryType().name()); * + searchEntry.getEntryType().name());
*/ */
this.searchDate = searchEntry.atechDateTime; this.searchDate = searchEntry.atechDateTime;
this.searchType = SearchType.Date; this.searchType = SearchType.Date;
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "PumpHistoryResult. Search parameters: Date(with searchEntry): " + targetDate);
LOG.debug("PumpHistoryResult. Search parameters: Date(with searchEntry): " + targetDate);
} else if (targetDate != null) { } else if (targetDate != null) {
this.searchDate = targetDate; this.searchDate = targetDate;
this.searchType = SearchType.Date; this.searchType = SearchType.Date;
if (isLogEnabled()) aapsLogger.debug(LTag.PUMPCOMM, "PumpHistoryResult. Search parameters: Date: " + targetDate);
LOG.debug("PumpHistoryResult. Search parameters: Date: " + targetDate);
} }
// this.unprocessedEntries = new ArrayList<>(); // this.unprocessedEntries = new ArrayList<>();
@ -54,7 +50,7 @@ public class PumpHistoryResult {
public void addHistoryEntries(List<PumpHistoryEntry> entries, int page) { public void addHistoryEntries(List<PumpHistoryEntry> entries, int page) {
this.unprocessedEntries = entries; this.unprocessedEntries = entries;
//LOG.debug("PumpHistoryResult. Unprocessed entries: {}", MedtronicUtil.getGsonInstance().toJson(entries)); //aapsLogger.debug(LTag.PUMPCOMM,"PumpHistoryResult. Unprocessed entries: {}", MedtronicUtil.getGsonInstance().toJson(entries));
processEntries(); processEntries();
} }
@ -66,47 +62,47 @@ public class PumpHistoryResult {
switch (searchType) { switch (searchType) {
case None: case None:
//LOG.debug("PE. None search"); //aapsLogger.debug(LTag.PUMPCOMM,"PE. None search");
this.validEntries.addAll(this.unprocessedEntries); this.validEntries.addAll(this.unprocessedEntries);
break; break;
case LastEntry: { case LastEntry: {
LOG.debug("PE. Last entry search"); aapsLogger.debug(LTag.PUMPCOMM, "PE. Last entry search");
//Collections.sort(this.unprocessedEntries, new PumpHistoryEntry.Comparator()); //Collections.sort(this.unprocessedEntries, new PumpHistoryEntry.Comparator());
LOG.debug("PE. PumpHistoryResult. Search entry date: " + searchEntry.atechDateTime); aapsLogger.debug(LTag.PUMPCOMM, "PE. PumpHistoryResult. Search entry date: " + searchEntry.atechDateTime);
Long date = searchEntry.atechDateTime; Long date = searchEntry.atechDateTime;
for (PumpHistoryEntry unprocessedEntry : unprocessedEntries) { for (PumpHistoryEntry unprocessedEntry : unprocessedEntries) {
if (unprocessedEntry.equals(searchEntry)) { if (unprocessedEntry.equals(searchEntry)) {
//LOG.debug("PE. Item found {}.", unprocessedEntry); //aapsLogger.debug(LTag.PUMPCOMM,"PE. Item found {}.", unprocessedEntry);
searchFinished = true; searchFinished = true;
break; break;
} }
//LOG.debug("PE. Entry {} added.", unprocessedEntry); //aapsLogger.debug(LTag.PUMPCOMM,"PE. Entry {} added.", unprocessedEntry);
this.validEntries.add(unprocessedEntry); this.validEntries.add(unprocessedEntry);
} }
} }
break; break;
case Date: { case Date: {
LOG.debug("PE. Date search: Search date: {}", this.searchDate); aapsLogger.debug(LTag.PUMPCOMM, "PE. Date search: Search date: {}", this.searchDate);
for (PumpHistoryEntry unprocessedEntry : unprocessedEntries) { for (PumpHistoryEntry unprocessedEntry : unprocessedEntries) {
if (unprocessedEntry.atechDateTime == null || unprocessedEntry.atechDateTime == 0) { if (unprocessedEntry.atechDateTime == null || unprocessedEntry.atechDateTime == 0) {
LOG.debug("PE. PumpHistoryResult. Search entry date: Entry with no date: {}", unprocessedEntry); aapsLogger.debug(LTag.PUMPCOMM, "PE. PumpHistoryResult. Search entry date: Entry with no date: {}", unprocessedEntry);
continue; continue;
} }
if (unprocessedEntry.isAfter(this.searchDate)) { if (unprocessedEntry.isAfter(this.searchDate)) {
this.validEntries.add(unprocessedEntry); this.validEntries.add(unprocessedEntry);
} else { } else {
// LOG.debug("PE. PumpHistoryResult. Not after.. Unprocessed Entry [year={},entry={}]", // aapsLogger.debug(LTag.PUMPCOMM,"PE. PumpHistoryResult. Not after.. Unprocessed Entry [year={},entry={}]",
// DateTimeUtil.getYear(unprocessedEntry.atechDateTime), unprocessedEntry); // DateTimeUtil.getYear(unprocessedEntry.atechDateTime), unprocessedEntry);
if (DateTimeUtil.getYear(unprocessedEntry.atechDateTime) > 2015) if (DateTimeUtil.getYear(unprocessedEntry.atechDateTime) > 2015)
olderEntries++; olderEntries++;
@ -123,7 +119,7 @@ public class PumpHistoryResult {
} // switch } // switch
//LOG.debug("PE. Valid Entries: {}", validEntries); //aapsLogger.debug(LTag.PUMPCOMM,"PE. Valid Entries: {}", validEntries);
} }
@ -178,11 +174,4 @@ public class PumpHistoryResult {
LastEntry, // LastEntry, //
Date Date
} }
private boolean isLogEnabled() {
return L.isEnabled(L.PUMPCOMM);
}
} }

View file

@ -1,19 +1,15 @@
package info.nightscout.androidaps.plugins.pump.medtronic.comm.message; package info.nightscout.androidaps.plugins.pump.medtronic.comm.message;
import java.util.List;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
/** /**
* Created by geoff on 6/2/16. * Created by geoff on 6/2/16.
*/ */
public class CarelinkLongMessageBody extends MessageBody { public class CarelinkLongMessageBody extends MessageBody {
public static final int LONG_MESSAGE_BODY_LENGTH = 65; private static final int LONG_MESSAGE_BODY_LENGTH = 65;
protected byte[] data; protected byte[] data;
public CarelinkLongMessageBody() { CarelinkLongMessageBody() {
init(new byte[0]); init(new byte[0]);
} }
@ -22,12 +18,6 @@ public class CarelinkLongMessageBody extends MessageBody {
init(payload); init(payload);
} }
public CarelinkLongMessageBody(List<Byte> payload) {
init(MedtronicUtil.createByteArray(payload));
}
@Override @Override
public void init(byte[] rxData) { public void init(byte[] rxData) {

View file

@ -25,7 +25,7 @@ public enum PacketType {
} }
} }
private byte value = 0; private byte value;
PacketType(int value) { PacketType(int value) {

View file

@ -1,10 +1,7 @@
package info.nightscout.androidaps.plugins.pump.medtronic.comm.message; package info.nightscout.androidaps.plugins.pump.medtronic.comm.message;
import org.slf4j.Logger; import info.nightscout.androidaps.logging.AAPSLogger;
import org.slf4j.LoggerFactory; import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RLMessage; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RLMessage;
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType; import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType;
@ -14,9 +11,9 @@ import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandTy
*/ */
public class PumpMessage implements RLMessage { public class PumpMessage implements RLMessage {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPCOMM); private final AAPSLogger aapsLogger;
public PacketType packetType = PacketType.Carelink; private PacketType packetType = PacketType.Carelink;
public byte[] address = new byte[]{0, 0, 0}; public byte[] address = new byte[]{0, 0, 0};
public MedtronicCommandType commandType; public MedtronicCommandType commandType;
public Byte invalidCommandType; public Byte invalidCommandType;
@ -26,18 +23,20 @@ public class PumpMessage implements RLMessage {
public static final int FRAME_DATA_LENGTH = 64; public static final int FRAME_DATA_LENGTH = 64;
public PumpMessage(String error) { public PumpMessage(AAPSLogger aapsLogger, String error) {
this.error = error; this.error = error;
this.aapsLogger = aapsLogger;
} }
public PumpMessage(byte[] rxData) { public PumpMessage(AAPSLogger aapsLogger, byte[] rxData) {
init(rxData); init(rxData);
this.aapsLogger = aapsLogger;
} }
public PumpMessage() { public PumpMessage(AAPSLogger aapsLogger) {
this.aapsLogger = aapsLogger;
} }
@ -67,8 +66,7 @@ public class PumpMessage implements RLMessage {
if (rxData.length > 4) { if (rxData.length > 4) {
this.commandType = MedtronicCommandType.getByCode(rxData[4]); this.commandType = MedtronicCommandType.getByCode(rxData[4]);
if (this.commandType == MedtronicCommandType.InvalidCommand) { if (this.commandType == MedtronicCommandType.InvalidCommand) {
if (isLogEnabled()) aapsLogger.error(LTag.PUMPCOMM, "PumpMessage - Unknown commandType " + rxData[4]);
LOG.error("PumpMessage - Unknown commandType " + rxData[4]);
} }
} }
if (rxData.length > 5) { if (rxData.length > 5) {
@ -80,7 +78,7 @@ public class PumpMessage implements RLMessage {
@Override @Override
public byte[] getTxData() { public byte[] getTxData() {
byte[] rval = ByteUtil.concat(new byte[]{(byte) packetType.getValue()}, address); byte[] rval = ByteUtil.concat(new byte[]{packetType.getValue()}, address);
rval = ByteUtil.concat(rval, commandType.getCommandCode()); rval = ByteUtil.concat(rval, commandType.getCommandCode());
rval = ByteUtil.concat(rval, messageBody.getTxData()); rval = ByteUtil.concat(rval, messageBody.getTxData());
return rval; return rval;
@ -211,10 +209,4 @@ public class PumpMessage implements RLMessage {
return sb.toString(); return sb.toString();
} }
private boolean isLogEnabled() {
return L.isEnabled(L.PUMPCOMM);
}
} }

View file

@ -1,113 +1,58 @@
package info.nightscout.androidaps.plugins.pump.medtronic.comm.ui; package info.nightscout.androidaps.plugins.pump.medtronic.comm.ui;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager; import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager;
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType; import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil; import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
/** /**
* Created by andy on 6/14/18. * Created by andy on 6/14/18.
*/ */
public class MedtronicUIComm { public class MedtronicUIComm {
private final HasAndroidInjector injector;
private final AAPSLogger aapsLogger; private final AAPSLogger aapsLogger;
private final MedtronicUtil medtronicUtil;
MedtronicCommunicationManager mcmInstance = null; private final MedtronicCommunicationManager medtronicCommunicationManager;
MedtronicUIPostprocessor uiPostprocessor; private final MedtronicUIPostprocessor medtronicUIPostprocessor;
public MedtronicUIComm( public MedtronicUIComm(
HasAndroidInjector injector,
AAPSLogger aapsLogger, AAPSLogger aapsLogger,
RxBusWrapper rxBus, MedtronicUtil medtronicUtil,
ResourceHelper resourceHelper MedtronicUIPostprocessor medtronicUIPostprocessor,
MedtronicCommunicationManager medtronicCommunicationManager
) { ) {
this.injector = injector;
this.aapsLogger = aapsLogger; this.aapsLogger = aapsLogger;
this.medtronicUtil = medtronicUtil;
uiPostprocessor = new MedtronicUIPostprocessor(aapsLogger, rxBus, resourceHelper); this.medtronicUIPostprocessor = medtronicUIPostprocessor;
this.medtronicCommunicationManager = medtronicCommunicationManager;
} }
private MedtronicCommunicationManager getCommunicationManager() {
if (mcmInstance == null) {
mcmInstance = MedtronicCommunicationManager.getInstance();
}
return mcmInstance;
}
public synchronized MedtronicUITask executeCommand(MedtronicCommandType commandType, Object... parameters) { public synchronized MedtronicUITask executeCommand(MedtronicCommandType commandType, Object... parameters) {
aapsLogger.warn(LTag.PUMP, "Execute Command: " + commandType.name()); aapsLogger.warn(LTag.PUMP, "Execute Command: " + commandType.name());
MedtronicUITask task = new MedtronicUITask(commandType, parameters); MedtronicUITask task = new MedtronicUITask(injector, commandType, parameters);
MedtronicUtil.setCurrentCommand(commandType); medtronicUtil.setCurrentCommand(commandType);
// new Thread(() -> { task.execute(medtronicCommunicationManager);
// LOG.warn("@@@ Start Thread");
//
// task.execute(getCommunicationManager());
//
// LOG.warn("@@@ End Thread");
// });
task.execute(getCommunicationManager());
// for (int i = 0; i < getMaxWaitTime(commandType); i++) {
// synchronized (task) {
// // try {
// //
// // //task.wait(1000);
// // } catch (InterruptedException e) {
// // LOG.error("executeCommand InterruptedException", e);
// // }
//
//
// SystemClock.sleep(1000);
// }
//
// if (task.isReceived()) {
// break;
// }
// }
if (!task.isReceived()) { if (!task.isReceived()) {
aapsLogger.warn(LTag.PUMP, "Reply not received for " + commandType); aapsLogger.warn(LTag.PUMP, "Reply not received for " + commandType);
} }
task.postProcess(uiPostprocessor); task.postProcess(medtronicUIPostprocessor);
return task; return task;
} }
/**
* We return 25s as waitTime (17 for wakeUp, and addtional 8 for data retrieval) for normal commands and
* 120s for History. Real time for returning data would be arround 5s, but lets be sure.
*
* @param commandType
* @return
*/
private int getMaxWaitTime(MedtronicCommandType commandType) {
if (commandType == MedtronicCommandType.GetHistoryData)
return 120;
else
return 25;
}
public int getInvalidResponsesCount() { public int getInvalidResponsesCount() {
return getCommunicationManager().getNotConnectedCount(); return medtronicCommunicationManager.getNotConnectedCount();
}
public void startTunning() {
RileyLinkUtil.sendBroadcastMessage(RileyLinkConst.IPC.MSG_PUMP_tunePump);
} }
} }

View file

@ -6,9 +6,13 @@ import org.joda.time.Duration;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper; import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin;
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BasalProfile; import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BasalProfile;
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BatteryStatusDTO; import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BatteryStatusDTO;
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.ClockDTO; import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.ClockDTO;
@ -20,34 +24,41 @@ import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpSta
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil; import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.resources.ResourceHelper;
import static info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil.sendNotification;
/** /**
* Created by andy on 6/15/18. * Created by andy on 6/15/18.
*/ */
class MedtronicUIPostprocessor { @Singleton
public class MedtronicUIPostprocessor {
private final AAPSLogger aapsLogger; private final AAPSLogger aapsLogger;
private final RxBusWrapper rxBus; private final RxBusWrapper rxBus;
private final ResourceHelper resourceHelper; private final ResourceHelper resourceHelper;
private final MedtronicUtil medtronicUtil;
private final MedtronicPumpStatus medtronicPumpStatus;
private final MedtronicPumpPlugin medtronicPumpPlugin;
@Inject
private MedtronicPumpStatus pumpStatus; public MedtronicUIPostprocessor(
AAPSLogger aapsLogger,
RxBusWrapper rxBus,
ResourceHelper resourceHelper,
public MedtronicUIPostprocessor(AAPSLogger aapsLogger, RxBusWrapper rxBus, ResourceHelper resourceHelper) { MedtronicUtil medtronicUtil,
MedtronicPumpStatus medtronicPumpStatus,
MedtronicPumpPlugin medtronicPumpPlugin) {
this.aapsLogger = aapsLogger; this.aapsLogger = aapsLogger;
this.rxBus = rxBus; this.rxBus = rxBus;
this.resourceHelper = resourceHelper; this.resourceHelper = resourceHelper;
pumpStatus = MedtronicUtil.getPumpStatus(); this.medtronicUtil = medtronicUtil;
this.medtronicPumpStatus = medtronicPumpStatus;
this.medtronicPumpPlugin = medtronicPumpPlugin;
} }
// this is mostly intended for command that return certain statuses (Remaining Insulin, ...), and // this is mostly intended for command that return certain statuses (Remaining Insulin, ...), and
// where responses won't be directly used // where responses won't be directly used
public void postProcessData(MedtronicUITask uiTask) { void postProcessData(MedtronicUITask uiTask) {
switch (uiTask.commandType) { switch (uiTask.commandType) {
@ -57,7 +68,7 @@ class MedtronicUIPostprocessor {
if (response) { if (response) {
BasalProfile basalProfile = (BasalProfile) uiTask.getParameter(0); BasalProfile basalProfile = (BasalProfile) uiTask.getParameter(0);
pumpStatus.basalsByHour = basalProfile.getProfilesByHour(); medtronicPumpStatus.basalsByHour = basalProfile.getProfilesByHour(medtronicPumpPlugin.getPumpDescription().pumpType);
} }
} }
break; break;
@ -66,11 +77,11 @@ class MedtronicUIPostprocessor {
BasalProfile basalProfile = (BasalProfile) uiTask.returnData; BasalProfile basalProfile = (BasalProfile) uiTask.returnData;
try { try {
Double[] profilesByHour = basalProfile.getProfilesByHour(); Double[] profilesByHour = basalProfile.getProfilesByHour(medtronicPumpPlugin.getPumpDescription().pumpType);
if (profilesByHour != null) { if (profilesByHour != null) {
pumpStatus.basalsByHour = profilesByHour; medtronicPumpStatus.basalsByHour = profilesByHour;
pumpStatus.basalProfileStatus = BasalProfileStatus.ProfileOK; medtronicPumpStatus.basalProfileStatus = BasalProfileStatus.ProfileOK;
} else { } else {
uiTask.responseType = MedtronicUIResponseType.Error; uiTask.responseType = MedtronicUIResponseType.Error;
uiTask.errorDescription = "No profile found."; uiTask.errorDescription = "No profile found.";
@ -85,20 +96,20 @@ class MedtronicUIPostprocessor {
break; break;
case SetBolus: { case SetBolus: {
pumpStatus.lastBolusAmount = uiTask.getDoubleFromParameters(0); medtronicPumpStatus.lastBolusAmount = uiTask.getDoubleFromParameters(0);
pumpStatus.lastBolusTime = new Date(); medtronicPumpStatus.lastBolusTime = new Date();
} }
break; break;
case GetRemainingInsulin: { case GetRemainingInsulin: {
pumpStatus.reservoirRemainingUnits = (Float) uiTask.returnData; medtronicPumpStatus.reservoirRemainingUnits = (Float) uiTask.returnData;
} }
break; break;
case CancelTBR: { case CancelTBR: {
pumpStatus.tempBasalStart = null; medtronicPumpStatus.tempBasalStart = null;
pumpStatus.tempBasalAmount = null; medtronicPumpStatus.tempBasalAmount = null;
pumpStatus.tempBasalLength = null; medtronicPumpStatus.tempBasalLength = null;
} }
break; break;
@ -113,7 +124,7 @@ class MedtronicUIPostprocessor {
aapsLogger.debug(LTag.PUMP, "New time was {} set.", response ? "" : "NOT"); aapsLogger.debug(LTag.PUMP, "New time was {} set.", response ? "" : "NOT");
if (response) { if (response) {
MedtronicUtil.getPumpTime().timeDifference = 0; medtronicUtil.getPumpTime().timeDifference = 0;
} }
} }
break; break;
@ -122,10 +133,10 @@ class MedtronicUIPostprocessor {
case GetBatteryStatus: { case GetBatteryStatus: {
BatteryStatusDTO batteryStatusDTO = (BatteryStatusDTO) uiTask.returnData; BatteryStatusDTO batteryStatusDTO = (BatteryStatusDTO) uiTask.returnData;
pumpStatus.batteryRemaining = batteryStatusDTO.getCalculatedPercent(pumpStatus.batteryType); medtronicPumpStatus.batteryRemaining = batteryStatusDTO.getCalculatedPercent(medtronicPumpStatus.batteryType);
if (batteryStatusDTO.voltage != null) { if (batteryStatusDTO.voltage != null) {
pumpStatus.batteryVoltage = batteryStatusDTO.voltage; medtronicPumpStatus.batteryVoltage = batteryStatusDTO.voltage;
} }
aapsLogger.debug(LTag.PUMP, "BatteryStatus: {}", batteryStatusDTO.toString()); aapsLogger.debug(LTag.PUMP, "BatteryStatus: {}", batteryStatusDTO.toString());
@ -134,9 +145,9 @@ class MedtronicUIPostprocessor {
break; break;
case PumpModel: { case PumpModel: {
if (pumpStatus.medtronicDeviceType != MedtronicUtil.getMedtronicPumpModel()) { if (medtronicPumpStatus.medtronicDeviceType != medtronicUtil.getMedtronicPumpModel()) {
aapsLogger.warn(LTag.PUMP, "Configured pump is different then pump detected !"); aapsLogger.warn(LTag.PUMP, "Configured pump is different then pump detected !");
sendNotification(MedtronicNotificationType.PumpTypeNotSame, resourceHelper, rxBus); medtronicUtil.sendNotification(MedtronicNotificationType.PumpTypeNotSame, resourceHelper, rxBus);
} }
} }
break; break;
@ -166,7 +177,7 @@ class MedtronicUIPostprocessor {
clockDTO.timeDifference = (int) dur.getStandardSeconds(); clockDTO.timeDifference = (int) dur.getStandardSeconds();
MedtronicUtil.setPumpTime(clockDTO); medtronicUtil.setPumpTime(clockDTO);
aapsLogger.debug(LTag.PUMP, "Pump Time: " + clockDTO.localDeviceTime + ", DeviceTime=" + clockDTO.pumpTime + // aapsLogger.debug(LTag.PUMP, "Pump Time: " + clockDTO.localDeviceTime + ", DeviceTime=" + clockDTO.pumpTime + //
", diff: " + dur.getStandardSeconds() + " s"); ", diff: " + dur.getStandardSeconds() + " s");
@ -190,29 +201,23 @@ class MedtronicUIPostprocessor {
Map<String, PumpSettingDTO> settings = (Map<String, PumpSettingDTO>) uiTask.returnData; Map<String, PumpSettingDTO> settings = (Map<String, PumpSettingDTO>) uiTask.returnData;
MedtronicUtil.setSettings(settings); medtronicUtil.setSettings(settings);
PumpSettingDTO checkValue = null; PumpSettingDTO checkValue;
if (pumpStatus == null) { medtronicPumpPlugin.getRileyLinkService().verifyConfiguration();
aapsLogger.debug(LTag.PUMP, "Pump Status: was null");
pumpStatus = MedtronicUtil.getPumpStatus();
aapsLogger.debug(LTag.PUMP, "Pump Status: " + this.pumpStatus);
}
this.pumpStatus.verifyConfiguration();
// check profile // check profile
if (!"Yes".equals(settings.get("PCFG_BASAL_PROFILES_ENABLED").value)) { if (!"Yes".equals(settings.get("PCFG_BASAL_PROFILES_ENABLED").value)) {
aapsLogger.error(LTag.PUMP, "Basal profiles are not enabled on pump."); aapsLogger.error(LTag.PUMP, "Basal profiles are not enabled on pump.");
sendNotification(MedtronicNotificationType.PumpBasalProfilesNotEnabled, resourceHelper, rxBus); medtronicUtil.sendNotification(MedtronicNotificationType.PumpBasalProfilesNotEnabled, resourceHelper, rxBus);
} else { } else {
checkValue = settings.get("PCFG_ACTIVE_BASAL_PROFILE"); checkValue = settings.get("PCFG_ACTIVE_BASAL_PROFILE");
if (!"STD".equals(checkValue.value)) { if (!"STD".equals(checkValue.value)) {
aapsLogger.error("Basal profile set on pump is incorrect (must be STD)."); aapsLogger.error("Basal profile set on pump is incorrect (must be STD).");
sendNotification(MedtronicNotificationType.PumpIncorrectBasalProfileSelected, resourceHelper, rxBus); medtronicUtil.sendNotification(MedtronicNotificationType.PumpIncorrectBasalProfileSelected, resourceHelper, rxBus);
} }
} }
@ -222,23 +227,23 @@ class MedtronicUIPostprocessor {
if (!"Units".equals(checkValue.value)) { if (!"Units".equals(checkValue.value)) {
aapsLogger.error("Wrong TBR type set on pump (must be Absolute)."); aapsLogger.error("Wrong TBR type set on pump (must be Absolute).");
sendNotification(MedtronicNotificationType.PumpWrongTBRTypeSet, resourceHelper, rxBus); medtronicUtil.sendNotification(MedtronicNotificationType.PumpWrongTBRTypeSet, resourceHelper, rxBus);
} }
// MAXes // MAXes
checkValue = settings.get("PCFG_MAX_BOLUS"); checkValue = settings.get("PCFG_MAX_BOLUS");
if (!MedtronicUtil.isSame(Double.parseDouble(checkValue.value), pumpStatus.maxBolus)) { if (!medtronicUtil.isSame(Double.parseDouble(checkValue.value), medtronicPumpStatus.maxBolus)) {
aapsLogger.error("Wrong Max Bolus set on Pump (current={}, required={}).", checkValue.value, pumpStatus.maxBolus); aapsLogger.error("Wrong Max Bolus set on Pump (current={}, required={}).", checkValue.value, medtronicPumpStatus.maxBolus);
sendNotification(MedtronicNotificationType.PumpWrongMaxBolusSet, resourceHelper, rxBus, pumpStatus.maxBolus); medtronicUtil.sendNotification(MedtronicNotificationType.PumpWrongMaxBolusSet, resourceHelper, rxBus, medtronicPumpStatus.maxBolus);
} }
checkValue = settings.get("PCFG_MAX_BASAL"); checkValue = settings.get("PCFG_MAX_BASAL");
if (!MedtronicUtil.isSame(Double.parseDouble(checkValue.value), pumpStatus.maxBasal)) { if (!medtronicUtil.isSame(Double.parseDouble(checkValue.value), medtronicPumpStatus.maxBasal)) {
aapsLogger.error("Wrong Max Basal set on Pump (current={}, required={}).", checkValue.value, pumpStatus.maxBasal); aapsLogger.error("Wrong Max Basal set on Pump (current={}, required={}).", checkValue.value, medtronicPumpStatus.maxBasal);
sendNotification(MedtronicNotificationType.PumpWrongMaxBasalSet, resourceHelper, rxBus, pumpStatus.maxBasal); medtronicUtil.sendNotification(MedtronicNotificationType.PumpWrongMaxBasalSet, resourceHelper, rxBus, medtronicPumpStatus.maxBasal);
} }
} }

View file

@ -1,13 +1,13 @@
package info.nightscout.androidaps.plugins.pump.medtronic.comm.ui; package info.nightscout.androidaps.plugins.pump.medtronic.comm.ui;
import org.joda.time.LocalDateTime; import org.joda.time.LocalDateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp; import javax.inject.Inject;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager; import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager;
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry; import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry;
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BasalProfile; import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BasalProfile;
@ -15,6 +15,7 @@ import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.TempBasalPair;
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType; import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType;
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicUIResponseType; import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicUIResponseType;
import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState; import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState;
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus;
import info.nightscout.androidaps.plugins.pump.medtronic.events.EventMedtronicDeviceStatusChange; import info.nightscout.androidaps.plugins.pump.medtronic.events.EventMedtronicDeviceStatusChange;
import info.nightscout.androidaps.plugins.pump.medtronic.events.EventMedtronicPumpValuesChanged; import info.nightscout.androidaps.plugins.pump.medtronic.events.EventMedtronicPumpValuesChanged;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil; import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
@ -25,7 +26,12 @@ import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
public class MedtronicUITask { public class MedtronicUITask {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMP); @Inject RxBusWrapper rxBus;
@Inject AAPSLogger aapsLogger;
@Inject MedtronicPumpStatus medtronicPumpStatus;
@Inject MedtronicUtil medtronicUtil;
private final HasAndroidInjector injector;
public MedtronicCommandType commandType; public MedtronicCommandType commandType;
public Object returnData; public Object returnData;
@ -36,12 +42,16 @@ public class MedtronicUITask {
MedtronicUIResponseType responseType; MedtronicUIResponseType responseType;
public MedtronicUITask(MedtronicCommandType commandType) { public MedtronicUITask(HasAndroidInjector injector, MedtronicCommandType commandType) {
this.injector = injector;
this.injector.androidInjector().inject(this);
this.commandType = commandType; this.commandType = commandType;
} }
public MedtronicUITask(MedtronicCommandType commandType, Object... parameters) { public MedtronicUITask(HasAndroidInjector injector, MedtronicCommandType commandType, Object... parameters) {
this.injector = injector;
this.injector.androidInjector().inject(this);
this.commandType = commandType; this.commandType = commandType;
this.parameters = parameters; this.parameters = parameters;
} }
@ -49,8 +59,7 @@ public class MedtronicUITask {
public void execute(MedtronicCommunicationManager communicationManager) { public void execute(MedtronicCommunicationManager communicationManager) {
if (isLogEnabled()) aapsLogger.debug(LTag.PUMP, "MedtronicUITask: @@@ In execute. {}", commandType);
LOG.debug("MedtronicUITask: @@@ In execute. {}", commandType);
switch (commandType) { switch (commandType) {
case PumpModel: { case PumpModel: {
@ -70,7 +79,7 @@ public class MedtronicUITask {
case GetRealTimeClock: { case GetRealTimeClock: {
returnData = communicationManager.getPumpTime(); returnData = communicationManager.getPumpTime();
MedtronicUtil.setPumpTime(null); medtronicUtil.setPumpTime(null);
} }
break; break;
@ -132,7 +141,7 @@ public class MedtronicUITask {
break; break;
default: { default: {
LOG.warn("This commandType is not supported (yet) - {}.", commandType); aapsLogger.warn(LTag.PUMP, "This commandType is not supported (yet) - {}.", commandType);
// invalid = true; // invalid = true;
responseType = MedtronicUIResponseType.Invalid; responseType = MedtronicUIResponseType.Invalid;
} }
@ -163,12 +172,12 @@ public class MedtronicUITask {
} }
public Double getDoubleFromParameters(int index) { Double getDoubleFromParameters(int index) {
return (Double) parameters[index]; return (Double) parameters[index];
} }
public Integer getIntegerFromParameters(int index) { private Integer getIntegerFromParameters(int index) {
return (Integer) parameters[index]; return (Integer) parameters[index];
} }
@ -185,25 +194,24 @@ public class MedtronicUITask {
void postProcess(MedtronicUIPostprocessor postprocessor) { void postProcess(MedtronicUIPostprocessor postprocessor) {
if (isLogEnabled()) aapsLogger.debug(LTag.PUMP, "MedtronicUITask: @@@ In execute. {}", commandType);
LOG.debug("MedtronicUITask: @@@ In execute. {}", commandType);
if (responseType == MedtronicUIResponseType.Data) { if (responseType == MedtronicUIResponseType.Data) {
postprocessor.postProcessData(this); postprocessor.postProcessData(this);
} }
if (responseType == MedtronicUIResponseType.Invalid) { if (responseType == MedtronicUIResponseType.Invalid) {
RxBus.Companion.getINSTANCE().send(new EventMedtronicDeviceStatusChange(PumpDeviceState.ErrorWhenCommunicating, rxBus.send(new EventMedtronicDeviceStatusChange(PumpDeviceState.ErrorWhenCommunicating,
"Unsupported command in MedtronicUITask")); "Unsupported command in MedtronicUITask"));
} else if (responseType == MedtronicUIResponseType.Error) { } else if (responseType == MedtronicUIResponseType.Error) {
RxBus.Companion.getINSTANCE().send(new EventMedtronicDeviceStatusChange(PumpDeviceState.ErrorWhenCommunicating, rxBus.send(new EventMedtronicDeviceStatusChange(PumpDeviceState.ErrorWhenCommunicating,
errorDescription)); errorDescription));
} else { } else {
RxBus.Companion.getINSTANCE().send(new EventMedtronicPumpValuesChanged()); rxBus.send(new EventMedtronicPumpValuesChanged());
MedtronicUtil.getPumpStatus().setLastCommunicationToNow(); medtronicPumpStatus.setLastCommunicationToNow();
} }
MedtronicUtil.setCurrentCommand(null); medtronicUtil.setCurrentCommand(null);
} }
@ -212,16 +220,11 @@ public class MedtronicUITask {
} }
public Object getParameter(int index) { Object getParameter(int index) {
return parameters[index]; return parameters[index];
} }
private boolean isLogEnabled() {
return L.isEnabled(L.PUMP);
}
public MedtronicUIResponseType getResponseType() { public MedtronicUIResponseType getResponseType() {
return this.responseType; return this.responseType;
} }

View file

@ -18,10 +18,12 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.db.DbObjectBase; import info.nightscout.androidaps.db.DbObjectBase;
import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.Source;
@ -31,6 +33,7 @@ import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil; import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil; import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil;
@ -67,22 +70,23 @@ import info.nightscout.androidaps.utils.sharedPreferences.SP;
// All things marked with "TODO: Fix db code" needs to be updated in new 2.5 database code // All things marked with "TODO: Fix db code" needs to be updated in new 2.5 database code
@Singleton
public class MedtronicHistoryData { public class MedtronicHistoryData {
private static AAPSLogger aapsLogger; private final AAPSLogger aapsLogger;
private SP sp; private final SP sp;
private ActivePluginProvider activePlugin; private final ActivePluginProvider activePlugin;
private final MedtronicUtil medtronicUtil;
private final MedtronicPumpHistoryDecoder medtronicPumpHistoryDecoder;
private List<PumpHistoryEntry> allHistory = null; private List<PumpHistoryEntry> allHistory;
private List<PumpHistoryEntry> newHistory = null; private List<PumpHistoryEntry> newHistory = null;
private Long lastHistoryRecordTime;
private boolean isInit = false; private boolean isInit = false;
private Gson gson; private Gson gson; // cannot be initialized in constructor because of injection
private Gson gsonCore; private Gson gsonCore; // cannot be initialized in constructor because of injection
private DatabaseHelper databaseHelper = MainApp.getDbHelper();
private ClockDTO pumpTime; private ClockDTO pumpTime;
private long lastIdUsed = 0; private long lastIdUsed = 0;
@ -94,25 +98,32 @@ public class MedtronicHistoryData {
*/ */
public static boolean doubleBolusDebug = false; public static boolean doubleBolusDebug = false;
@Inject
public MedtronicHistoryData(AAPSLogger aapsLogger, SP sp, ActivePluginProvider activePlugin) { public MedtronicHistoryData(
AAPSLogger aapsLogger,
SP sp,
ActivePluginProvider activePlugin,
MedtronicUtil medtronicUtil,
MedtronicPumpHistoryDecoder medtronicPumpHistoryDecoder
) {
this.allHistory = new ArrayList<>(); this.allHistory = new ArrayList<>();
this.gson = MedtronicUtil.gsonInstance;
this.gsonCore = MedtronicUtil.getGsonInstanceCore();
this.aapsLogger = aapsLogger; this.aapsLogger = aapsLogger;
this.sp = sp; this.sp = sp;
this.activePlugin = activePlugin; this.activePlugin = activePlugin;
this.medtronicUtil = medtronicUtil;
if (this.gson == null) { this.medtronicPumpHistoryDecoder = medtronicPumpHistoryDecoder;
this.gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
}
if (this.gsonCore == null) {
this.gsonCore = new GsonBuilder().create();
}
} }
private Gson gson() {
if (gson == null) gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
return gson;
}
private Gson gsonCore() {
if (gsonCore == null) gsonCore = new GsonBuilder().create();
return gsonCore;
}
/** /**
* Add New History entries * Add New History entries
@ -134,11 +145,11 @@ public class MedtronicHistoryData {
this.newHistory = newEntries; this.newHistory = newEntries;
showLogs("List of history (before filtering): [" + this.newHistory.size() + "]", gson.toJson(this.newHistory)); showLogs("List of history (before filtering): [" + this.newHistory.size() + "]", gson().toJson(this.newHistory));
} }
private static void showLogs(String header, String data) { private void showLogs(String header, String data) {
if (header != null) { if (header != null) {
aapsLogger.debug(LTag.PUMP, header); aapsLogger.debug(LTag.PUMP, header);
} }
@ -208,7 +219,7 @@ public class MedtronicHistoryData {
aapsLogger.debug(LTag.PUMP, "New History entries found: {}", this.newHistory.size()); aapsLogger.debug(LTag.PUMP, "New History entries found: {}", this.newHistory.size());
showLogs("List of history (after filtering): [" + this.newHistory.size() + "]", gson.toJson(this.newHistory)); showLogs("List of history (after filtering): [" + this.newHistory.size() + "]", gson().toJson(this.newHistory));
} }
@ -321,7 +332,7 @@ public class MedtronicHistoryData {
List<PumpHistoryEntry> items = getDataForPumpSuspends(); List<PumpHistoryEntry> items = getDataForPumpSuspends();
showLogs("isPumpSuspended: ", MedtronicUtil.gsonInstance.toJson(items)); showLogs("isPumpSuspended: ", gson().toJson(items));
if (isCollectionNotEmpty(items)) { if (isCollectionNotEmpty(items)) {
@ -407,7 +418,7 @@ public class MedtronicHistoryData {
// Prime (for reseting autosense) // Prime (for reseting autosense)
List<PumpHistoryEntry> primeRecords = getFilteredItems(PumpHistoryEntryType.Prime); List<PumpHistoryEntry> primeRecords = getFilteredItems(PumpHistoryEntryType.Prime);
aapsLogger.debug(LTag.PUMP, "ProcessHistoryData: Prime [count={}, items={}]", primeRecords.size(), gson.toJson(primeRecords)); aapsLogger.debug(LTag.PUMP, "ProcessHistoryData: Prime [count={}, items={}]", primeRecords.size(), gson().toJson(primeRecords));
if (isCollectionNotEmpty(primeRecords)) { if (isCollectionNotEmpty(primeRecords)) {
try { try {
@ -421,7 +432,7 @@ public class MedtronicHistoryData {
// TDD // TDD
List<PumpHistoryEntry> tdds = getFilteredItems(PumpHistoryEntryType.EndResultTotals, getTDDType()); List<PumpHistoryEntry> tdds = getFilteredItems(PumpHistoryEntryType.EndResultTotals, getTDDType());
aapsLogger.debug(LTag.PUMP, "ProcessHistoryData: TDD [count={}, items={}]", tdds.size(), gson.toJson(tdds)); aapsLogger.debug(LTag.PUMP, "ProcessHistoryData: TDD [count={}, items={}]", tdds.size(), gson().toJson(tdds));
if (isCollectionNotEmpty(tdds)) { if (isCollectionNotEmpty(tdds)) {
try { try {
@ -432,12 +443,12 @@ public class MedtronicHistoryData {
} }
} }
pumpTime = MedtronicUtil.getPumpTime(); pumpTime = medtronicUtil.getPumpTime();
// Bolus // Bolus
List<PumpHistoryEntry> treatments = getFilteredItems(PumpHistoryEntryType.Bolus); List<PumpHistoryEntry> treatments = getFilteredItems(PumpHistoryEntryType.Bolus);
aapsLogger.debug(LTag.PUMP, "ProcessHistoryData: Bolus [count={}, items={}]", treatments.size(), gson.toJson(treatments)); aapsLogger.debug(LTag.PUMP, "ProcessHistoryData: Bolus [count={}, items={}]", treatments.size(), gson().toJson(treatments));
if (treatments.size() > 0) { if (treatments.size() > 0) {
try { try {
@ -451,7 +462,7 @@ public class MedtronicHistoryData {
// TBR // TBR
List<PumpHistoryEntry> tbrs = getFilteredItems(PumpHistoryEntryType.TempBasalCombined); List<PumpHistoryEntry> tbrs = getFilteredItems(PumpHistoryEntryType.TempBasalCombined);
aapsLogger.debug(LTag.PUMP, "ProcessHistoryData: TBRs Processed [count={}, items={}]", tbrs.size(), gson.toJson(tbrs)); aapsLogger.debug(LTag.PUMP, "ProcessHistoryData: TBRs Processed [count={}, items={}]", tbrs.size(), gson().toJson(tbrs));
if (tbrs.size() > 0) { if (tbrs.size() > 0) {
try { try {
@ -463,7 +474,7 @@ public class MedtronicHistoryData {
} }
// 'Delivery Suspend' // 'Delivery Suspend'
List<TempBasalProcessDTO> suspends = null; List<TempBasalProcessDTO> suspends;
try { try {
suspends = getSuspends(); suspends = getSuspends();
@ -473,7 +484,7 @@ public class MedtronicHistoryData {
} }
aapsLogger.debug(LTag.PUMP, "ProcessHistoryData: 'Delivery Suspend' Processed [count={}, items={}]", suspends.size(), aapsLogger.debug(LTag.PUMP, "ProcessHistoryData: 'Delivery Suspend' Processed [count={}, items={}]", suspends.size(),
gson.toJson(suspends)); gson().toJson(suspends));
if (isCollectionNotEmpty(suspends)) { if (isCollectionNotEmpty(suspends)) {
try { try {
@ -539,9 +550,9 @@ public class MedtronicHistoryData {
List<PumpHistoryEntry> tdds = filterTDDs(tddsIn); List<PumpHistoryEntry> tdds = filterTDDs(tddsIn);
aapsLogger.debug(LTag.PUMP, getLogPrefix() + "TDDs found: {}.\n{}", tdds.size(), gson.toJson(tdds)); aapsLogger.debug(LTag.PUMP, getLogPrefix() + "TDDs found: {}.\n{}", tdds.size(), gson().toJson(tdds));
List<TDD> tddsDb = databaseHelper.getTDDsForLastXDays(3); List<TDD> tddsDb = MainApp.getDbHelper().getTDDsForLastXDays(3);
for (PumpHistoryEntry tdd : tdds) { for (PumpHistoryEntry tdd : tdds) {
@ -557,7 +568,7 @@ public class MedtronicHistoryData {
aapsLogger.debug(LTag.PUMP, "TDD Add: {}", tddNew); aapsLogger.debug(LTag.PUMP, "TDD Add: {}", tddNew);
databaseHelper.createOrUpdateTDD(tddNew); MainApp.getDbHelper().createOrUpdateTDD(tddNew);
} else { } else {
@ -566,7 +577,7 @@ public class MedtronicHistoryData {
aapsLogger.debug(LTag.PUMP, "TDD Edit: {}", tddDbEntry); aapsLogger.debug(LTag.PUMP, "TDD Edit: {}", tddDbEntry);
databaseHelper.createOrUpdateTDD(tddDbEntry); MainApp.getDbHelper().createOrUpdateTDD(tddDbEntry);
} }
} }
} }
@ -595,13 +606,11 @@ public class MedtronicHistoryData {
long oldestTimestamp = getOldestTimestamp(entryList); long oldestTimestamp = getOldestTimestamp(entryList);
Gson gson = MedtronicUtil.getGsonInstance();
List<? extends DbObjectBase> entriesFromHistory = getDatabaseEntriesByLastTimestamp(oldestTimestamp, ProcessHistoryRecord.Bolus); List<? extends DbObjectBase> entriesFromHistory = getDatabaseEntriesByLastTimestamp(oldestTimestamp, ProcessHistoryRecord.Bolus);
if (doubleBolusDebug) if (doubleBolusDebug)
aapsLogger.debug(LTag.PUMP, "DoubleBolusDebug: List (before filter): {}, FromDb={}", gson.toJson(entryList), aapsLogger.debug(LTag.PUMP, "DoubleBolusDebug: List (before filter): {}, FromDb={}", gson().toJson(entryList),
gsonCore.toJson(entriesFromHistory)); gsonCore().toJson(entriesFromHistory));
filterOutAlreadyAddedEntries(entryList, entriesFromHistory); filterOutAlreadyAddedEntries(entryList, entriesFromHistory);
@ -614,8 +623,8 @@ public class MedtronicHistoryData {
filterOutNonInsulinEntries(entriesFromHistory); filterOutNonInsulinEntries(entriesFromHistory);
if (doubleBolusDebug) if (doubleBolusDebug)
aapsLogger.debug(LTag.PUMP, "DoubleBolusDebug: List (after filter): {}, FromDb={}", gson.toJson(entryList), aapsLogger.debug(LTag.PUMP, "DoubleBolusDebug: List (after filter): {}, FromDb={}", gson().toJson(entryList),
gsonCore.toJson(entriesFromHistory)); gsonCore().toJson(entriesFromHistory));
if (isCollectionEmpty(entriesFromHistory)) { if (isCollectionEmpty(entriesFromHistory)) {
for (PumpHistoryEntry treatment : entryList) { for (PumpHistoryEntry treatment : entryList) {
@ -678,8 +687,8 @@ public class MedtronicHistoryData {
List<? extends DbObjectBase> entriesFromHistory = getDatabaseEntriesByLastTimestamp(oldestTimestamp, ProcessHistoryRecord.TBR); List<? extends DbObjectBase> entriesFromHistory = getDatabaseEntriesByLastTimestamp(oldestTimestamp, ProcessHistoryRecord.TBR);
aapsLogger.debug(LTag.PUMP, ProcessHistoryRecord.TBR.getDescription() + " List (before filter): {}, FromDb={}", gson.toJson(entryList), aapsLogger.debug(LTag.PUMP, ProcessHistoryRecord.TBR.getDescription() + " List (before filter): {}, FromDb={}", gson().toJson(entryList),
gson.toJson(entriesFromHistory)); gson().toJson(entriesFromHistory));
TempBasalProcessDTO processDTO = null; TempBasalProcessDTO processDTO = null;
@ -729,7 +738,7 @@ public class MedtronicHistoryData {
tempBasal.durationInMinutes = tempBasalProcessDTO.getDuration(); tempBasal.durationInMinutes = tempBasalProcessDTO.getDuration();
databaseHelper.createOrUpdate(tempBasal); MainApp.getDbHelper().createOrUpdate(tempBasal);
aapsLogger.debug(LTag.PUMP, "Edit " + ProcessHistoryRecord.TBR.getDescription() + " - (entryFromDb={}) ", tempBasal); aapsLogger.debug(LTag.PUMP, "Edit " + ProcessHistoryRecord.TBR.getDescription() + " - (entryFromDb={}) ", tempBasal);
} else { } else {
@ -777,7 +786,7 @@ public class MedtronicHistoryData {
} }
} }
TemporaryBasal tempBasal = databaseHelper.findTempBasalByPumpId(pumpId); TemporaryBasal tempBasal = MainApp.getDbHelper().findTempBasalByPumpId(pumpId);
return tempBasal; return tempBasal;
} }
@ -798,7 +807,7 @@ public class MedtronicHistoryData {
//proposedTime += (this.pumpTime.timeDifference * 1000); //proposedTime += (this.pumpTime.timeDifference * 1000);
if (doubleBolusDebug) if (doubleBolusDebug)
aapsLogger.debug(LTag.PUMP, "DoubleBolusDebug: findDbEntry Treatment={}, FromDb={}", treatment, gson.toJson(entriesFromHistory)); aapsLogger.debug(LTag.PUMP, "DoubleBolusDebug: findDbEntry Treatment={}, FromDb={}", treatment, gson().toJson(entriesFromHistory));
if (entriesFromHistory.size() == 0) { if (entriesFromHistory.size() == 0) {
if (doubleBolusDebug) if (doubleBolusDebug)
@ -852,10 +861,10 @@ public class MedtronicHistoryData {
if (min == 0 && sec == 10 && outList.size() > 1) { if (min == 0 && sec == 10 && outList.size() > 1) {
aapsLogger.error("Too many entries (with too small diff): (timeDiff=[min={},sec={}],count={},list={})", aapsLogger.error("Too many entries (with too small diff): (timeDiff=[min={},sec={}],count={},list={})",
min, sec, outList.size(), gson.toJson(outList)); min, sec, outList.size(), gson().toJson(outList));
if (doubleBolusDebug) if (doubleBolusDebug)
aapsLogger.debug(LTag.PUMP, "DoubleBolusDebug: findDbEntry Error - Too many entries (with too small diff): (timeDiff=[min={},sec={}],count={},list={})", aapsLogger.debug(LTag.PUMP, "DoubleBolusDebug: findDbEntry Error - Too many entries (with too small diff): (timeDiff=[min={},sec={}],count={},list={})",
min, sec, outList.size(), gson.toJson(outList)); min, sec, outList.size(), gson().toJson(outList));
} }
} }
} }
@ -868,7 +877,7 @@ public class MedtronicHistoryData {
if (processHistoryRecord == ProcessHistoryRecord.Bolus) { if (processHistoryRecord == ProcessHistoryRecord.Bolus) {
return activePlugin.getActiveTreatments().getTreatmentsFromHistoryAfterTimestamp(startTimestamp); return activePlugin.getActiveTreatments().getTreatmentsFromHistoryAfterTimestamp(startTimestamp);
} else { } else {
return databaseHelper.getTemporaryBasalsDataFromTime(startTimestamp, true); return MainApp.getDbHelper().getTemporaryBasalsDataFromTime(startTimestamp, true);
} }
} }
@ -905,8 +914,8 @@ public class MedtronicHistoryData {
if (doubleBolusDebug) if (doubleBolusDebug)
aapsLogger.debug(LTag.PUMP, "DoubleBolusDebug: filterOutAlreadyAddedEntries: PumpHistory={}, Treatments={}", aapsLogger.debug(LTag.PUMP, "DoubleBolusDebug: filterOutAlreadyAddedEntries: PumpHistory={}, Treatments={}",
gson.toJson(removeTreatmentsFromPH), gson().toJson(removeTreatmentsFromPH),
gsonCore.toJson(removeTreatmentsFromHistory)); gsonCore().toJson(removeTreatmentsFromHistory));
treatmentsFromHistory.removeAll(removeTreatmentsFromHistory); treatmentsFromHistory.removeAll(removeTreatmentsFromHistory);
} }
@ -976,7 +985,7 @@ public class MedtronicHistoryData {
treatment.pumpId = bolus.getPumpId(); treatment.pumpId = bolus.getPumpId();
treatment.insulin = bolusDTO.getDeliveredAmount(); treatment.insulin = bolusDTO.getDeliveredAmount();
TreatmentService.UpdateReturn updateReturn = ((TreatmentsPlugin)activePlugin.getActiveTreatments()).getService().createOrUpdateMedtronic(treatment, false); TreatmentService.UpdateReturn updateReturn = ((TreatmentsPlugin) activePlugin.getActiveTreatments()).getService().createOrUpdateMedtronic(treatment, false);
if (doubleBolusDebug) if (doubleBolusDebug)
aapsLogger.debug(LTag.PUMP, "DoubleBolusDebug: addBolus(tretament!=null): NewTreatment={}, UpdateReturn={}", treatment, updateReturn); aapsLogger.debug(LTag.PUMP, "DoubleBolusDebug: addBolus(tretament!=null): NewTreatment={}, UpdateReturn={}", treatment, updateReturn);
@ -1026,7 +1035,7 @@ public class MedtronicHistoryData {
treatment.setLinkedObject(temporaryBasalDb); treatment.setLinkedObject(temporaryBasalDb);
databaseHelper.createOrUpdate(temporaryBasalDb); MainApp.getDbHelper().createOrUpdate(temporaryBasalDb);
aapsLogger.debug(LTag.PUMP, operation + " - [date={},pumpId={}, rate={} {}, duration={}]", // aapsLogger.debug(LTag.PUMP, operation + " - [date={},pumpId={}, rate={} {}, duration={}]", //
temporaryBasalDb.date, // temporaryBasalDb.date, //
@ -1042,7 +1051,7 @@ public class MedtronicHistoryData {
for (TempBasalProcessDTO tempBasalProcess : tempBasalProcessList) { for (TempBasalProcessDTO tempBasalProcess : tempBasalProcessList) {
TemporaryBasal tempBasal = databaseHelper.findTempBasalByPumpId(tempBasalProcess.itemOne.getPumpId()); TemporaryBasal tempBasal = MainApp.getDbHelper().findTempBasalByPumpId(tempBasalProcess.itemOne.getPumpId());
if (tempBasal == null) { if (tempBasal == null) {
// add // add
@ -1058,7 +1067,7 @@ public class MedtronicHistoryData {
tempBasalProcess.itemOne.setLinkedObject(tempBasal); tempBasalProcess.itemOne.setLinkedObject(tempBasal);
tempBasalProcess.itemTwo.setLinkedObject(tempBasal); tempBasalProcess.itemTwo.setLinkedObject(tempBasal);
databaseHelper.createOrUpdate(tempBasal); MainApp.getDbHelper().createOrUpdate(tempBasal);
} }
} }
@ -1205,11 +1214,11 @@ public class MedtronicHistoryData {
if (!finishedItems) { if (!finishedItems) {
showLogs("NoDeliveryRewindPrimeRecords: Not finished Items: ", gson.toJson(tempData)); showLogs("NoDeliveryRewindPrimeRecords: Not finished Items: ", gson().toJson(tempData));
return outList; return outList;
} }
showLogs("NoDeliveryRewindPrimeRecords: Records to evaluate: ", gson.toJson(tempData)); showLogs("NoDeliveryRewindPrimeRecords: Records to evaluate: ", gson().toJson(tempData));
List<PumpHistoryEntry> items = getFilteredItems(tempData, // List<PumpHistoryEntry> items = getFilteredItems(tempData, //
PumpHistoryEntryType.Prime PumpHistoryEntryType.Prime
@ -1305,7 +1314,7 @@ public class MedtronicHistoryData {
} }
} }
LocalDateTime oldestEntryTime = null; LocalDateTime oldestEntryTime;
try { try {
@ -1370,11 +1379,11 @@ public class MedtronicHistoryData {
private PumpHistoryEntryType getTDDType() { private PumpHistoryEntryType getTDDType() {
if (MedtronicUtil.getMedtronicPumpModel() == null) { if (medtronicUtil.getMedtronicPumpModel() == null) {
return PumpHistoryEntryType.EndResultTotals; return PumpHistoryEntryType.EndResultTotals;
} }
switch (MedtronicUtil.getMedtronicPumpModel()) { switch (medtronicUtil.getMedtronicPumpModel()) {
case Medtronic_515: case Medtronic_515:
case Medtronic_715: case Medtronic_715:
@ -1401,13 +1410,13 @@ public class MedtronicHistoryData {
List<PumpHistoryEntry> filteredItems = getFilteredItems(PumpHistoryEntryType.ChangeBasalProfile_NewProfile); List<PumpHistoryEntry> filteredItems = getFilteredItems(PumpHistoryEntryType.ChangeBasalProfile_NewProfile);
aapsLogger.debug(LTag.PUMP, "hasBasalProfileChanged. Items: " + gson.toJson(filteredItems)); aapsLogger.debug(LTag.PUMP, "hasBasalProfileChanged. Items: " + gson().toJson(filteredItems));
return (filteredItems.size() > 0); return (filteredItems.size() > 0);
} }
public void processLastBasalProfileChange(MedtronicPumpStatus mdtPumpStatus) { public void processLastBasalProfileChange(PumpType pumpType, MedtronicPumpStatus mdtPumpStatus) {
List<PumpHistoryEntry> filteredItems = getFilteredItems(PumpHistoryEntryType.ChangeBasalProfile_NewProfile); List<PumpHistoryEntry> filteredItems = getFilteredItems(PumpHistoryEntryType.ChangeBasalProfile_NewProfile);
@ -1433,7 +1442,7 @@ public class MedtronicHistoryData {
aapsLogger.debug(LTag.PUMP, "processLastBasalProfileChange. item found, setting new basalProfileLocally: " + newProfile); aapsLogger.debug(LTag.PUMP, "processLastBasalProfileChange. item found, setting new basalProfileLocally: " + newProfile);
BasalProfile basalProfile = (BasalProfile) newProfile.getDecodedData().get("Object"); BasalProfile basalProfile = (BasalProfile) newProfile.getDecodedData().get("Object");
mdtPumpStatus.basalsByHour = basalProfile.getProfilesByHour(); mdtPumpStatus.basalsByHour = basalProfile.getProfilesByHour(pumpType);
} }
} }
@ -1447,7 +1456,6 @@ public class MedtronicHistoryData {
public void setLastHistoryRecordTime(Long lastHistoryRecordTime) { public void setLastHistoryRecordTime(Long lastHistoryRecordTime) {
// this.previousLastHistoryRecordTime = this.lastHistoryRecordTime; // this.previousLastHistoryRecordTime = this.lastHistoryRecordTime;
this.lastHistoryRecordTime = lastHistoryRecordTime;
} }
@ -1470,8 +1478,8 @@ public class MedtronicHistoryData {
for (PumpHistoryEntry pumpHistoryEntry : TBRs_Input) { for (PumpHistoryEntry pumpHistoryEntry : TBRs_Input) {
if (map.containsKey(pumpHistoryEntry.DT)) { if (map.containsKey(pumpHistoryEntry.DT)) {
MedtronicPumpHistoryDecoder.decodeTempBasal(map.get(pumpHistoryEntry.DT), pumpHistoryEntry); medtronicPumpHistoryDecoder.decodeTempBasal(map.get(pumpHistoryEntry.DT), pumpHistoryEntry);
pumpHistoryEntry.setEntryType(PumpHistoryEntryType.TempBasalCombined); pumpHistoryEntry.setEntryType(medtronicUtil.getMedtronicPumpModel(), PumpHistoryEntryType.TempBasalCombined);
TBRs.add(pumpHistoryEntry); TBRs.add(pumpHistoryEntry);
map.remove(pumpHistoryEntry.DT); map.remove(pumpHistoryEntry.DT);
} else { } else {

View file

@ -3,14 +3,13 @@ package info.nightscout.androidaps.plugins.pump.medtronic.data.dto;
import com.google.gson.annotations.Expose; import com.google.gson.annotations.Expose;
import org.joda.time.Instant; import org.joda.time.Instant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil; import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
@ -32,7 +31,7 @@ import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
*/ */
public class BasalProfile { public class BasalProfile {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPCOMM); private final AAPSLogger aapsLogger;
public static final int MAX_RAW_DATA_SIZE = (48 * 3) + 1; public static final int MAX_RAW_DATA_SIZE = (48 * 3) + 1;
private static final boolean DEBUG_BASALPROFILE = false; private static final boolean DEBUG_BASALPROFILE = false;
@ -41,18 +40,20 @@ public class BasalProfile {
private List<BasalProfileEntry> listEntries; private List<BasalProfileEntry> listEntries;
public BasalProfile() { public BasalProfile(AAPSLogger aapsLogger) {
this.aapsLogger = aapsLogger;
init(); init();
} }
public BasalProfile(byte[] data) { public BasalProfile(AAPSLogger aapsLogger, byte[] data) {
this .aapsLogger = aapsLogger;
setRawData(data); setRawData(data);
} }
// this asUINT8 should be combined with Record.asUINT8, and placed in a new util class. // this asUINT8 should be combined with Record.asUINT8, and placed in a new util class.
protected static int readUnsignedByte(byte b) { private static int readUnsignedByte(byte b) {
return (b < 0) ? b + 256 : b; return (b < 0) ? b + 256 : b;
} }
@ -65,9 +66,9 @@ public class BasalProfile {
} }
public boolean setRawData(byte[] data) { private boolean setRawData(byte[] data) {
if (data == null) { if (data == null) {
LOG.error("setRawData: buffer is null!"); aapsLogger.error(LTag.PUMPCOMM,"setRawData: buffer is null!");
return false; return false;
} }
@ -90,7 +91,7 @@ public class BasalProfile {
public boolean setRawDataFromHistory(byte[] data) { public boolean setRawDataFromHistory(byte[] data) {
if (data == null) { if (data == null) {
LOG.error("setRawData: buffer is null!"); aapsLogger.error(LTag.PUMPCOMM,"setRawData: buffer is null!");
return false; return false;
} }
@ -115,13 +116,13 @@ public class BasalProfile {
public void dumpBasalProfile() { public void dumpBasalProfile() {
LOG.debug("Basal Profile entries:"); aapsLogger.debug(LTag.PUMPCOMM,"Basal Profile entries:");
List<BasalProfileEntry> entries = getEntries(); List<BasalProfileEntry> entries = getEntries();
for (int i = 0; i < entries.size(); i++) { for (int i = 0; i < entries.size(); i++) {
BasalProfileEntry entry = entries.get(i); BasalProfileEntry entry = entries.get(i);
String startString = entry.startTime.toString("HH:mm"); String startString = entry.startTime.toString("HH:mm");
// this doesn't work // this doesn't work
LOG.debug(String.format("Entry %d, rate=%.3f (0x%02X), start=%s (0x%02X)", i + 1, entry.rate, aapsLogger.debug(LTag.PUMPCOMM,String.format("Entry %d, rate=%.3f (0x%02X), start=%s (0x%02X)", i + 1, entry.rate,
entry.rate_raw, startString, entry.startTime_raw)); entry.rate_raw, startString, entry.startTime_raw));
} }
@ -168,14 +169,14 @@ public class BasalProfile {
BasalProfileEntry rval = new BasalProfileEntry(); BasalProfileEntry rval = new BasalProfileEntry();
List<BasalProfileEntry> entries = getEntries(); List<BasalProfileEntry> entries = getEntries();
if (entries.size() == 0) { if (entries.size() == 0) {
LOG.warn(String.format("getEntryForTime(%s): table is empty", aapsLogger.warn(LTag.PUMPCOMM,String.format("getEntryForTime(%s): table is empty",
when.toDateTime().toLocalTime().toString("HH:mm"))); when.toDateTime().toLocalTime().toString("HH:mm")));
return rval; return rval;
} }
// Log.w(TAG,"Assuming first entry"); // Log.w(TAG,"Assuming first entry");
rval = entries.get(0); rval = entries.get(0);
if (entries.size() == 1) { if (entries.size() == 1) {
LOG.debug("getEntryForTime: Only one entry in profile"); aapsLogger.debug(LTag.PUMPCOMM,"getEntryForTime: Only one entry in profile");
return rval; return rval;
} }
@ -185,17 +186,17 @@ public class BasalProfile {
while (!done) { while (!done) {
BasalProfileEntry entry = entries.get(i); BasalProfileEntry entry = entries.get(i);
if (DEBUG_BASALPROFILE) { if (DEBUG_BASALPROFILE) {
LOG.debug(String.format("Comparing 'now'=%s to entry 'start time'=%s", when.toDateTime().toLocalTime() aapsLogger.debug(LTag.PUMPCOMM,String.format("Comparing 'now'=%s to entry 'start time'=%s", when.toDateTime().toLocalTime()
.toString("HH:mm"), entry.startTime.toString("HH:mm"))); .toString("HH:mm"), entry.startTime.toString("HH:mm")));
} }
if (localMillis >= entry.startTime.getMillisOfDay()) { if (localMillis >= entry.startTime.getMillisOfDay()) {
rval = entry; rval = entry;
if (DEBUG_BASALPROFILE) if (DEBUG_BASALPROFILE)
LOG.debug("Accepted Entry"); aapsLogger.debug(LTag.PUMPCOMM,"Accepted Entry");
} else { } else {
// entry at i has later start time, keep older entry // entry at i has later start time, keep older entry
if (DEBUG_BASALPROFILE) if (DEBUG_BASALPROFILE)
LOG.debug("Rejected Entry"); aapsLogger.debug(LTag.PUMPCOMM,"Rejected Entry");
done = true; done = true;
} }
i++; i++;
@ -204,7 +205,7 @@ public class BasalProfile {
} }
} }
if (DEBUG_BASALPROFILE) { if (DEBUG_BASALPROFILE) {
LOG.debug(String.format("getEntryForTime(%s): Returning entry: rate=%.3f (%d), start=%s (%d)", when aapsLogger.debug(LTag.PUMPCOMM,String.format("getEntryForTime(%s): Returning entry: rate=%.3f (%d), start=%s (%d)", when
.toDateTime().toLocalTime().toString("HH:mm"), rval.rate, rval.rate_raw, .toDateTime().toLocalTime().toString("HH:mm"), rval.rate, rval.rate_raw,
rval.startTime.toString("HH:mm"), rval.startTime_raw)); rval.startTime.toString("HH:mm"), rval.startTime_raw));
} }
@ -216,7 +217,7 @@ public class BasalProfile {
List<BasalProfileEntry> entries = new ArrayList<>(); List<BasalProfileEntry> entries = new ArrayList<>();
if (mRawData == null || mRawData[2] == 0x3f) { if (mRawData == null || mRawData[2] == 0x3f) {
LOG.warn("Raw Data is empty."); aapsLogger.warn(LTag.PUMPCOMM,"Raw Data is empty.");
return entries; // an empty list return entries; // an empty list
} }
boolean done = false; boolean done = false;
@ -234,9 +235,9 @@ public class BasalProfile {
st = readUnsignedByte(mRawData[i + 2]); st = readUnsignedByte(mRawData[i + 2]);
try { try {
entries.add(new BasalProfileEntry(r, st)); entries.add(new BasalProfileEntry(aapsLogger, r, st));
} catch (Exception ex) { } catch (Exception ex) {
LOG.error("Error decoding basal profile from bytes: {}", ByteUtil.shortHexString(mRawData)); aapsLogger.error(LTag.PUMPCOMM,"Error decoding basal profile from bytes: {}", ByteUtil.shortHexString(mRawData));
throw ex; throw ex;
} }
@ -278,17 +279,17 @@ public class BasalProfile {
} }
public Double[] getProfilesByHour() { public Double[] getProfilesByHour(PumpType pumpType) {
List<BasalProfileEntry> entries = null; List<BasalProfileEntry> entries = null;
try { try {
entries = getEntries(); entries = getEntries();
} catch (Exception ex) { } catch (Exception ex) {
LOG.error("============================================================================="); aapsLogger.error(LTag.PUMPCOMM,"=============================================================================");
LOG.error(" Error generating entries. Ex.: " + ex, ex); aapsLogger.error(LTag.PUMPCOMM," Error generating entries. Ex.: " + ex, ex);
LOG.error(" rawBasalValues: " + ByteUtil.shortHexString(this.getRawData())); aapsLogger.error(LTag.PUMPCOMM," rawBasalValues: " + ByteUtil.shortHexString(this.getRawData()));
LOG.error("============================================================================="); aapsLogger.error(LTag.PUMPCOMM,"=============================================================================");
//FabricUtil.createEvent("MedtronicBasalProfileGetByHourError", null); //FabricUtil.createEvent("MedtronicBasalProfileGetByHourError", null);
} }
@ -305,8 +306,6 @@ public class BasalProfile {
Double[] basalByHour = new Double[24]; Double[] basalByHour = new Double[24];
PumpType pumpType = MedtronicUtil.getPumpStatus().pumpType;
for (int i = 0; i < entries.size(); i++) { for (int i = 0; i < entries.size(); i++) {
BasalProfileEntry current = entries.get(i); BasalProfileEntry current = entries.get(i);
@ -368,7 +367,7 @@ public class BasalProfile {
return L.isEnabled(L.PUMPCOMM); return L.isEnabled(L.PUMPCOMM);
} }
public boolean verify() { public boolean verify(PumpType pumpType) {
try { try {
getEntries(); getEntries();
@ -376,7 +375,7 @@ public class BasalProfile {
return false; return false;
} }
Double[] profilesByHour = getProfilesByHour(); Double[] profilesByHour = getProfilesByHour(pumpType);
for (Double aDouble : profilesByHour) { for (Double aDouble : profilesByHour) {
if (aDouble > 35.0d) if (aDouble > 35.0d)

View file

@ -1,11 +1,9 @@
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto; package info.nightscout.androidaps.plugins.pump.medtronic.data.dto;
import org.joda.time.LocalTime; import org.joda.time.LocalTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil; import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
/** /**
@ -15,22 +13,18 @@ import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
*/ */
public class BasalProfileEntry { public class BasalProfileEntry {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPCOMM); byte[] rate_raw;
public byte[] rate_raw;
public double rate; public double rate;
public byte startTime_raw; byte startTime_raw;
public LocalTime startTime; // Just a "time of day" public LocalTime startTime; // Just a "time of day"
public BasalProfileEntry() { public BasalProfileEntry() {
rate = -9.999E6; rate = -9.999E6;
rate_raw = MedtronicUtil.getByteArrayFromUnsignedShort(0xFF, true); rate_raw = MedtronicUtil.getByteArrayFromUnsignedShort(0xFF, true);
startTime = new LocalTime(0); startTime = new LocalTime(0);
startTime_raw = (byte)0xFF; startTime_raw = (byte) 0xFF;
} }
public BasalProfileEntry(double rate, int hour, int minutes) { public BasalProfileEntry(double rate, int hour, int minutes) {
byte[] data = MedtronicUtil.getBasalStrokes(rate, true); byte[] data = MedtronicUtil.getBasalStrokes(rate, true);
@ -44,47 +38,42 @@ public class BasalProfileEntry {
interval++; interval++;
} }
startTime_raw = (byte)interval; startTime_raw = (byte) interval;
startTime = new LocalTime(hour, minutes == 30 ? 30 : 0); startTime = new LocalTime(hour, minutes == 30 ? 30 : 0);
} }
BasalProfileEntry(AAPSLogger aapsLogger, int rateStrokes, int startTimeInterval) {
public BasalProfileEntry(int rateStrokes, int startTimeInterval) {
// rateByte is insulin delivery rate, U/hr, in 0.025 U increments // rateByte is insulin delivery rate, U/hr, in 0.025 U increments
// startTimeByte is time-of-day, in 30 minute increments // startTimeByte is time-of-day, in 30 minute increments
rate_raw = MedtronicUtil.getByteArrayFromUnsignedShort(rateStrokes, true); rate_raw = MedtronicUtil.getByteArrayFromUnsignedShort(rateStrokes, true);
rate = rateStrokes * 0.025; rate = rateStrokes * 0.025;
startTime_raw = (byte)startTimeInterval; startTime_raw = (byte) startTimeInterval;
try { try {
startTime = new LocalTime(startTimeInterval / 2, (startTimeInterval % 2) * 30); startTime = new LocalTime(startTimeInterval / 2, (startTimeInterval % 2) * 30);
} catch (Exception ex) { } catch (Exception ex) {
LOG.error( aapsLogger.error(LTag.PUMPCOMM,
"Error creating BasalProfileEntry: startTimeInterval={}, startTime_raw={}, hours={}, rateStrokes={}", "Error creating BasalProfileEntry: startTimeInterval={}, startTime_raw={}, hours={}, rateStrokes={}",
startTimeInterval, startTime_raw, startTimeInterval / 2, rateStrokes); startTimeInterval, startTime_raw, startTimeInterval / 2, rateStrokes);
throw ex; throw ex;
} }
} }
BasalProfileEntry(byte rateByte, int startTimeByte) {
public BasalProfileEntry(byte rateByte, int startTimeByte) {
// rateByte is insulin delivery rate, U/hr, in 0.025 U increments // rateByte is insulin delivery rate, U/hr, in 0.025 U increments
// startTimeByte is time-of-day, in 30 minute increments // startTimeByte is time-of-day, in 30 minute increments
rate_raw = MedtronicUtil.getByteArrayFromUnsignedShort(rateByte, true); rate_raw = MedtronicUtil.getByteArrayFromUnsignedShort(rateByte, true);
rate = rateByte * 0.025; rate = rateByte * 0.025;
startTime_raw = (byte)startTimeByte; startTime_raw = (byte) startTimeByte;
startTime = new LocalTime(startTimeByte / 2, (startTimeByte % 2) * 30); startTime = new LocalTime(startTimeByte / 2, (startTimeByte % 2) * 30);
} }
public void setStartTime(LocalTime localTime) { public void setStartTime(LocalTime localTime) {
this.startTime = localTime; this.startTime = localTime;
} }
public void setRate(double rate) { public void setRate(double rate) {
this.rate = rate; this.rate = rate;
} }
} }

View file

@ -24,8 +24,6 @@ import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpH
public class DailyTotalsDTO { public class DailyTotalsDTO {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPCOMM);
// bg avg, bg low hi, number Bgs, // bg avg, bg low hi, number Bgs,
// Sen Avg, Sen Lo/Hi, Sens Cal/Data = 0/0, // Sen Avg, Sen Lo/Hi, Sens Cal/Data = 0/0,
// Insulin=19.8[8,9], Basal[10,11], Bolus[13,14], Carbs, // Insulin=19.8[8,9], Basal[10,11], Bolus[13,14], Carbs,

View file

@ -1,16 +1,14 @@
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto; package info.nightscout.androidaps.plugins.pump.medtronic.data.dto;
import com.google.gson.annotations.Expose; import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil; import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
@ -19,21 +17,7 @@ import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
* <p> * <p>
* Just need a class to keep the pair together, for parcel transport. * Just need a class to keep the pair together, for parcel transport.
*/ */
public class TempBasalPair { public class TempBasalPair extends info.nightscout.androidaps.plugins.pump.common.data.TempBasalPair {
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMPCOMM);
@Expose
private double insulinRate = 0.0d;
@Expose
private int durationMinutes = 0;
@Expose
private boolean isPercent = false;
public TempBasalPair() {
}
/** /**
* This constructor is for use with PumpHistoryDecoder * This constructor is for use with PumpHistoryDecoder
@ -43,6 +27,7 @@ public class TempBasalPair {
* @param isPercent * @param isPercent
*/ */
public TempBasalPair(byte rateByte, int startTimeByte, boolean isPercent) { public TempBasalPair(byte rateByte, int startTimeByte, boolean isPercent) {
super();
int rateInt = ByteUtil.asUINT8(rateByte); int rateInt = ByteUtil.asUINT8(rateByte);
if (isPercent) if (isPercent)
@ -54,17 +39,11 @@ public class TempBasalPair {
} }
public TempBasalPair(double insulinRate, boolean isPercent, int durationMinutes) { public TempBasalPair(AAPSLogger aapsLogger, byte[] response) {
this.insulinRate = insulinRate; super();
this.isPercent = isPercent;
this.durationMinutes = durationMinutes;
}
public TempBasalPair(byte[] response) {
if (L.isEnabled(L.PUMPCOMM)) if (L.isEnabled(L.PUMPCOMM))
LOG.debug("Received TempBasal response: " + ByteUtil.getHex(response)); aapsLogger.debug(LTag.PUMPBTCOMM, "Received TempBasal response: " + ByteUtil.getHex(response));
isPercent = response[0] == 1; isPercent = response[0] == 1;
@ -76,50 +55,25 @@ public class TempBasalPair {
insulinRate = strokes / 40.0d; insulinRate = strokes / 40.0d;
} }
if (response.length<6) { if (response.length < 6) {
durationMinutes = ByteUtil.asUINT8(response[4]); durationMinutes = ByteUtil.asUINT8(response[4]);
} else { } else {
durationMinutes = MedtronicUtil.makeUnsignedShort(response[4], response[5]); durationMinutes = MedtronicUtil.makeUnsignedShort(response[4], response[5]);
} }
LOG.warn("TempBasalPair (with {} byte response): {}", response.length, toString()); aapsLogger.warn(LTag.PUMPBTCOMM, "TempBasalPair (with {} byte response): {}", response.length, toString());
} }
public double getInsulinRate() { public TempBasalPair(double insulinRate, boolean isPercent, int durationMinutes) {
return insulinRate; super(insulinRate, isPercent, durationMinutes);
}
public void setInsulinRate(double insulinRate) {
this.insulinRate = insulinRate;
}
public int getDurationMinutes() {
return durationMinutes;
}
public void setDurationMinutes(int durationMinutes) {
this.durationMinutes = durationMinutes;
}
public boolean isPercent() {
return isPercent;
}
public void setIsPercent(boolean yesIsPercent) {
this.isPercent = yesIsPercent;
} }
public byte[] getAsRawData() { public byte[] getAsRawData() {
List<Byte> list = new ArrayList<Byte>(); List<Byte> list = new ArrayList<>();
list.add((byte) 5); list.add((byte) 5);
@ -168,7 +122,7 @@ public class TempBasalPair {
} }
@Override @NotNull @Override
public String toString() { public String toString() {
return "TempBasalPair [" + "Rate=" + insulinRate + ", DurationMinutes=" + durationMinutes + ", IsPercent=" return "TempBasalPair [" + "Rate=" + insulinRate + ", DurationMinutes=" + durationMinutes + ", IsPercent="
+ isPercent + "]"; + isPercent + "]";

View file

@ -1,5 +1,7 @@
package info.nightscout.androidaps.plugins.pump.medtronic.defs; package info.nightscout.androidaps.plugins.pump.medtronic.defs;
import androidx.annotation.StringRes;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -19,30 +21,14 @@ public enum BatteryType {
NiMH(R.string.key_medtronic_pump_battery_nimh, 1.10d, 1.40d) // NiMH(R.string.key_medtronic_pump_battery_nimh, 1.10d, 1.40d) //
; ;
private final String description; public final @StringRes int description;
public double lowVoltage; public final double lowVoltage;
public double highVoltage; public final double highVoltage;
static Map<String, BatteryType> mapByDescription;
static {
mapByDescription = new HashMap<>();
for (BatteryType value : values()) {
mapByDescription.put(value.description, value);
}
}
BatteryType(int resId, double lowVoltage, double highVoltage) { BatteryType(int resId, double lowVoltage, double highVoltage) {
this.description = MainApp.gs(resId); this.description = resId;
this.lowVoltage = lowVoltage; this.lowVoltage = lowVoltage;
this.highVoltage = highVoltage; this.highVoltage = highVoltage;
} }
public static BatteryType getByDescription(String batteryTypeStr) {
if (mapByDescription.containsKey(batteryTypeStr)) {
return mapByDescription.get(batteryTypeStr);
}
return BatteryType.None;
}
} }

View file

@ -1,7 +1,5 @@
package info.nightscout.androidaps.plugins.pump.medtronic.defs; package info.nightscout.androidaps.plugins.pump.medtronic.defs;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
/** /**
* Created by andy on 6/28/18. * Created by andy on 6/28/18.
*/ */
@ -30,9 +28,9 @@ public enum MedtronicStatusRefreshType {
} }
public MedtronicCommandType getCommandType() { public MedtronicCommandType getCommandType(MedtronicDeviceType medtronicDeviceType) {
if (this == Configuration) { if (this == Configuration) {
return MedtronicCommandType.getSettings(MedtronicUtil.getMedtronicPumpModel()); return MedtronicCommandType.getSettings(medtronicDeviceType);
} else } else
return commandType; return commandType;
} }

Some files were not shown because too many files have changed in this diff Show more