Diaconn support

This commit is contained in:
Milos Kozak 2021-06-08 23:27:14 +02:00
parent 13245df279
commit 8e466be92c
152 changed files with 16972 additions and 6 deletions

View file

@ -192,6 +192,7 @@ dependencies {
implementation project(':omnipod-common')
implementation project(':omnipod-eros')
implementation project(':omnipod-dash')
implementation project(':diaconn')
implementation fileTree(include: ['*.jar'], dir: 'libs')

View file

@ -14,6 +14,7 @@ import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin
import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
import info.nightscout.androidaps.danar.DanaRPlugin
import info.nightscout.androidaps.danars.DanaRSPlugin
import info.nightscout.androidaps.diaconn.DiaconnG8Plugin
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.events.EventPreferenceChange
import info.nightscout.androidaps.events.EventRebuildTabs
@ -99,6 +100,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
@Inject lateinit var passwordCheck: PasswordCheck
@Inject lateinit var nsSettingStatus: NSSettingsStatus
@Inject lateinit var openHumansUploader: OpenHumansUploader
@Inject lateinit var diaconnG8Plugin: DiaconnG8Plugin
override fun onAttach(context: Context) {
AndroidSupportInjection.inject(this)
@ -173,6 +175,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
addPreferencesFromResourceIfEnabled(localInsightPlugin, rootKey, config.PUMPDRIVERS)
addPreferencesFromResourceIfEnabled(comboPlugin, rootKey, config.PUMPDRIVERS)
addPreferencesFromResourceIfEnabled(medtronicPumpPlugin, rootKey, config.PUMPDRIVERS)
addPreferencesFromResourceIfEnabled(diaconnG8Plugin, rootKey, config.PUMPDRIVERS)
addPreferencesFromResource(R.xml.pref_pump, rootKey, config.PUMPDRIVERS)
addPreferencesFromResourceIfEnabled(virtualPumpPlugin, rootKey)
addPreferencesFromResourceIfEnabled(insulinOrefFreePeakPlugin, rootKey)

View file

@ -13,6 +13,7 @@ import info.nightscout.androidaps.danar.di.DanaRModule
import info.nightscout.androidaps.danars.di.DanaRSModule
import info.nightscout.androidaps.database.DatabaseModule
import info.nightscout.androidaps.di.CoreModule
import info.nightscout.androidaps.diaconn.di.DiaconnG8Module
import info.nightscout.androidaps.insight.di.InsightDatabaseModule
import info.nightscout.androidaps.insight.di.InsightModule
import info.nightscout.androidaps.plugins.pump.common.di.PumpCommonModule
@ -56,7 +57,8 @@ import javax.inject.Singleton
InsightModule::class,
InsightDatabaseModule::class,
WorkersModule::class,
OHUploaderModule::class
OHUploaderModule::class,
DiaconnG8Module::class
]
)
interface AppComponent : AndroidInjector<MainApp> {

View file

@ -8,6 +8,7 @@ import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin
import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
import info.nightscout.androidaps.danar.DanaRPlugin
import info.nightscout.androidaps.danars.DanaRSPlugin
import info.nightscout.androidaps.diaconn.DiaconnG8Plugin
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
@ -158,6 +159,12 @@ abstract class PluginsModule {
// @IntKey(155)
// abstract fun bindOmnipodPumpPlugin(plugin: OmnipodErosPumpPlugin): PluginBase
@Binds
@PumpDriver
@IntoMap
@IntKey(155)
abstract fun bindDiaconnG8Plugin(plugin: DiaconnG8Plugin): PluginBase
@Binds
@NotNSClient
@IntoMap

View file

@ -29,6 +29,7 @@ import info.nightscout.androidaps.extensions.toStringMedium
import info.nightscout.androidaps.extensions.toStringShort
import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.activities.HistoryBrowseActivity
import info.nightscout.androidaps.diaconn.DiaconnG8Plugin
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.interfaces.Config
@ -304,7 +305,11 @@ class ActionsFragment : DaggerFragment() {
val activeBgSource = activePlugin.activeBgSource
historyBrowser?.visibility = (profile != null).toVisibility()
fill?.visibility = (pump.pumpDescription.isRefillingCapable && pump.isInitialized() && !pump.isSuspended()).toVisibility()
pumpBatteryChange?.visibility = (pump.pumpDescription.isBatteryReplaceable || (pump is OmnipodErosPumpPlugin && pump.isUseRileyLinkBatteryLevel && pump.isBatteryChangeLoggingEnabled)).toVisibility()
if(pump is DiaconnG8Plugin) {
pumpBatteryChange?.visibility = (pump.pumpDescription.isBatteryReplaceable && !pump.isBatteryChangeLoggingEnabled()).toVisibility()
} else {
pumpBatteryChange?.visibility = (pump.pumpDescription.isBatteryReplaceable || (pump is OmnipodErosPumpPlugin && pump.isUseRileyLinkBatteryLevel && pump.isBatteryChangeLoggingEnabled)).toVisibility()
}
tempTarget?.visibility = (profile != null && config.APS).toVisibility()
tddStats?.visibility = pump.pumpDescription.supportsTDDs.toVisibility()

View file

@ -129,7 +129,7 @@ class LocalProfileFragment : DaggerFragment() {
binding.dia.setParams(currentProfile.dia, hardLimits.minDia(), hardLimits.maxDia(), 0.1, DecimalFormat("0.0"), false, binding.save, textWatch)
binding.dia.tag = "LP_DIA"
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.ic, "IC", resourceHelper.gs(R.string.ic_label), currentProfile.ic, null, hardLimits.minIC(), hardLimits.maxIC(), 0.1, DecimalFormat("0.0"), save)
basalView = TimeListEdit(context, aapsLogger, dateUtil, view, R.id.basal_holder, "BASAL", resourceHelper.gs(R.string.basal_label) + ": " + sumLabel(), currentProfile.basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save)
basalView = TimeListEdit(context, aapsLogger, dateUtil, view, R.id.basal_holder, "BASAL", resourceHelper.gs(R.string.basal_label) + ": " + sumLabel(), currentProfile.basal, null, pumpDescription.basalMinimumRate, pumpDescription.basalMaximumRate, 0.01, DecimalFormat("0.00"), save)
if (units == Constants.MGDL) {
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf, "ISF", resourceHelper.gs(R.string.isf_label), currentProfile.isf, null, HardLimits.MIN_ISF, HardLimits.MAX_ISF, 1.0, DecimalFormat("0"), save)
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.target, "TARGET", resourceHelper.gs(R.string.target_label), currentProfile.targetLow, currentProfile.targetHigh, HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), 1.0, DecimalFormat("0"), save)

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.queue.commands
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Dana
import info.nightscout.androidaps.interfaces.Diaconn
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.queue.Callback
import javax.inject.Inject
@ -22,6 +23,13 @@ class CommandLoadEvents(
aapsLogger.debug(LTag.PUMPQUEUE, "Result success: ${r.success} enacted: ${r.enacted}")
callback?.result(r)?.run()
}
if (pump is Diaconn) {
val diaconnPump = pump as Diaconn
val r = diaconnPump.loadHistory()
aapsLogger.debug(LTag.PUMPQUEUE, "Result success: ${r.success} enacted: ${r.enacted}")
callback?.result(r)?.run()
}
}
override fun status(): String = "LOAD EVENTS"

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.queue.commands
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Dana
import info.nightscout.androidaps.interfaces.Diaconn
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.queue.Callback
import javax.inject.Inject
@ -23,6 +24,13 @@ class CommandLoadHistory(
aapsLogger.debug(LTag.PUMPQUEUE, "Result success: " + r.success + " enacted: " + r.enacted)
callback?.result(r)?.run()
}
if (pump is Diaconn) {
val diaconnG8Pump = pump as Diaconn
val r = diaconnG8Pump.loadHistory()
aapsLogger.debug(LTag.PUMPQUEUE, "Result success: " + r.success + " enacted: " + r.enacted)
callback?.result(r)?.run()
}
}
override fun status(): String = "LOAD HISTORY $type"

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.queue.commands
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Dana
import info.nightscout.androidaps.interfaces.Diaconn
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.queue.Callback
import javax.inject.Inject
@ -21,6 +22,12 @@ class CommandSetUserSettings(
aapsLogger.debug(LTag.PUMPQUEUE, "Result success: ${r.success} enacted: ${r.enacted}")
callback?.result(r)?.run()
}
if (pump is Diaconn) {
val r = pump.setUserOptions()
aapsLogger.debug(LTag.PUMPQUEUE, "Result success: ${r.success} enacted: ${r.enacted}")
callback?.result(r)?.run()
}
}
override fun status(): String = "SET USER SETTINGS"

View file

@ -425,7 +425,7 @@ class TDDStatsActivity : NoSplashAppCompatActivity() {
private fun isOldData(historyList: List<TotalDailyDose>): Boolean {
val type = activePlugin.activePump.pumpDescription.pumpType
val startsYesterday = type == PumpType.DANA_R || type == PumpType.DANA_RS || type == PumpType.DANA_RV2 || type == PumpType.DANA_R_KOREAN || type == PumpType.ACCU_CHEK_INSIGHT_VIRTUAL
val startsYesterday = type == PumpType.DANA_R || type == PumpType.DANA_RS || type == PumpType.DANA_RV2 || type == PumpType.DANA_R_KOREAN || type == PumpType.ACCU_CHEK_INSIGHT_VIRTUAL || type == PumpType.DIACONN_G8
val df: DateFormat = SimpleDateFormat("dd.MM.", Locale.getDefault())
return historyList.size < 3 || df.format(Date(historyList[0].timestamp)) != df.format(Date(System.currentTimeMillis() - if (startsYesterday) 1000 * 60 * 60 * 24 else 0))
}

View file

@ -0,0 +1,8 @@
package info.nightscout.androidaps.interfaces
import info.nightscout.androidaps.data.PumpEnactResult
interface Diaconn {
fun loadHistory(): PumpEnactResult // for history browser
fun setUserOptions(): PumpEnactResult // pump etc settings
}

View file

@ -9,5 +9,6 @@ enum class ManufacturerType(val description: String) {
Animas("Animas"),
Cellnovo("Cellnovo"),
Roche("Roche"),
Ypsomed("Ypsomed");
Ypsomed("Ypsomed"),
G2e("G2e");
}

View file

@ -23,6 +23,7 @@ enum class PumpCapability {
MedtronicCapabilities(arrayOf(Bolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, TDD)),
OmnipodCapabilities(arrayOf(Bolus, TempBasal, BasalProfileSet, BasalRate30min)),
YpsomedCapabilities(arrayOf(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, TDD, ManualTDDLoad)), // BasalRates (separately grouped)
DiaconnCapabilities(arrayOf(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, TDD, ManualTDDLoad)), //
BasalRate_Duration15minAllowed,
BasalRate_Duration30minAllowed,
BasalRate_Duration15and30minAllowed(arrayOf(BasalRate_Duration15minAllowed, BasalRate_Duration30minAllowed)),

View file

@ -284,7 +284,23 @@ enum class PumpType {
model = "USER",
tbrSettings = DoseSettings(1.0, 15, 24 * 60, 0.0, 500.0),
extendedBolusSettings = DoseSettings(0.1, 15, 12 * 60, 0.1),
pumpCapability = PumpCapability.MDI);
pumpCapability = PumpCapability.MDI),
//Diaconn Pump
DIACONN_G8(description = "DiaconnG8",
manufacturer = ManufacturerType.G2e,
model = "Diaconn G8",
bolusSize = 0.01,
specialBolusSize = null,
extendedBolusSettings = DoseSettings(0.05, 10, 5 * 60, 0.05),
pumpTempBasalType = PumpTempBasalType.Absolute,
tbrSettings = DoseSettings(0.01, 30, 24 * 60, 0.0, 6.0),
specialBasalDurations = PumpCapability.BasalRate_Duration30minAllowed,
baseBasalMinValue = 0.05,
baseBasalMaxValue = 3.0,
baseBasalStep = 0.01,
baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.DanaWithHistoryCapabilities);
val description: String
var manufacturer: ManufacturerType? = null
@ -444,5 +460,6 @@ enum class PumpType {
YPSOPUMP -> InterfaceIDs.PumpType.YPSOPUMP
MDI -> InterfaceIDs.PumpType.MDI
USER -> InterfaceIDs.PumpType.USER
DIACONN_G8 -> InterfaceIDs.PumpType.DIACONN_G8
}
}

View file

@ -43,6 +43,7 @@ data class InterfaceIDs(
TANDEM_T_SLIM_X2,
YPSOPUMP,
MDI,
DIACONN_G8,
USER;
companion object {

30
diaconn/build.gradle Normal file
View file

@ -0,0 +1,30 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'com.hiya.jacoco-android'
apply from: "${project.rootDir}/gradle/android_dependencies.gradle"
apply from: "${project.rootDir}/gradle/android_module_dependencies.gradle"
apply from: "${project.rootDir}/gradle/test_dependencies.gradle"
android {
defaultConfig {
versionCode 1
versionName "1.0"
kapt {
arguments {
arg("room.incremental", "true")
arg("room.schemaLocation", "$projectDir/schemas")
}
}
}
}
dependencies {
implementation project(':core')
api "androidx.room:room-ktx:$room_version"
api "androidx.room:room-runtime:$room_version"
api "androidx.room:room-rxjava2:$room_version"
kapt "androidx.room:room-compiler:$room_version"
}

View file

21
diaconn/proguard-rules.pro vendored Normal file
View file

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View file

@ -0,0 +1,92 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "698b023da2f9efdc0351236c43eb20b6",
"entities": [
{
"tableName": "diaconnHistory",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`timestamp` INTEGER NOT NULL, `code` INTEGER NOT NULL, `value` REAL NOT NULL, `bolusType` TEXT NOT NULL, `stringValue` TEXT NOT NULL, `duration` INTEGER NOT NULL, `dailyBasal` REAL NOT NULL, `dailyBolus` REAL NOT NULL, `alarm` TEXT NOT NULL, PRIMARY KEY(`timestamp`))",
"fields": [
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "code",
"columnName": "code",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "value",
"columnName": "value",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "bolusType",
"columnName": "bolusType",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "stringValue",
"columnName": "stringValue",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "duration",
"columnName": "duration",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "dailyBasal",
"columnName": "dailyBasal",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "dailyBolus",
"columnName": "dailyBolus",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "alarm",
"columnName": "alarm",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"timestamp"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_diaconnHistory_code_timestamp",
"unique": false,
"columnNames": [
"code",
"timestamp"
],
"createSql": "CREATE INDEX IF NOT EXISTS `index_diaconnHistory_code_timestamp` ON `${TABLE_NAME}` (`code`, `timestamp`)"
}
],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '698b023da2f9efdc0351236c43eb20b6')"
]
}
}

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="info.nightscout.androidaps.diaconn">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<application>
<activity android:name="info.nightscout.androidaps.diaconn.activities.DiaconnG8HistoryActivity" />
<activity android:name="info.nightscout.androidaps.diaconn.activities.DiaconnG8UserOptionsActivity" />
<activity android:name="info.nightscout.androidaps.diaconn.activities.DiaconnG8BLEScanActivity">
<intent-filter>
<action android:name="info.nightscout.androidaps.plugins.PumpDiaconnG8.activities.DiaconnG8BLEScanActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service android:name="info.nightscout.androidaps.diaconn.service.DiaconnG8Service"
android:enabled="true"
android:exported="false"/>
</application>
</manifest>

View file

@ -0,0 +1,197 @@
package info.nightscout.androidaps.diaconn
import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.activities.TDDStatsActivity
import info.nightscout.androidaps.diaconn.databinding.DiaconnG8FragmentBinding
import info.nightscout.androidaps.diaconn.events.EventDiaconnG8NewStatus
import info.nightscout.androidaps.events.EventExtendedBolusChange
import info.nightscout.androidaps.events.EventInitializationChanged
import info.nightscout.androidaps.events.EventPumpStatusChanged
import info.nightscout.androidaps.events.EventTempBasalChange
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.interfaces.Pump
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.queue.events.EventQueueChanged
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.WarnColors
import io.reactivex.rxkotlin.plusAssign
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import javax.inject.Inject
class DiaconnG8Fragment : DaggerFragment() {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var commandQueue: CommandQueueProvider
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var sp: SP
@Inject lateinit var warnColors: WarnColors
@Inject lateinit var dateUtil: DateUtil
private var disposable: CompositeDisposable = CompositeDisposable()
private val loopHandler = Handler()
private lateinit var refreshLoop: Runnable
private var _binding: DiaconnG8FragmentBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
init {
refreshLoop = Runnable {
activity?.runOnUiThread { updateGUI() }
loopHandler.postDelayed(refreshLoop, T.mins(1).msecs())
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View {
_binding = DiaconnG8FragmentBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.diaconnG8Pumpstatus.setBackgroundColor(resourceHelper.gc(R.color.colorInitializingBorder))
binding.history.setOnClickListener { startActivity(Intent(context, info.nightscout.androidaps.diaconn.activities.DiaconnG8HistoryActivity::class.java)) }
binding.stats.setOnClickListener { startActivity(Intent(context, TDDStatsActivity::class.java)) }
binding.userOptions.setOnClickListener { startActivity(Intent(context, info.nightscout.androidaps.diaconn.activities.DiaconnG8UserOptionsActivity::class.java)) }
binding.btconnection.setOnClickListener {
aapsLogger.debug(LTag.PUMP, "Clicked connect to pump")
diaconnG8Pump.lastConnection = 0
commandQueue.readStatus("Clicked connect to pump", null)
}
}
@Synchronized
override fun onResume() {
super.onResume()
loopHandler.postDelayed(refreshLoop, T.mins(1).msecs())
disposable += rxBus
.toObservable(EventInitializationChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventDiaconnG8NewStatus::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventExtendedBolusChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventTempBasalChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventQueueChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventPumpStatusChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
when (it.status) {
EventPumpStatusChanged.Status.CONNECTING ->
@Suppress("SetTextI18n")
binding.btconnection.text = "{fa-bluetooth-b spin} ${it.secondsElapsed}s"
EventPumpStatusChanged.Status.CONNECTED ->
@Suppress("SetTextI18n")
binding.btconnection.text = "{fa-bluetooth}"
EventPumpStatusChanged.Status.DISCONNECTED ->
@Suppress("SetTextI18n")
binding.btconnection.text = "{fa-bluetooth-b}"
else -> {}
}
if (it.getStatus(resourceHelper) != "") {
binding.diaconnG8Pumpstatus.text = it.getStatus(resourceHelper)
binding.diaconnG8Pumpstatuslayout.visibility = View.VISIBLE
} else {
binding.diaconnG8Pumpstatuslayout.visibility = View.GONE
}
}, fabricPrivacy::logException)
updateGUI()
}
@Synchronized
override fun onPause() {
super.onPause()
disposable.clear()
loopHandler.removeCallbacks(refreshLoop)
}
@Synchronized
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
@SuppressLint("SetTextI18n")
@Synchronized
fun updateGUI() {
if (_binding == null) return
val pump = diaconnG8Pump
val plugin: Pump = activePlugin.activePump
if (pump.lastConnection != 0L) {
val agoMsec = System.currentTimeMillis() - pump.lastConnection
val agoMin = (agoMsec.toDouble() / 60.0 / 1000.0).toInt()
binding.lastconnection.text = dateUtil.timeString(pump.lastConnection) + " (" + resourceHelper.gs(R.string.minago, agoMin) + ")"
warnColors.setColor(binding.lastconnection, agoMin.toDouble(), 16.0, 31.0)
}
if (pump.lastBolusTime != 0L) {
val agoMsec = System.currentTimeMillis() - pump.lastBolusTime
val agoHours = agoMsec.toDouble() / 60.0 / 60.0 / 1000.0
if (agoHours < 6)
// max 6h back
binding.lastbolus.text = dateUtil.timeString(pump.lastBolusTime) + " " + dateUtil.sinceString(pump.lastBolusTime, resourceHelper) + " " + resourceHelper.gs(R.string.formatinsulinunits, pump.lastBolusAmount)
else
binding.lastbolus.text = ""
}
binding.dailyunits.text = resourceHelper.gs(R.string.reservoirvalue, (pump.todayBaseAmount + pump.todaySnackAmount + pump.todayMealAmount), ((pump.maxBasal.toInt() * 24) + pump.maxBolusePerDay.toInt()))
warnColors.setColor(binding.dailyunits, pump.baseInjAmount, pump.baseAmount * 0.75, pump.baseAmount * 0.9)
binding.basabasalrate.text = pump.baseInjAmount.toString() +" / "+ resourceHelper.gs(R.string.pump_basebasalrate, plugin.baseBasalRate)
binding.tempbasal.text = diaconnG8Pump.temporaryBasalToString()
binding.extendedbolus.text = diaconnG8Pump.extendedBolusToString()
binding.reservoir.text = resourceHelper.gs(R.string.reservoirvalue, pump.systemRemainInsulin, 307)
warnColors.setColorInverse(binding.reservoir, pump.systemRemainInsulin , 50.0, 20.0)
binding.battery.text = "{fa-battery-" + pump.systemRemainBattery / 25 + "}" + " ("+ pump.systemRemainBattery + " %)"
warnColors.setColorInverse(binding.battery, pump.systemRemainBattery.toDouble(), 51.0, 26.0)
//binding.tdd.text = "basal: " +pump.todayBaseAmount + "/ bolus: "+ (pump.todaySnackAmount + pump.todayMealAmount)
binding.firmware.text = resourceHelper.gs(R.string.diaconn_g8_pump) + "\nVersion: " + pump.majorVersion.toString() + "." + pump.minorVersion.toString() + "\nCountry: "+pump.country.toString() + "\nProductType: "+ pump.productType.toString() + "\nManufacture: " + pump.makeYear + "." + pump.makeMonth + "." + pump.makeDay
binding.basalstep.text = pump.basalStep.toString()
binding.bolusstep.text = pump.bolusStep.toString()
binding.serialNumber.text = pump.serialNo.toString()
val status = commandQueue.spannedStatus()
if (status.toString() == "") {
binding.queue.visibility = View.GONE
} else {
binding.queue.visibility = View.VISIBLE
binding.queue.text = status
}
binding.userOptions.visibility = View.VISIBLE
}
}

View file

@ -0,0 +1,583 @@
package info.nightscout.androidaps.diaconn
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.IBinder
import android.text.format.DateFormat
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.diaconn.events.EventDiaconnG8DeviceChange
import info.nightscout.androidaps.diaconn.service.DiaconnG8Service
import info.nightscout.androidaps.events.EventAppExit
import info.nightscout.androidaps.events.EventConfigBuilderChange
import info.nightscout.androidaps.extensions.convertedToAbsolute
import info.nightscout.androidaps.extensions.plannedRemainingMinutes
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.common.ManufacturerType
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction
import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage
import info.nightscout.androidaps.plugins.pump.common.bolusInfo.TemporaryBasalStorage
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import org.json.JSONException
import org.json.JSONObject
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.abs
import kotlin.math.max
@Singleton
class DiaconnG8Plugin @Inject constructor(
injector: HasAndroidInjector,
aapsLogger: AAPSLogger,
private val rxBus: RxBusWrapper,
private val context: Context,
resourceHelper: ResourceHelper,
private val constraintChecker: ConstraintChecker,
private val profileFunction: ProfileFunction,
private val sp: SP,
commandQueue: CommandQueueProvider,
private val diaconnG8Pump: DiaconnG8Pump,
private val pumpSync: PumpSync,
private val detailedBolusInfoStorage: DetailedBolusInfoStorage,
private val temporaryBasalStorage: TemporaryBasalStorage,
private val fabricPrivacy: FabricPrivacy,
private val dateUtil: DateUtil
) : PumpPluginBase(PluginDescription()
.mainType(PluginType.PUMP)
.fragmentClass(DiaconnG8Fragment::class.java.name)
.pluginIcon(R.drawable.ic_diaconn_g8)
.pluginName(R.string.diaconn_g8_pump)
.shortName(R.string.diaconn_g8_pump_shortname)
.preferencesId(R.xml.pref_diaconn)
.description(R.string.description_pump_diaconn_g8),
injector, aapsLogger, resourceHelper, commandQueue
), Pump, Diaconn, Constraints {
private val disposable = CompositeDisposable()
private var diaconnG8Service: DiaconnG8Service? = null
private var mDeviceAddress = ""
var mDeviceName = ""
override val pumpDescription = PumpDescription(PumpType.DIACONN_G8)
override fun onStart() {
super.onStart()
val intent = Intent(context, DiaconnG8Service::class.java)
context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE)
disposable.add(rxBus
.toObservable(EventAppExit::class.java)
.observeOn(Schedulers.io())
.subscribe({ context.unbindService(mConnection) }) { fabricPrivacy.logException(it) }
)
disposable.add(rxBus
.toObservable(EventConfigBuilderChange::class.java)
.observeOn(Schedulers.io())
.subscribe { diaconnG8Pump.reset() }
)
disposable.add(rxBus
.toObservable(EventDiaconnG8DeviceChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ changePump() }) { fabricPrivacy.logException(it) }
)
changePump() // load device name
}
override fun onStop() {
context.unbindService(mConnection)
disposable.clear()
super.onStop()
}
private val mConnection: ServiceConnection = object : ServiceConnection {
override fun onServiceDisconnected(name: ComponentName) {
aapsLogger.debug(LTag.PUMP, "Service is disconnected")
diaconnG8Service = null
}
override fun onServiceConnected(name: ComponentName, service: IBinder) {
aapsLogger.debug(LTag.PUMP, "Service is connected")
val mLocalBinder = service as DiaconnG8Service.LocalBinder
diaconnG8Service = mLocalBinder.serviceInstance
}
}
fun changePump() {
mDeviceAddress = sp.getString(R.string.key_diaconn_g8_address, "")
mDeviceName = sp.getString(R.string.key_diaconn_g8_name, "")
diaconnG8Pump.reset()
commandQueue.readStatus("DeviceChanged", null)
}
override fun connect(reason: String) {
aapsLogger.debug(LTag.PUMP, "Diaconn G8 connect from: $reason")
if(diaconnG8Service != null && mDeviceAddress != "" && mDeviceName != "") {
val success = diaconnG8Service?.connect(reason, mDeviceAddress) ?: false
if(!success) ToastUtils.showToastInUiThread(context, resourceHelper.gs(R.string.ble_not_supported))
}
}
override fun isConnected(): Boolean = diaconnG8Service?.isConnected ?: false
override fun isConnecting(): Boolean = diaconnG8Service?.isConnecting ?: false
override fun isHandshakeInProgress(): Boolean = false
override fun disconnect(reason: String) {
aapsLogger.debug(LTag.PUMP, "Diaconn G8 disconnect from: $reason")
diaconnG8Service?.disconnect(reason)
}
override fun stopConnecting() {
diaconnG8Service?.stopConnecting()
}
override fun getPumpStatus(reason: String) {
diaconnG8Service?.readPumpStatus()
pumpDescription.basalStep = diaconnG8Pump.basalStep
pumpDescription.bolusStep = diaconnG8Pump.bolusStep
pumpDescription.basalMaximumRate = diaconnG8Pump.maxBasalPerHours
}
// Diaconn Pump Interface
override fun loadHistory(): PumpEnactResult {
return diaconnG8Service?.loadHistory() ?: PumpEnactResult(injector).success(false)
}
override fun setUserOptions(): PumpEnactResult {
return diaconnG8Service?.setUserSettings() ?: PumpEnactResult(injector).success(false)
}
// Constraints interface
override fun applyBasalConstraints(absoluteRate: Constraint<Double>, profile: Profile): Constraint<Double> {
absoluteRate.setIfSmaller(aapsLogger, diaconnG8Pump.maxBasal, resourceHelper.gs(R.string.limitingbasalratio, diaconnG8Pump.maxBasal, resourceHelper.gs(R.string.pumplimit)), this)
return absoluteRate
}
override fun applyBasalPercentConstraints(percentRate: Constraint<Int>, profile: Profile): Constraint<Int> {
percentRate.setIfGreater(aapsLogger, 0, resourceHelper.gs(R.string.limitingpercentrate, 0, resourceHelper.gs(R.string.itmustbepositivevalue)), this)
percentRate.setIfSmaller(aapsLogger, pumpDescription.maxTempPercent, resourceHelper.gs(R.string.limitingpercentrate, pumpDescription.maxTempPercent, resourceHelper.gs(R.string.pumplimit)), this)
return percentRate
}
override fun applyBolusConstraints(insulin: Constraint<Double>): Constraint<Double> {
insulin.setIfSmaller(aapsLogger, diaconnG8Pump.maxBolus, resourceHelper.gs(R.string.limitingbolus, diaconnG8Pump.maxBolus, resourceHelper.gs(R.string.pumplimit)), this)
return insulin
}
override fun applyExtendedBolusConstraints(insulin: Constraint<Double>): Constraint<Double> {
return applyBolusConstraints(insulin)
}
// Pump interface
override fun isInitialized(): Boolean =
diaconnG8Pump.lastConnection > 0 && diaconnG8Pump.maxBasal > 0
override fun isSuspended(): Boolean =
diaconnG8Pump.basePauseStatus == 1
override fun isBusy(): Boolean =
diaconnG8Service?.isConnected ?: false || diaconnG8Service?.isConnecting ?: false
override fun setNewBasalProfile(profile: Profile): PumpEnactResult {
val result = PumpEnactResult(injector)
if (!isInitialized()) {
val notification = Notification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED, resourceHelper.gs(R.string.pumpNotInitializedProfileNotSet), Notification.URGENT)
rxBus.send(EventNewNotification(notification))
result.comment = resourceHelper.gs(R.string.pumpNotInitializedProfileNotSet)
return result
} else {
rxBus.send(EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED))
}
return if (diaconnG8Service?.updateBasalsInPump(profile) != true) {
val notification = Notification(Notification.FAILED_UPDATE_PROFILE, resourceHelper.gs(R.string.failedupdatebasalprofile), Notification.URGENT)
rxBus.send(EventNewNotification(notification))
result.comment = resourceHelper.gs(R.string.failedupdatebasalprofile)
result
} else {
rxBus.send(EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED))
rxBus.send(EventDismissNotification(Notification.FAILED_UPDATE_PROFILE))
val notification = Notification(Notification.PROFILE_SET_OK, resourceHelper.gs(R.string.profile_set_ok), Notification.INFO, 60)
rxBus.send(EventNewNotification(notification))
result.success = true
result.enacted = true
result.comment = "OK"
result
}
}
override fun isThisProfileSet(profile: Profile): Boolean {
if (!isInitialized()) return true // TODO: not sure what's better. so far TRUE to prevent too many SMS
if (diaconnG8Pump.pumpProfiles == null) return true // TODO: not sure what's better. so far TRUE to prevent too many SMS
val basalValues = 24
val basalIncrement = 60 * 60
for (h in 0 until basalValues) {
val pumpValue = diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][h]
val profileValue = profile.getBasalTimeFromMidnight(h * basalIncrement)
if (abs(pumpValue - profileValue) > pumpDescription.basalStep) {
aapsLogger.debug(LTag.PUMP, "Diff found. Hour: $h Pump: $pumpValue Profile: $profileValue")
return false
}
}
return true
}
override fun lastDataTime(): Long = diaconnG8Pump.lastConnection
override val baseBasalRate: Double
get() = diaconnG8Pump.baseAmount
override val reservoirLevel: Double
get() = diaconnG8Pump.systemRemainInsulin
override val batteryLevel: Int
get() = diaconnG8Pump.systemRemainBattery
@Synchronized
override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult {
detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(Constraint(detailedBolusInfo.insulin)).value()
return if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
val carbs = detailedBolusInfo.carbs
detailedBolusInfo.carbs = 0.0
var carbTimeStamp = detailedBolusInfo.carbsTimestamp ?: detailedBolusInfo.timestamp
if (carbTimeStamp == detailedBolusInfo.timestamp) carbTimeStamp -= T.mins(1).msecs() // better set 1 min back to prevents clash with insulin
detailedBolusInfoStorage.add(detailedBolusInfo) // will be picked up on reading history
val t = EventOverviewBolusProgress.Treatment(0.0, 0, detailedBolusInfo.bolusType == DetailedBolusInfo.BolusType.SMB)
var connectionOK = false
if (detailedBolusInfo.insulin > 0 || carbs > 0) connectionOK = diaconnG8Service?.bolus(detailedBolusInfo.insulin, carbs.toInt(), carbTimeStamp, t)
?: false
val result = PumpEnactResult(injector)
result.success = connectionOK
result.bolusDelivered = t.insulin
result.carbsDelivered = detailedBolusInfo.carbs
if(result.success) result.enacted = true
if (!result.success) {
setErrorMsg(diaconnG8Pump.bolusStartErrorCode, result)
} else result.comment = resourceHelper.gs(R.string.ok)
aapsLogger.debug(LTag.PUMP, "deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.bolusDelivered)
result
} else {
val result = PumpEnactResult(injector)
result.success = false
result.bolusDelivered = 0.0
result.carbsDelivered = 0.0
result.comment = resourceHelper.gs(R.string.invalidinput)
aapsLogger.error("deliverTreatment: Invalid input")
result
}
}
override fun stopBolusDelivering() {
diaconnG8Service?.bolusStop()
}
// This is called from APS
@Synchronized
override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult {
val result = PumpEnactResult(injector)
var absoluteAfterConstrain = constraintChecker.applyBasalConstraints(Constraint(absoluteRate), profile).value()
val doTempOff = baseBasalRate - absoluteAfterConstrain == 0.0
val doLowTemp = absoluteAfterConstrain < baseBasalRate
val doHighTemp = absoluteAfterConstrain > baseBasalRate
if (doTempOff) {
// If temp in progress
if (diaconnG8Pump.isTempBasalInProgress) {
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Stopping temp basal (doTempOff)")
return cancelTempBasal(false)
}
result.success = true
result.enacted = false
result.absolute = baseBasalRate
result.isPercent = false
result.isTempCancel = true
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: doTempOff OK")
return result
}
if (doLowTemp || doHighTemp) {
// Check if some temp is already in progress
if(absoluteAfterConstrain > 6.0) absoluteAfterConstrain = 6.0 // pumpLimit
//val activeTemp = activePluginProvider.activeTreatments.getTempBasalFromHistory(System.currentTimeMillis())
if (diaconnG8Pump.isTempBasalInProgress) {
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: currently running")
// Correct basal already set ?
if (diaconnG8Pump.tempBasalAbsoluteRate == absoluteAfterConstrain && diaconnG8Pump.tempBasalRemainingMin > 4) {
if (!enforceNew) {
result.success = true
result.absolute = absoluteAfterConstrain
result.enacted = false
result.duration = diaconnG8Pump.tempBasalRemainingMin
result.isPercent = false
result.isTempCancel = false
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Correct temp basal already set (doLowTemp || doHighTemp)")
return result
}
}
}
temporaryBasalStorage.add(PumpSync.PumpState.TemporaryBasal(dateUtil.now(), T.mins(durationInMinutes.toLong()).msecs(), absoluteRate, true, tbrType, 0L, 0L))
// Convert duration from minutes to hours
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Setting temp basal $absoluteAfterConstrain% for $durationInMinutes mins (doLowTemp || doHighTemp)")
val connectionOK: Boolean = if (durationInMinutes == 15 || durationInMinutes == 30) {
diaconnG8Service?.tempBasalShortDuration(absoluteAfterConstrain, durationInMinutes) ?: false
} else {
val durationInHours = max(durationInMinutes / 60, 1)
diaconnG8Service?.tempBasal(absoluteAfterConstrain, durationInHours) ?: false
}
if (connectionOK && diaconnG8Pump.isTempBasalInProgress && diaconnG8Pump.tempBasalAbsoluteRate == absoluteAfterConstrain) {
result.enacted = true
result.success = true
result.comment = resourceHelper.gs(R.string.ok)
result.isTempCancel = false
result.duration = diaconnG8Pump.tempBasalRemainingMin
result.absolute = diaconnG8Pump.tempBasalAbsoluteRate
result.isPercent = false
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: OK")
return result
}
}
result.enacted = false
result.success = false
result.comment = resourceHelper.gs(R.string.tempbasaldeliveryerror)
aapsLogger.error("setTempBasalAbsolute: Failed to set temp basal")
return result
}
@Synchronized
override fun setTempBasalPercent(percent: Int, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult {
return if (percent == 0) {
setTempBasalAbsolute(0.0, durationInMinutes, profile, enforceNew, tbrType)
} else {
var absoluteValue = profile.getBasal() * (percent / 100.0)
absoluteValue = pumpDescription.pumpType.determineCorrectBasalSize(absoluteValue)
aapsLogger.warn(LTag.PUMP, "setTempBasalPercent [DiaconnG8Plugin] - 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.")
setTempBasalAbsolute(absoluteValue, durationInMinutes, profile, enforceNew, tbrType)
}
}
@Synchronized
override fun setExtendedBolus(insulin: Double, durationInMinutes: Int): PumpEnactResult {
var insulinAfterConstraint = constraintChecker.applyExtendedBolusConstraints(Constraint(insulin)).value()
// needs to be rounded
//val durationInHalfHours = max(durationInMinutes / 30, 1)
insulinAfterConstraint = Round.roundTo(insulinAfterConstraint, pumpDescription.extendedBolusStep)
val result = PumpEnactResult(injector)
if (diaconnG8Pump.isExtendedInProgress && abs(diaconnG8Pump.extendedBolusAmount - insulinAfterConstraint) < pumpDescription.extendedBolusStep) {
result.enacted = false
result.success = true
result.comment = resourceHelper.gs(R.string.ok)
result.duration = diaconnG8Pump.extendedBolusRemainingMinutes
result.absolute = diaconnG8Pump.extendedBolusAbsoluteRate
result.isPercent = false
result.isTempCancel = false
aapsLogger.debug(LTag.PUMP, "setExtendedBolus: Correct extended bolus already set. Current: " + diaconnG8Pump.extendedBolusAmount + " Asked: " + insulinAfterConstraint)
return result
}
val connectionOK = diaconnG8Service?.extendedBolus(insulinAfterConstraint, durationInMinutes)
?: false
if (connectionOK) {
result.enacted = true
result.success = true
result.comment = resourceHelper.gs(R.string.ok)
result.isTempCancel = false
result.duration = diaconnG8Pump.extendedBolusRemainingMinutes
result.absolute = diaconnG8Pump.extendedBolusAbsoluteRate
result.bolusDelivered = diaconnG8Pump.extendedBolusAmount
result.isPercent = false
aapsLogger.debug(LTag.PUMP, "setExtendedBolus: OK")
return result
}
result.enacted = false
result.success = false
setErrorMsg(diaconnG8Pump.bolusStartErrorCode, result)
aapsLogger.error("setExtendedBolus: Failed to extended bolus")
return result
}
@Synchronized
override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult {
val result = PumpEnactResult(injector)
if (diaconnG8Pump.isTempBasalInProgress) {
diaconnG8Service?.tempBasalStop()
result.success = !diaconnG8Pump.isTempBasalInProgress
result.enacted = true
result.isTempCancel = true
} else {
result.success = true
result.enacted = false
result.isTempCancel = true
result.comment = resourceHelper.gs(R.string.ok)
aapsLogger.debug(LTag.PUMP, "cancelRealTempBasal: OK")
}
return result
}
@Synchronized override fun cancelExtendedBolus(): PumpEnactResult {
val result = PumpEnactResult(injector)
if (diaconnG8Pump.isExtendedInProgress) {
diaconnG8Service?.extendedBolusStop()
result.success = !diaconnG8Pump.isExtendedInProgress
result.enacted = true
} else {
result.success = true
result.enacted = false
result.comment = resourceHelper.gs(R.string.ok)
aapsLogger.debug(LTag.PUMP, "cancelExtendedBolus: OK")
}
return result
}
override fun getJSONStatus(profile: Profile, profileName: String, version: String): JSONObject {
val now = System.currentTimeMillis()
if (diaconnG8Pump.lastConnection + 60 * 60 * 1000L < System.currentTimeMillis()) {
return JSONObject()
}
val pumpJson = JSONObject()
val battery = JSONObject()
val status = JSONObject()
val extended = JSONObject()
try {
battery.put("percent", diaconnG8Pump.systemRemainBattery)
status.put("status", if (diaconnG8Pump.pumpSuspended) "suspended" else "normal")
status.put("timestamp", dateUtil.toISOString(diaconnG8Pump.lastConnection))
extended.put("Version", version)
if (diaconnG8Pump.lastBolusTime != 0L) {
extended.put("LastBolus", dateUtil.dateAndTimeString(diaconnG8Pump.lastBolusTime))
extended.put("LastBolusAmount", diaconnG8Pump.lastBolusAmount)
}
val tb = pumpSync.expectedPumpState().temporaryBasal
if (tb != null) {
extended.put("TempBasalAbsoluteRate", tb.convertedToAbsolute(now, profile))
extended.put("TempBasalStart", dateUtil.dateAndTimeString(tb.timestamp))
extended.put("TempBasalRemaining", tb.plannedRemainingMinutes)
}
val eb = pumpSync.expectedPumpState().extendedBolus
if (eb != null) {
extended.put("ExtendedBolusAbsoluteRate", eb.rate)
extended.put("ExtendedBolusStart", dateUtil.dateAndTimeString(eb.timestamp))
extended.put("ExtendedBolusRemaining", eb.plannedRemainingMinutes)
}
extended.put("BaseBasalRate", baseBasalRate)
try {
extended.put("ActiveProfile", profileFunction.getProfileName())
} catch (e: Exception) {
aapsLogger.error("Unhandled exception", e)
}
pumpJson.put("battery", battery)
pumpJson.put("status", status)
pumpJson.put("extended", extended)
pumpJson.put("reservoir", diaconnG8Pump.systemRemainInsulin.toInt())
pumpJson.put("clock", dateUtil.toISOString(now))
} catch (e: JSONException) {
aapsLogger.error("Unhandled exception", e)
}
return pumpJson
}
override fun manufacturer(): ManufacturerType {
return ManufacturerType.G2e
}
override fun model(): PumpType {
return PumpType.DIACONN_G8
}
override fun serialNumber(): String {
return diaconnG8Pump.serialNo.toString()
}
override fun shortStatus(veryShort: Boolean): String {
var ret = ""
if (diaconnG8Pump.lastConnection != 0L) {
val agoMillis = System.currentTimeMillis() - diaconnG8Pump.lastConnection
val agoMin = (agoMillis / 60.0 / 1000.0).toInt()
ret += "LastConn: $agoMin minago\n"
}
if (diaconnG8Pump.lastBolusTime != 0L)
ret += "LastBolus: ${DecimalFormatter.to2Decimal(diaconnG8Pump.lastBolusAmount)}U @${DateFormat.format("HH:mm", diaconnG8Pump.lastBolusTime)}"
if (diaconnG8Pump.isTempBasalInProgress)
ret += "Temp: ${diaconnG8Pump.temporaryBasalToString()}"
if (diaconnG8Pump.isExtendedInProgress)
ret += "Extended: ${diaconnG8Pump.extendedBolusToString()}\n"
if (!veryShort) {
ret += "TDD: ${DecimalFormatter.to0Decimal(diaconnG8Pump.dailyTotalUnits)} / ${diaconnG8Pump.maxDailyTotalUnits} U"
}
ret += "Reserv: ${DecimalFormatter.to0Decimal(diaconnG8Pump.systemRemainInsulin)} U"
ret += "Batt: ${diaconnG8Pump.systemRemainBattery}"
return ret
}
override val isFakingTempsByExtendedBoluses: Boolean = false
override fun loadTDDs(): PumpEnactResult = loadHistory()
override fun getCustomActions(): List<CustomAction>? = null
override fun executeCustomAction(customActionType: CustomActionType) {}
override fun canHandleDST(): Boolean = false
fun isBatteryChangeLoggingEnabled():Boolean {
return sp.getBoolean(R.string.key_diaconn_g8_logbatterychange, false)
}
fun isInsulinChangeLoggingEnabled():Boolean {
return sp.getBoolean(R.string.key_diaconn_g8_loginsulinchange, false)
}
@Synchronized
fun setErrorMsg(errorCode: Int, result: PumpEnactResult) {
when (errorCode) {
1 -> result.comment = resourceHelper.gs(R.string.diaconn_g8_errorcode_1)
2 -> result.comment = resourceHelper.gs(R.string.diaconn_g8_errorcode_2)
3 -> result.comment = resourceHelper.gs(R.string.diaconn_g8_errorcode_3)
4 -> result.comment = resourceHelper.gs(R.string.diaconn_g8_errorcode_4)
6 -> result.comment = resourceHelper.gs(R.string.diaconn_g8_errorcode_6)
7 -> result.comment = resourceHelper.gs(R.string.diaconn_g8_errorcode_7)
8 -> result.comment = resourceHelper.gs(R.string.diaconn_g8_errorcode_8)
9 -> result.comment = resourceHelper.gs(R.string.diaconn_g8_errorcode_9)
10 -> result.comment = resourceHelper.gs(R.string.diaconn_g8_errorcode_10)
11 -> result.comment = resourceHelper.gs(R.string.diaconn_g8_errorcode_11)
12 -> result.comment = resourceHelper.gs(R.string.diaconn_g8_errorcode_12)
13 -> result.comment = resourceHelper.gs(R.string.diaconn_g8_errorcode_13)
14 -> result.comment = resourceHelper.gs(R.string.diaconn_g8_errorcode_14)
15 -> result.comment = resourceHelper.gs(R.string.diaconn_g8_errorcode_15)
else -> result.comment = "not defined Error code: $errorCode"
}
}
override fun preprocessPreferences(preferenceFragment: PreferenceFragmentCompat) {
val bolusSpeedPreference: Preference? = preferenceFragment.findPreference(resourceHelper.gs(R.string.key_diaconn_g8_bolusspeed))
bolusSpeedPreference?.setOnPreferenceChangeListener { _, newValue ->
val intBolusSpeed = newValue.toString().toInt()
diaconnG8Pump.bolusSpeed = intBolusSpeed
diaconnG8Pump.speed = intBolusSpeed
diaconnG8Pump.setUserOptionType = DiaconnG8Pump.BOLUS_SPEED
sp.putBoolean("diaconn_g8_isbolusspeedsync", false)
true
}
}
}

View file

@ -0,0 +1,333 @@
package info.nightscout.androidaps.diaconn
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.T
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.max
import kotlin.math.min
import kotlin.math.roundToInt
@Singleton
class DiaconnG8Pump @Inject constructor(
private val aapsLogger: AAPSLogger,
private val dateUtil: DateUtil
) {
var maxBolusePerDay: Double = 0.0
var pumpIncarnationNum: Int = 65536
var isPumpVersionGe2_63: Boolean = false // is pumpVersion higher then 2.63
var insulinWarningGrade: Int =0
var insulinWarningProcess: Int =0
var insulinWarningRemain: Int =0
var batteryWaningGrade: Int = 0
var batteryWaningProcess: Int = 0
var batteryWaningRemain: Int = 0
var injectionBlockType: Int =0
var injectionBlockRemainAmount: Double = 0.0
var injectionBlockProcess: Int = 0
var injectionBlockGrade: Int = 0
var lastConnection: Long = 0
var lastSettingsRead: Long = 0
// time
private var pumpTime: Long = 0
fun setPumpTime(value: Long) {
pumpTime = value
}
fun getPumpTime() = pumpTime
// Status
var pumpSuspended = false
var dailyTotalUnits = 0.0
var maxDailyTotalUnits = 0
var bolusStep = 0.01
var basalStep = 0.01
var iob = 0.0
var bolusBlocked = false
var lastBolusTime: Long = 0
var lastBolusAmount = 0.0
var extendedBolusMinutes = 0
var extendedBolusSoFarInMinutes = 0
var extendedBolusDeliveredSoFar = 0.0
/*
* TEMP BASALS
*/
var isTempBasalInProgress = false
var tempBasalPercent = 0
var tempBasalStart: Long = 0
var tempBasalAbsoluteRate: Double = 0.0
var tempBasalDuration: Long = 0
val tempBasalRemainingMin: Int
get() = max(tbElapsedTime, 0)
fun temporaryBasalToString(): String {
if (!isTempBasalInProgress) return ""
return tempBasalAbsoluteRate.toString() + "U @" +
dateUtil.timeString(tempBasalStart) +
" " + tbElapsedTime + "/" + T.msecs(tempBasalDuration).mins() + "'"
}
fun fromTemporaryBasal(tbr: PumpSync.PumpState.TemporaryBasal?) {
if (tbr == null) {
tempBasalStart = 0
tempBasalDuration = 0
tempBasalAbsoluteRate = 0.0
} else {
tempBasalStart = tbr.timestamp
tempBasalDuration = tbr.duration
tempBasalAbsoluteRate = tbr.rate
}
}
/*
* EXTENDED BOLUSES
*/
var extendedBolusStart: Long = 0
var extendedBolusDuration: Long = 0
var extendedBolusAmount = 0.0
var isExtendedInProgress:Boolean = false
var extendedBolusPassedMinutes = 0
var extendedBolusRemainingMinutes = 0
var extendedBolusAbsoluteRate = 0.0
fun extendedBolusToString(): String {
if (!isExtendedInProgress) return ""
return "E "+ DecimalFormatter.to2Decimal(extendedBolusDeliveredSoFar) +"/" + DecimalFormatter.to2Decimal(extendedBolusAbsoluteRate) + "U/h @" +
dateUtil.timeString(extendedBolusStart) +
" " + extendedBolusPassedMinutes + "/" + extendedBolusMinutes + "'"
}
fun fromExtendedBolus(eb: PumpSync.PumpState.ExtendedBolus?) {
if (eb == null) {
extendedBolusStart = 0
extendedBolusDuration = 0
extendedBolusAmount = 0.0
} else {
extendedBolusStart = eb.timestamp
extendedBolusDuration = eb.duration
extendedBolusAmount = eb.amount
}
}
// Profile
var units = 0
var activeProfile = 0
var pumpProfiles: Array<Array<Double>>? = null
//Limits
var maxBolus = 0.0
var maxBasal = 0.0
// User settings
var setUserOptionType = 0 // ALARM:0, LCD:1, LANG:2, BOLUS_SPEED:3
var beepAndAlarm = 0
var alarmIntesity = 0
var lcdOnTimeSec = 0
var selectedLanguage = 0
var bolusSpeed = 0
// Bolus settings
var bolusStartErrorCode: Int = 0 // last start bolus erroCode
var historyDoneReceived: Boolean = false // true when last history message is received
var bolusingTreatment: EventOverviewBolusProgress.Treatment? = null // actually delivered treatment
var bolusAmountToBeDelivered = 0.0 // amount to be delivered
var bolusProgressLastTimeStamp: Long = 0 // timestamp of last bolus progress message
var bolusStopped = false // bolus finished
var bolusStopForced = false // bolus forced to stop by user
var bolusDone = false // success end
fun buildDiaconnG8ProfileRecord(nsProfile: Profile): Array<Double> {
val record = Array(24) { 0.0 }
for (hour in 0..23) {
//Some values get truncated to the next lower one.
// -> round them to two decimals and make sure we are a small delta larger (that will get truncated)
val value = (100.0 * nsProfile.getBasalTimeFromMidnight((hour * 60 * 60))).roundToInt() / 100.0 + 0.00001
aapsLogger.debug(LTag.PUMP, "NS basal value for $hour:00 is $value")
record[hour] = value
//aapsLogger.debug(LTag.PUMP, "NS basal value * 100 for $hour:00 is $value")
}
return record
}
fun reset() {
aapsLogger.debug(LTag.PUMP, "Diaconn G8 Pump reset")
lastConnection = 0
lastSettingsRead = 0
}
// G8 pump
var result:Int = 0 // 조회결과
// 1. pump setting info
var systemRemainInsulin = 0.0 // 인슐린 잔량
var systemRemainBattery = 0 // 배터리 잔량(0~100%)
var systemBasePattern = 0 // 기저주입 패턴(0=없음, 1=기본, 2=생활1, 3=생활2, 4=생활3, 5=닥터1, 6=닥터2)
var systemTbStatus = 0 // 임시기저 상태(1=임시기저 중, 2=임시기저 해제)
var systemInjectionMealStatus = 0 // 식사주입 상태(1=주입중, 2=주입상태아님)
var systemInjectionSnackStatus = 0 // 일반간식 주입 상태(1=주입중, 2=주입상태아님)
var systemInjectionSquareStatue = 0 // 스퀘어회식 주입 상태(1=주입중, 2=주입상태아님)
var systemInjectionDualStatus = 0 // 더블회식 주입 상태(1=주입중, 2=주입상태아님)
// 2. basal injection suspend status (1:stop, 2:release)
var basePauseStatus = 0 // 상태(1=정지,2=해제)
// 3. Pump time
var year = 0 // 년 (18~99)
var month = 0 // 월 (1~12)
var day = 0 // 일 (1~31)
var hour = 0 // 시 (0~23)
var minute = 0 // 분 (0~59)
var second = 0 // 초 (0~59)
// 4. pump system info
var country = 0 // 생산국(K, C), ASCII
var productType = 0 // 제품종류(A ~ Z), ASCII
var makeYear = 0 // 제조년
var makeMonth = 0 // 제조월
var makeDay = 0 // 제조일
var lotNo = 0 // LOT NO
var serialNo = 0 // SERIAL NO
var majorVersion = 0 // Major 버전
var minorVersion = 0 // Minor 버전
// 5. pump log status
var pumpLastLogNum = 0 // 마지막 저장 로그 번호(0~9999)
var pumpWrappingCount = 0 // wrapping 카운트(0~255)
var apslastLogNum = 0 // 앱에서 처리한 마지막 로그 번호.
var apsWrappingCount = 0 // 앱에서 처리한 마지막 로그 번호.
var isProgressPumpLogSync = false // 로그 동기화 진행 여부
// 6. bolus speed status.
var speed = 0 // 주입 속도(1 ~ 8)
var maxBasalPerHours = 0.0
// 7. Tempbasal status
var tbStatus = 0 // 임시기저 상태
var tbTime = 0 // 임시기저 시간
var tbInjectRateRatio = 0 // 임시기저 주입량/률 1000(0.00U)~1600(6.00U), 50000(0%)~50200(200%), 50000이상이면 주입률로 판정
var tbElapsedTime = 0 // 임시기저 경과 시간(0~1425분)
var tbInjectAbsoluteValue = 0.0 // 임시기저 주입량/률 1000(0.00U)~1600(6.00U)
// 8. Basal status
var baseStatus = 0 // 주입상태
var baseHour = 0 // 현재주입시간(0~23)
var baseAmount = 0.0 // 주입설정량(량*100, 23.25->2325, 15.2->1520)
var baseInjAmount = 0.0 // 현재주입량(량*100, 23.25->2325, 15.2->1520)
// 9. meal bolus status
var mealKind = 0 // 주입종류(1=아침,2=점심,3=저녁)
var mealStartTime = 0 // 식사주입 시작시간(time_t)
var mealStatus = 0 // 주입상태(1=주입중,2=주입상태아님)
var mealAmount = 0.0 // 주입설정량(량*100, 23.25->2325, 15.2->1520)
var mealInjAmount = 0.0 // 현재주입량(량*100, 23.25->2325, 15.2->1520)
var mealSpeed = 0 // 주입속도(1~8)
// 10. snack bolus status
var snackStatus = 0 // 주입상태(1=주입중,2=주입상태아님)
var snackAmount = 0.0 // 주입설정량(량*100, 23.25->2325, 15.2->1520)
var snackInjAmount = 0.0 // 현재주입량(량*100, 23.25->2325, 15.2->1520)
var snackSpeed = 0 // 주입속도(1~8)
// 11. square(extended) bolus status
var squareStatus = 0 // 주입상태
var squareTime = 0 // 설정 주입시간(10~300분)
var squareInjTime = 0 // 경과 주입시간(10~300분)
var squareAmount = 0.0 // 주입 설정량
var squareInjAmount = 0.0 // 현재 주입량
// 12. daul bolus status
var dualStatus = 0 // 주입상태
var dualAmount = 0.0 // 일반주입 설정량
var dualInjAmount = 0.0 // 일반주입량
var dualSquareTime = 0 // 스퀘어주입 설정시간(10~300분)
var dualInjSquareTime = 0 // 스퀘어주입 경과시간(10~300분)
var dualSquareAmount = 0.0 // 스퀘어주입 설정량
var dualInjSquareAmount = 0.0 // 스퀘어주입량
// 13. last injection status
var recentKind1 = 0 // 최근-1 주입 종류(1=식사, 2=일반간식, 3=스퀘어회식, 4=더블회식)
var recentTime1 = 0 // 최근-1 주입 시간
var recentAmount1 = 0.0 // 최근-1 주입량
var recentKind2 = 0 // 최근-2 주입 종류(1=식사, 2=일반간식, 3=스퀘어회식, 4=더블회식)
var recentTime2 = 0 // 최근-2 주입 시간
var recentAmount2 = 0.0 // 최근-2 주입량
// 14. daily injection status
var todayBaseAmount = 0.0 // 기저주입 총량
var todayMealAmount = 0.0 // 식사주입 총량
var todaySnackAmount = 0.0 // 회식주입 총량
// 15. meat setting status
var morningHour = 0 // 아침 개시 시간(0~23)
var morningAmount = 0.0 // 아침 식전량
var lunchHour = 0 // 점심 개시 시간(0~23)
var lunchAmount = 0.0 // 점심 식전량
var dinnerHour = 0 // 저녁 개시 시간(0~23)
var dinnerAmount = 0.0 // 저녁 식전량
// 16. basal injection status at this hour
var currentBasePattern = 0 // 패턴 종류 (1=기본, 2=생활1, 3=생활2, 4=생활3, 5=닥터1, 6=닥터2)
var currentBaseHour = 0 // 현재주입시간(0~23)
var currentBaseTbBeforeAmount = 0.0 // 해당시간의 임시기저 계산 전 기저주입량: 기저주입막힘 발생 시 기저주입 막힘량 제외, 기저정지로 인해 주입되지 않은 량 제외, 리셋으로 인해 주입되지 않은 량 제외(47.5=4750)
var currentBaseTbAfterAmount = 0.0 // 해당시간의 임시기저 계산 후 기저주입량: 기저주입막힘 발생 시 기저주입 막힘량 제외, 기저정지로 인해 주입되지 않은 량 제외, 리셋으로 인해 주입되지 않은 량 제외(47.5=4750)
// 17. saved basal pattern status
var baseAmount1 = 0.00// 주입량 1(량*100, 23.25->2325, 15.2->1520)
var baseAmount2 = 0.0// 주입량 2(량*100, 23.25->2325, 15.2->1520)
var baseAmount3 = 0.0 // 주입량 3(량*100, 23.25->2325, 15.2->1520)
var baseAmount4 = 0.0 // 주입량 4(량*100, 23.25->2325, 15.2->1520)
var baseAmount5 = 0.0 // 주입량 5(량*100, 23.25->2325, 15.2->1520)
var baseAmount6 = 0.0 // 주입량 6(량*100, 23.25->2325, 15.2->1520)
var baseAmount7 = 0.0 // 주입량 7(량*100, 23.25->2325, 15.2->1520)
var baseAmount8 = 0.0 // 주입량 8(량*100, 23.25->2325, 15.2->1520)
var baseAmount9 = 0.0 // 주입량 9(량*100, 23.25->2325, 15.2->1520)
var baseAmount10 = 0.0 // 주입량 10(량*100, 23.25->2325, 15.2->1520)
var baseAmount11 = 0.0 // 주입량 11(량*100, 23.25->2325, 15.2->1520)
var baseAmount12 = 0.0 // 주입량 12(량*100, 23.25->2325, 15.2->1520)
var baseAmount13 = 0.0 // 주입량 13(량*100, 23.25->2325, 15.2->1520)
var baseAmount14 = 0.0 // 주입량 14(량*100, 23.25->2325, 15.2->1520)
var baseAmount15 = 0.0 // 주입량 15(량*100, 23.25->2325, 15.2->1520)
var baseAmount16 = 0.0 // 주입량 16(량*100, 23.25->2325, 15.2->1520)
var baseAmount17 = 0.0 // 주입량 17(량*100, 23.25->2325, 15.2->1520)
var baseAmount18 = 0.0 // 주입량 18(량*100, 23.25->2325, 15.2->1520)
var baseAmount19 = 0.0 // 주입량 19(량*100, 23.25->2325, 15.2->1520)
var baseAmount20 = 0.0 // 주입량 20(량*100, 23.25->2325, 15.2->1520)
var baseAmount21 = 0.0 // 주입량 21(량*100, 23.25->2325, 15.2->1520)
var baseAmount22 = 0.0 // 주입량 22(량*100, 23.25->2325, 15.2->1520)
var baseAmount23 = 0.0 // 주입량 23(량*100, 23.25->2325, 15.2->1520)
var baseAmount24 = 0.0 // 주입량 24(량*100, 23.25->2325, 15.2->1520)
var otpNumber = 0
companion object {
// User settings
const val ALARM = 0
const val LCD = 1
const val LANG = 2
const val BOLUS_SPEED = 3
}
}

View file

@ -0,0 +1,184 @@
package info.nightscout.androidaps.diaconn.activities
import android.annotation.SuppressLint
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.le.BluetoothLeScanner
import android.bluetooth.le.ScanCallback
import android.bluetooth.le.ScanFilter
import android.bluetooth.le.ScanResult
import android.bluetooth.le.ScanSettings
import android.content.pm.ActivityInfo
import android.os.Bundle
import android.os.Handler
import android.os.ParcelUuid
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.TextView
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
import info.nightscout.androidaps.diaconn.events.EventDiaconnG8DeviceChange
import info.nightscout.androidaps.diaconn.R
import info.nightscout.androidaps.diaconn.databinding.DiaconnG8BlescannerActivityBinding
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.pump.common.ble.BlePreCheck
import info.nightscout.androidaps.utils.sharedPreferences.SP
import java.util.*
import javax.inject.Inject
class DiaconnG8BLEScanActivity : NoSplashAppCompatActivity() {
@Inject lateinit var sp: SP
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var blePreCheck: BlePreCheck
private var listAdapter: ListAdapter? = null
private val devices = ArrayList<BluetoothDeviceItem>()
private var bluetoothLeScanner: BluetoothLeScanner? = null
private val serviceUUID = UUID.fromString("6e400001-b5a3-f393-e0a9-e50e24dcca9e") // BLE GATT Service UUID
private lateinit var binding: DiaconnG8BlescannerActivityBinding
@SuppressLint("SourceLockedOrientationActivity")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DiaconnG8BlescannerActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
blePreCheck.prerequisitesCheck(this)
listAdapter = ListAdapter()
binding.blescannerListview.emptyView = binding.blescannerNodevice
binding.blescannerListview.adapter = listAdapter
listAdapter?.notifyDataSetChanged()
}
override fun onResume() {
super.onResume()
BluetoothAdapter.getDefaultAdapter()?.let { bluetoothAdapter ->
if (!bluetoothAdapter.isEnabled) bluetoothAdapter.enable()
bluetoothLeScanner = bluetoothAdapter.bluetoothLeScanner
startScan()
}
}
override fun onPause() {
super.onPause()
stopScan()
}
private fun startScan() =
try {
val filters: MutableList<ScanFilter> = ArrayList()
val scan_filter = ScanFilter.Builder()
.setServiceUuid(ParcelUuid(serviceUUID))
.build()
filters.add(scan_filter)
val settings = ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build()
bluetoothLeScanner?.startScan(filters, settings, mBleScanCallback)
} catch (e: IllegalStateException) {
} // ignore BT not on
private fun stopScan() =
try {
bluetoothLeScanner?.stopScan(mBleScanCallback)
} catch (e: IllegalStateException) {
} // ignore BT not on
private fun addBleDevice(device: BluetoothDevice?) {
if (device == null || device.name == null || device.name == "") {
return
}
val item = BluetoothDeviceItem(device)
if (devices.contains(item)) {
return
}
devices.add(item)
Handler().post { listAdapter!!.notifyDataSetChanged() }
}
private val mBleScanCallback: ScanCallback = object : ScanCallback() {
override fun onScanResult(callbackType: Int, result: ScanResult) {
addBleDevice(result.device)
}
}
internal inner class ListAdapter : BaseAdapter() {
override fun getCount(): Int = devices.size
override fun getItem(i: Int): BluetoothDeviceItem = devices[i]
override fun getItemId(i: Int): Long = 0
override fun getView(i: Int, convertView: View?, parent: ViewGroup?): View {
var v = convertView
val holder: ViewHolder
if (v == null) {
v = View.inflate(applicationContext, R.layout.diaconn_g8_blescanner_item, null)
holder = ViewHolder(v)
v.tag = holder
} else {
// reuse view if already exists
holder = v.tag as ViewHolder
}
val item = getItem(i)
holder.setData(item)
return v!!
}
private inner class ViewHolder(v: View) : View.OnClickListener {
private lateinit var item: BluetoothDeviceItem
private val name: TextView = v.findViewById(R.id.ble_name)
private val address: TextView = v.findViewById(R.id.ble_address)
init {
v.setOnClickListener(this@ViewHolder)
}
override fun onClick(v: View) {
sp.putString(R.string.key_diaconn_g8_address, item.device.address)
sp.putString(R.string.key_diaconn_g8_name, name.text.toString())
item.device.createBond()
rxBus.send(EventDiaconnG8DeviceChange())
finish()
}
fun setData(data: BluetoothDeviceItem) {
var tTitle = data.device.name
if (tTitle == null || tTitle == "") {
tTitle = "(unknown)"
}
name.text = tTitle
address.text = data.device.address
item = data
}
}
}
//
inner class BluetoothDeviceItem internal constructor(val device: BluetoothDevice) {
override fun equals(other: Any?): Boolean {
if (other !is BluetoothDeviceItem) {
return false
}
return stringEquals(device.address, other.device.address)
}
private fun stringEquals(arg1: String, arg2: String): Boolean {
return try {
arg1 == arg2
} catch (e: Exception) {
false
}
}
override fun hashCode(): Int = device.hashCode()
}
}

View file

@ -0,0 +1,257 @@
package info.nightscout.androidaps.diaconn.activities
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
import info.nightscout.androidaps.diaconn.R
import info.nightscout.androidaps.diaconn.common.RecordTypes
import info.nightscout.androidaps.diaconn.database.DiaconnHistoryRecord
import info.nightscout.androidaps.diaconn.database.DiaconnHistoryRecordDao
import info.nightscout.androidaps.diaconn.databinding.DiaconnG8HistoryActivityBinding
import info.nightscout.androidaps.events.EventPumpStatusChanged
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import java.util.*
import javax.inject.Inject
class DiaconnG8HistoryActivity : NoSplashAppCompatActivity() {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var commandQueue: CommandQueueProvider
@Inject lateinit var diaconnHistoryRecordDao: DiaconnHistoryRecordDao
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var aapsSchedulers: AapsSchedulers
private val disposable = CompositeDisposable()
private var showingType = RecordTypes.RECORD_TYPE_ALARM
private var historyList: List<DiaconnHistoryRecord> = ArrayList()
class TypeList internal constructor(var type: Byte, var name: String) {
override fun toString(): String = name
}
private lateinit var binding: DiaconnG8HistoryActivityBinding
override fun onResume() {
super.onResume()
disposable += rxBus
.toObservable(EventPumpStatusChanged::class.java)
.observeOn(aapsSchedulers.main)
.subscribe({ binding.status.text = it.getStatus(resourceHelper) }) { fabricPrivacy.logException(it) }
swapAdapter(showingType)
}
override fun onPause() {
super.onPause()
disposable.clear()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DiaconnG8HistoryActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.recyclerview.setHasFixedSize(true)
binding.recyclerview.layoutManager = LinearLayoutManager(this)
binding.recyclerview.adapter = RecyclerViewAdapter(historyList)
binding.status.visibility = View.GONE
// Types
val typeList = ArrayList<TypeList>()
typeList.add(TypeList(RecordTypes.RECORD_TYPE_ALARM, resourceHelper.gs(R.string.diaconn_g8_history_alarm)))
typeList.add(TypeList(RecordTypes.RECORD_TYPE_BASALHOUR, resourceHelper.gs(R.string.diaconn_g8_history_basalhours)))
typeList.add(TypeList(RecordTypes.RECORD_TYPE_BOLUS, resourceHelper.gs(R.string.diaconn_g8_history_bolus)))
typeList.add(TypeList(RecordTypes.RECORD_TYPE_TB, resourceHelper.gs(R.string.diaconn_g8_history_tempbasal)))
typeList.add(TypeList(RecordTypes.RECORD_TYPE_DAILY, resourceHelper.gs(R.string.diaconn_g8_history_dailyinsulin)))
typeList.add(TypeList(RecordTypes.RECORD_TYPE_REFILL, resourceHelper.gs(R.string.diaconn_g8_history_refill)))
typeList.add(TypeList(RecordTypes.RECORD_TYPE_SUSPEND, resourceHelper.gs(R.string.diaconn_g8_history_suspend)))
binding.spinner.adapter = ArrayAdapter(this, R.layout.spinner_centered, typeList)
binding.reload.setOnClickListener {
val selected = binding.spinner.selectedItem as TypeList?
?: return@setOnClickListener
runOnUiThread {
binding.reload.visibility = View.GONE
binding.status.visibility = View.VISIBLE
}
clearCardView()
commandQueue.loadHistory(selected.type, object : Callback() {
override fun run() {
swapAdapter(selected.type)
runOnUiThread {
binding.reload.visibility = View.VISIBLE
binding.status.visibility = View.GONE
}
}
})
}
binding.spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
val selected = typeList[position]
swapAdapter(selected.type)
showingType = selected.type
}
override fun onNothingSelected(parent: AdapterView<*>?) {
clearCardView()
}
}
}
inner class RecyclerViewAdapter internal constructor(private var historyList: List<DiaconnHistoryRecord>) : RecyclerView.Adapter<RecyclerViewAdapter.HistoryViewHolder>() {
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): HistoryViewHolder =
HistoryViewHolder(LayoutInflater.from(viewGroup.context).inflate(R.layout.diaconn_g8_history_item, viewGroup, false))
override fun onBindViewHolder(holder: HistoryViewHolder, position: Int) {
val record = historyList[position]
holder.time.text = dateUtil.dateAndTimeString(record.timestamp)
holder.value.text = DecimalFormatter.to2Decimal(record.value)
holder.stringValue.text = record.stringValue
holder.bolusType.text = record.bolusType
holder.duration.text = DecimalFormatter.to0Decimal(record.duration.toDouble())
holder.alarm.text = record.alarm
when (showingType) {
RecordTypes.RECORD_TYPE_ALARM -> {
holder.time.visibility = View.VISIBLE
holder.value.visibility = View.VISIBLE
holder.stringValue.visibility = View.VISIBLE
holder.bolusType.visibility = View.GONE
holder.duration.visibility = View.GONE
holder.dailyBasal.visibility = View.GONE
holder.dailyBolus.visibility = View.GONE
holder.dailyTotal.visibility = View.GONE
holder.alarm.visibility = View.VISIBLE
}
RecordTypes.RECORD_TYPE_BOLUS -> {
holder.time.visibility = View.VISIBLE
holder.value.visibility = View.VISIBLE
holder.stringValue.visibility = View.VISIBLE
holder.bolusType.visibility = View.VISIBLE
holder.duration.visibility = View.VISIBLE
holder.dailyBasal.visibility = View.GONE
holder.dailyBolus.visibility = View.GONE
holder.dailyTotal.visibility = View.GONE
holder.alarm.visibility = View.GONE
}
RecordTypes.RECORD_TYPE_DAILY -> {
holder.dailyBasal.text = resourceHelper.gs(R.string.formatinsulinunits, record.dailyBasal)
holder.dailyBolus.text = resourceHelper.gs(R.string.formatinsulinunits, record.dailyBolus)
holder.dailyTotal.text = resourceHelper.gs(R.string.formatinsulinunits, record.dailyBolus + record.dailyBasal)
holder.time.text = dateUtil.dateString(record.timestamp)
holder.time.visibility = View.VISIBLE
holder.value.visibility = View.GONE
holder.stringValue.visibility = View.GONE
holder.bolusType.visibility = View.GONE
holder.duration.visibility = View.GONE
holder.dailyBasal.visibility = View.VISIBLE
holder.dailyBolus.visibility = View.VISIBLE
holder.dailyTotal.visibility = View.VISIBLE
holder.alarm.visibility = View.GONE
}
RecordTypes.RECORD_TYPE_BASALHOUR -> {
holder.time.visibility = View.VISIBLE
holder.value.visibility = View.VISIBLE
holder.stringValue.visibility = View.VISIBLE
holder.bolusType.visibility = View.GONE
holder.duration.visibility = View.GONE
holder.dailyBasal.visibility = View.GONE
holder.dailyBolus.visibility = View.GONE
holder.dailyTotal.visibility = View.GONE
holder.alarm.visibility = View.GONE
}
RecordTypes.RECORD_TYPE_REFILL -> {
holder.time.visibility = View.VISIBLE
holder.value.visibility = View.VISIBLE
holder.stringValue.visibility = View.VISIBLE
holder.bolusType.visibility = View.GONE
holder.duration.visibility = View.GONE
holder.dailyBasal.visibility = View.GONE
holder.dailyBolus.visibility = View.GONE
holder.dailyTotal.visibility = View.GONE
holder.alarm.visibility = View.GONE
}
RecordTypes.RECORD_TYPE_TB -> {
holder.time.visibility = View.VISIBLE
holder.value.visibility = View.VISIBLE
holder.stringValue.visibility = View.VISIBLE
holder.bolusType.visibility = View.GONE
holder.duration.visibility = View.VISIBLE
holder.dailyBasal.visibility = View.GONE
holder.dailyBolus.visibility = View.GONE
holder.dailyTotal.visibility = View.GONE
holder.alarm.visibility = View.GONE
}
RecordTypes.RECORD_TYPE_SUSPEND -> {
holder.time.visibility = View.VISIBLE
holder.value.visibility = View.GONE
holder.stringValue.visibility = View.VISIBLE
holder.bolusType.visibility = View.GONE
holder.duration.visibility = View.GONE
holder.dailyBasal.visibility = View.GONE
holder.dailyBolus.visibility = View.GONE
holder.dailyTotal.visibility = View.GONE
holder.alarm.visibility = View.GONE
}
}
}
override fun getItemCount(): Int {
return historyList.size
}
inner class HistoryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var time: TextView = itemView.findViewById(R.id.diaconn_g8_history_time)
var value: TextView = itemView.findViewById(R.id.diaconn_g8_history_value)
var bolusType: TextView = itemView.findViewById(R.id.diaconn_g8_history_bolustype)
var stringValue: TextView = itemView.findViewById(R.id.diaconn_g8_history_stringvalue)
var duration: TextView = itemView.findViewById(R.id.diaconn_g8_history_duration)
var dailyBasal: TextView = itemView.findViewById(R.id.diaconn_g8_history_dailybasal)
var dailyBolus: TextView = itemView.findViewById(R.id.diaconn_g8_history_dailybolus)
var dailyTotal: TextView = itemView.findViewById(R.id.diaconn_g8_history_dailytotal)
var alarm: TextView = itemView.findViewById(R.id.diaconn_g8_history_alarm)
}
}
private fun swapAdapter(type: Byte) {
disposable += diaconnHistoryRecordDao
.allFromByType(dateUtil.now() - T.months(1).msecs(), type)
.subscribeOn(aapsSchedulers.io)
.observeOn(aapsSchedulers.main)
.subscribe { historyList -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(historyList), false) }
}
private fun clearCardView() = binding.recyclerview.swapAdapter(RecyclerViewAdapter(ArrayList()), false)
}

View file

@ -0,0 +1,192 @@
package info.nightscout.androidaps.diaconn.activities
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.diaconn.R
import info.nightscout.androidaps.diaconn.databinding.DiaconnG8UserOptionsActivityBinding
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.disposables.CompositeDisposable
import java.text.DecimalFormat
import javax.inject.Inject
class DiaconnG8UserOptionsActivity : NoSplashAppCompatActivity() {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var context: Context
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var commandQueue: CommandQueueProvider
@Inject lateinit var sp: SP
private val disposable = CompositeDisposable()
private lateinit var binding: DiaconnG8UserOptionsActivityBinding
@Synchronized
override fun onResume() {
super.onResume()
}
@Synchronized
override fun onPause() {
disposable.clear()
super.onPause()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DiaconnG8UserOptionsActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.saveAlarm.setOnClickListener { onSaveAlarmClick() }
binding.saveLcdOnTime.setOnClickListener { onSavelcdOnTimeClick() }
binding.saveLang.setOnClickListener { onSaveLangClick() }
binding.saveBolusSpeed.setOnClickListener { onSaveBolusSpeedClick() }
val spBolusSpeed = sp.getString("g8_bolusspeed", "5")
binding.bolusSpeed.setParams(spBolusSpeed.toDouble(), 1.0, 8.0, 1.0, DecimalFormat("1"), true, binding.saveBolusSpeed)
aapsLogger.debug(LTag.PUMP,
"UserOptionsLoaded:" + (System.currentTimeMillis() - diaconnG8Pump.lastConnection) / 1000 + " s ago"
+ "\nbeepAndAlarm:" + diaconnG8Pump.beepAndAlarm
+ "\nalarmIntesity:" + diaconnG8Pump.alarmIntesity
+ "\nlanguage:" + diaconnG8Pump.selectedLanguage
+ "\nlcdOnTimeSec:" + diaconnG8Pump.lcdOnTimeSec)
fillSoundCategory()
fillSoundSubCategory()
binding.beepAndAlarm.setSelection(diaconnG8Pump.beepAndAlarm - 1)
binding.alarmIntesity.setSelection(diaconnG8Pump.alarmIntesity - 1)
binding.beepAndAlarm.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
binding.alarmIntesity.visibility = if("silent" == binding.beepAndAlarm.getItemAtPosition(position).toString()) View.GONE else View.VISIBLE
}
override fun onNothingSelected(parent: AdapterView<*>?) {}
}
when (diaconnG8Pump.lcdOnTimeSec) {
1 -> binding.pumpscreentimeout10.isChecked = true
2 -> binding.pumpscreentimeout20.isChecked = true
3 -> binding.pumpscreentimeout30.isChecked = true
}
when (diaconnG8Pump.selectedLanguage) {
1 -> binding.pumplangChiness.isChecked = true
2 -> binding.pumplangKorean.isChecked = true
3 -> binding.pumplangEnglish.isChecked = true
}
}
private fun onSaveAlarmClick() {
diaconnG8Pump.setUserOptionType = DiaconnG8Pump.ALARM
diaconnG8Pump.beepAndAlarm = binding.beepAndAlarm.selectedItemPosition + 1
diaconnG8Pump.alarmIntesity = binding.alarmIntesity.selectedItemPosition + 1
onSaveClick()
}
private fun onSavelcdOnTimeClick() {
diaconnG8Pump.setUserOptionType = DiaconnG8Pump.LCD
diaconnG8Pump.lcdOnTimeSec = when {
binding.pumpscreentimeout10.isChecked -> 1
binding.pumpscreentimeout20.isChecked -> 2
binding.pumpscreentimeout30.isChecked -> 3
else -> 1
}
onSaveClick()
}
private fun onSaveLangClick() {
diaconnG8Pump.setUserOptionType = DiaconnG8Pump.LANG
diaconnG8Pump.selectedLanguage = when {
binding.pumplangChiness.isChecked -> 1
binding.pumplangKorean.isChecked -> 2
binding.pumplangEnglish.isChecked -> 3
else -> 2
}
onSaveClick()
}
private fun onSaveBolusSpeedClick() {
val intSpeed = binding.bolusSpeed.value.toInt()
diaconnG8Pump.bolusSpeed = intSpeed
diaconnG8Pump.speed = intSpeed
diaconnG8Pump.setUserOptionType = DiaconnG8Pump.BOLUS_SPEED
sp.putString("g8_bolusspeed", intSpeed.toString())
sp.putBoolean("diaconn_g8_isbolusspeedsync", false)
ToastUtils.okToast(context, "Save Success!")
}
private fun onSaveClick() {
commandQueue.setUserOptions(object : Callback() {
override fun run() {
if (!result.success) {
val i = Intent(context, ErrorHelperActivity::class.java)
i.putExtra("soundid", R.raw.boluserror)
i.putExtra("status", result.comment)
i.putExtra("title", resourceHelper.gs(R.string.pumperror))
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(i)
}
}
})
finish()
}
private fun fillSoundCategory() {
val categories = ArrayList<String>()
categories.add(resourceHelper.gs(R.string.diaconn_g8_pumpalarm_sound))
categories.add(resourceHelper.gs(R.string.diaconn_g8_pumpalarm_vibrate))
categories.add(resourceHelper.gs(R.string.diaconn_g8_pumpalarm_silent))
context.let { context ->
val adapterCategories = ArrayAdapter(context, R.layout.spinner_centered, categories)
binding.beepAndAlarm.adapter = adapterCategories
}
}
private fun fillSoundSubCategory() {
val categories = ArrayList<String>()
categories.add(resourceHelper.gs(R.string.diaconn_g8_pumpalarm_intensity_low))
categories.add(resourceHelper.gs(R.string.diaconn_g8_pumpalarm_intensity_middle))
categories.add(resourceHelper.gs(R.string.diaconn_g8_pumpalarm_intensity_high))
context.let { context ->
val adapterCategories = ArrayAdapter(context, R.layout.spinner_centered, categories)
binding.alarmIntesity.adapter = adapterCategories
}
}
}

View file

@ -0,0 +1,11 @@
package info.nightscout.androidaps.diaconn.common
object RecordTypes {
const val RECORD_TYPE_BOLUS = 0x01.toByte()
const val RECORD_TYPE_DAILY = 0x02.toByte()
const val RECORD_TYPE_ALARM = 0x03.toByte()
const val RECORD_TYPE_REFILL = 0x04.toByte()
const val RECORD_TYPE_SUSPEND = 0x05.toByte()
const val RECORD_TYPE_BASALHOUR = 0x06.toByte()
const val RECORD_TYPE_TB = 0x07.toByte()
}

View file

@ -0,0 +1,32 @@
package info.nightscout.androidaps.diaconn.database
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
const val TABLE_DIACONN_HISTORY = "diaconnHistory"
@Database(
entities = [DiaconnHistoryRecord::class],
exportSchema = true,
version = DiaconnHistoryDatabase.VERSION
)
abstract class DiaconnHistoryDatabase : RoomDatabase() {
abstract fun historyRecordDao(): DiaconnHistoryRecordDao
companion object {
const val VERSION = 1
fun build(context: Context) =
Room.databaseBuilder(
context.applicationContext,
DiaconnHistoryDatabase::class.java,
"diaconn_database.db"
)
.fallbackToDestructiveMigration()
.build()
}
}

View file

@ -0,0 +1,19 @@
package info.nightscout.androidaps.diaconn.database
import androidx.room.Entity
import androidx.room.Index
import androidx.room.PrimaryKey
@Entity(tableName = TABLE_DIACONN_HISTORY,
indices = [Index("code", "timestamp")])
data class DiaconnHistoryRecord(
@PrimaryKey var timestamp: Long,
var code: Byte = 0x0F,
var value: Double = 0.0,
var bolusType: String = "None",
var stringValue: String = "",
var duration: Int = 0,
var dailyBasal: Double = 0.0,
var dailyBolus: Double = 0.0,
var alarm: String = ""
)

View file

@ -0,0 +1,17 @@
package info.nightscout.androidaps.diaconn.database
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import io.reactivex.Single
@Dao
abstract class DiaconnHistoryRecordDao {
@Query("SELECT * from $TABLE_DIACONN_HISTORY WHERE timestamp >= :timestamp AND code = :type")
abstract fun allFromByType(timestamp: Long, type: Byte): Single<List<DiaconnHistoryRecord>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun createOrUpdate(diaconnHistoryRecord: DiaconnHistoryRecord)
}

View file

@ -0,0 +1,17 @@
package info.nightscout.androidaps.diaconn.di
import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Fragment
import info.nightscout.androidaps.diaconn.activities.DiaconnG8BLEScanActivity
import info.nightscout.androidaps.diaconn.activities.DiaconnG8HistoryActivity
import info.nightscout.androidaps.diaconn.activities.DiaconnG8UserOptionsActivity
@Module
@Suppress("unused")
abstract class DiaconnG8ActivitiesModule {
@ContributesAndroidInjector abstract fun contributesDiaconnG8Fragment(): DiaconnG8Fragment
@ContributesAndroidInjector abstract fun contributesDiaconnG8HistoryActivity(): DiaconnG8HistoryActivity
@ContributesAndroidInjector abstract fun contributesDiaconnG8UserOptionsActivity(): DiaconnG8UserOptionsActivity
@ContributesAndroidInjector abstract fun contributesDiaconnG8BLEScanActivity(): DiaconnG8BLEScanActivity
}

View file

@ -0,0 +1,12 @@
package info.nightscout.androidaps.diaconn.di
import dagger.Module
@Module(includes = [
DiaconnG8ActivitiesModule::class,
DiaconnG8ServiceModule::class,
DiaconnG8PacketModule::class,
DiaconnHistoryModule::class
])
open class DiaconnG8Module

View file

@ -0,0 +1,81 @@
package info.nightscout.androidaps.diaconn.di
import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.diaconn.packet.*
@Module
@Suppress("unused")
abstract class DiaconnG8PacketModule {
@ContributesAndroidInjector abstract fun contributesDiaconnG8Packet(): DiaconnG8Packet
@ContributesAndroidInjector abstract fun contributesAppCancelSettingPacket(): AppCancelSettingPacket
@ContributesAndroidInjector abstract fun contributesAppCancelSettingResponsePacket(): AppCancelSettingResponsePacket
@ContributesAndroidInjector abstract fun contributesAppConfirmSettingPacket(): AppConfirmSettingPacket
@ContributesAndroidInjector abstract fun contributesAppConfirmSettingResponsePacket(): AppConfirmSettingResponsePacket
@ContributesAndroidInjector abstract fun contributesSneckLimitInquirePacket(): SneckLimitInquirePacket
@ContributesAndroidInjector abstract fun contributesBasalLimitInquirePacket(): BasalLimitInquirePacket
@ContributesAndroidInjector abstract fun contributesSneckLimitInquireResponsePacket(): SneckLimitInquireResponsePacket
@ContributesAndroidInjector abstract fun contributesBasalLimitInquireResponsePacket(): BasalLimitInquireResponsePacket
@ContributesAndroidInjector abstract fun contributesBasalPauseReportPacket(): BasalPauseReportPacket
@ContributesAndroidInjector abstract fun contributesBasalPauseSettingPacket(): BasalPauseSettingPacket
@ContributesAndroidInjector abstract fun contributesBasalPauseSettingResponsePacket(): BasalPauseSettingResponsePacket
@ContributesAndroidInjector abstract fun contributesBasalSettingPacket(): BasalSettingPacket
@ContributesAndroidInjector abstract fun contributesBasalSettingReportPacket(): BasalSettingReportPacket
@ContributesAndroidInjector abstract fun contributesBasalSettingResponsePacket(): BasalSettingResponsePacket
@ContributesAndroidInjector abstract fun contributesBigMainInfoInquirePacket(): BigMainInfoInquirePacket
@ContributesAndroidInjector abstract fun contributesBigMainInfoInquireResponsePacket(): BigMainInfoInquireResponsePacket
@ContributesAndroidInjector abstract fun contributesBigLogInquirePacket(): BigLogInquirePacket
@ContributesAndroidInjector abstract fun contributesBigLogInquireResponsePacket(): BigLogInquireResponsePacket
@ContributesAndroidInjector abstract fun contributesConfirmReportPacket(): ConfirmReportPacket
@ContributesAndroidInjector abstract fun contributesInjectionBasalSettingPacket(): InjectionBasalSettingPacket
@ContributesAndroidInjector abstract fun contributesInjectionBasalSettingResponsePacket(): InjectionBasalSettingResponsePacket
@ContributesAndroidInjector abstract fun contributesInjectionSnackResultReportPacket(): InjectionSnackResultReportPacket
@ContributesAndroidInjector abstract fun contributesInjectionSnactSettingPacket(): InjectionSnackSettingPacket
@ContributesAndroidInjector abstract fun contributesInjectionSnackSettingResponsePacket(): InjectionSnackSettingResponsePacket
@ContributesAndroidInjector abstract fun contributesInjectionExtendedBolusResultReportPacket(): InjectionExtendedBolusResultReportPacket
@ContributesAndroidInjector abstract fun contributesInjectionExtendedBolusSettingPacket(): InjectionExtendedBolusSettingPacket
@ContributesAndroidInjector abstract fun contributesInjectionExtendedBolusSettingResponsePacket(): InjectionExtendedBolusSettingResponsePacket
@ContributesAndroidInjector abstract fun contributesInjectionBasalReportPacket(): InjectionBasalReportPacket
@ContributesAndroidInjector abstract fun contributesInjectionSnackInquirePacket(): InjectionSnackInquirePacket
@ContributesAndroidInjector abstract fun contributesInjectionSnackInquireResponsePacket(): InjectionSnackInquireResponsePacket
@ContributesAndroidInjector abstract fun contributesRejectReportPacket(): RejectReportPacket
@ContributesAndroidInjector abstract fun contributesTempBasalReportPacket(): TempBasalReportPacket
@ContributesAndroidInjector abstract fun contributesTempBasalSettingPacket(): TempBasalSettingPacket
@ContributesAndroidInjector abstract fun contributesTempBasalSettingResponsePacket(): TempBasalSettingResponsePacket
@ContributesAndroidInjector abstract fun contributesTempBasalInquirePacket(): TempBasalInquirePacket
@ContributesAndroidInjector abstract fun contributesTempBasalInquireResponsePacket(): TempBasalInquireResponsePacket
@ContributesAndroidInjector abstract fun contributesTimeInquirePacket(): TimeInquirePacket
@ContributesAndroidInjector abstract fun contributesTimeInquireResponsePacket(): TimeInquireResponsePacket
@ContributesAndroidInjector abstract fun contributesTimeReportPacket(): TimeReportPacket
@ContributesAndroidInjector abstract fun contributesTimeSettingPacket(): TimeSettingPacket
@ContributesAndroidInjector abstract fun contributesTimeSettingResponsePacket(): TimeSettingResponsePacket
@ContributesAndroidInjector abstract fun contributesLogStatusInquirePacket(): LogStatusInquirePacket
@ContributesAndroidInjector abstract fun contributesLogStatusInquireResponsePacket(): LogStatusInquireResponsePacket
@ContributesAndroidInjector abstract fun contributesInjectionCancelSettingPacket(): InjectionCancelSettingPacket
@ContributesAndroidInjector abstract fun contributesInjectionCancelSettingResponsePacket(): InjectionCancelSettingResponsePacket
@ContributesAndroidInjector abstract fun contributesSoundSettingPacket(): SoundSettingPacket
@ContributesAndroidInjector abstract fun contributesSoundSettingResponsePacket(): SoundSettingResponsePacket
@ContributesAndroidInjector abstract fun contributesDisplayTimeoutSettingPacket(): DisplayTimeoutSettingPacket
@ContributesAndroidInjector abstract fun contributesDisplayTimeoutSettingResponsePacket(): DisplayTimeoutSettingResponsePacket
@ContributesAndroidInjector abstract fun contributesLanguageSettingPacket(): LanguageSettingPacket
@ContributesAndroidInjector abstract fun contributesLanguageSettingResponsePacket(): LanguageSettingResponsePacket
@ContributesAndroidInjector abstract fun contributesInjectionBlockReportPacket(): InjectionBlockReportPacket
@ContributesAndroidInjector abstract fun contributesBatteryWarningReportPacket(): BatteryWarningReportPacket
@ContributesAndroidInjector abstract fun contributesInsulinLackReportPacket(): InsulinLackReportPacket
@ContributesAndroidInjector abstract fun contributesIncarnationInquirePacket(): IncarnationInquirePacket
@ContributesAndroidInjector abstract fun contributesIncarnationInquireResponsePacket(): IncarnationInquireResponsePacket
@ContributesAndroidInjector abstract fun contributesBolusSpeedSettingPacket(): BolusSpeedSettingPacket
@ContributesAndroidInjector abstract fun contributesBolusSpeedSettingResponsePacket(): BolusSpeedSettingResponsePacket
@ContributesAndroidInjector abstract fun contributesInjectionSpeedInquirePacket(): BolusSpeedInquirePacket
@ContributesAndroidInjector abstract fun contributesInjectionSpeedInquireResponsePacket(): BolusSpeedInquireResponsePacket
@ContributesAndroidInjector abstract fun contributesBolusSpeedSettingReportPacket(): BolusSpeedSettingReportPacket
@ContributesAndroidInjector abstract fun contributesSoundInquirePacket(): SoundInquirePacket
@ContributesAndroidInjector abstract fun contributesSoundInquireResponsePacket(): SoundInquireResponsePacket
@ContributesAndroidInjector abstract fun contributesDisplayTimeInquirePacket(): DisplayTimeInquirePacket
@ContributesAndroidInjector abstract fun contributesDisplayTimeInquireResponsePacket(): DisplayTimeInquireResponsePacket
@ContributesAndroidInjector abstract fun contributesLanguageInquirePacket(): LanguageInquirePacket
@ContributesAndroidInjector abstract fun contributesLanguageInquireResponsePacket(): LanguageInquireResponsePacket
}

View file

@ -0,0 +1,11 @@
package info.nightscout.androidaps.diaconn.di
import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.diaconn.service.DiaconnG8Service
@Module
@Suppress("unused")
abstract class DiaconnG8ServiceModule {
@ContributesAndroidInjector abstract fun contributesDiaconnG8Service(): DiaconnG8Service
}

View file

@ -0,0 +1,21 @@
package info.nightscout.androidaps.diaconn.di
import android.content.Context
import dagger.Module
import dagger.Provides
import info.nightscout.androidaps.diaconn.database.DiaconnHistoryDatabase
import info.nightscout.androidaps.diaconn.database.DiaconnHistoryRecordDao
import javax.inject.Singleton
@Module
class DiaconnHistoryModule {
@Provides
@Singleton
internal fun provideDatabase(context: Context): DiaconnHistoryDatabase = DiaconnHistoryDatabase.build(context)
@Provides
@Singleton
internal fun provideHistoryRecordDao(diaconnHistoryDatabase: DiaconnHistoryDatabase): DiaconnHistoryRecordDao =
diaconnHistoryDatabase.historyRecordDao()
}

View file

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

View file

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

View file

@ -0,0 +1,32 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* AppCancelSettingPacket
*/
class AppCancelSettingPacket(
injector: HasAndroidInjector,
private var reqMsgType: Byte,
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x29
aapsLogger.debug(LTag.PUMPCOMM, "AppCancelSettingPacket init")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END)
buffer.put(reqMsgType) // 명령코드
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_APP_CANCEL_SETTING"
}
}

View file

@ -0,0 +1,44 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* AppCancelSettingResponsePacket
*/
class AppCancelSettingResponsePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
var result =0
init {
msgType = 0xA9.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "AppCancelSettingResPacket init ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "AppCancelSettingResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
result = getByteToInt(bufferData)
if(!isSuccSettingResponseResult(result)) {
diaconnG8Pump.bolusStartErrorCode = result
failed = true
return
}
aapsLogger.debug(LTag.PUMPCOMM, "Result --> ${result}")
}
override fun getFriendlyName(): String {
return "PUMP_APP_CANCEL_SETTING_RESPONSE"
}
}

View file

@ -0,0 +1,39 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* AppConfirmSettingPacket
*/
class AppConfirmSettingPacket(
injector: HasAndroidInjector,
private var reqMsgType: Byte, // 명령코드
private var otp: Int // 응답시 전달받은 opt (random 6 digit numbner)
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x37
aapsLogger.debug(LTag.PUMPCOMM, "AppConfirmSettingPacket init")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END);
buffer.put(reqMsgType) // 명령코드
buffer.putInt(otp) // 응답시 전달받은 opt (random 6digit numbner)
aapsLogger.debug(LTag.PUMPCOMM, "reqMsgType -> ${reqMsgType}")
aapsLogger.debug(LTag.PUMPCOMM, "otp -> ${otp}")
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_APP_CONFRIM_SETTING"
}
}

View file

@ -0,0 +1,43 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* AppConfirmSettingResponsePacket
*/
class AppConfirmSettingResponsePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
var result =0
init {
msgType = 0xB7.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "AppConfirmSettingReqPacket Response ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "AppConfirmSettingResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
result = getByteToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "Result --> ${result}")
if(!isSuccSettingResponseResult(result)) {
diaconnG8Pump.bolusStartErrorCode = result
failed = true
return
}
}
override fun getFriendlyName(): String {
return "PUMP_APP_CONFIRM_SETTING_RESPONSE"
}
}

View file

@ -0,0 +1,30 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* BasalLimitInquirePacket
*/
class BasalLimitInquirePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x52.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "BasalLimitInquirePacket init")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END);
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_BASAL_LIMIT_INQUIRE"
}
}

View file

@ -0,0 +1,44 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* BasalLimitInquireResponsePacket
*/
class BasalLimitInquireResponsePacket(injector: HasAndroidInjector) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x92.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "BasalLimitInquireResponsePacket init")
}
override fun handleMessage(data: ByteArray?) {
val result = defect(data)
if (result != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "BasalLimitInquireResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
val result2 = getByteToInt(bufferData)
if(!isSuccInquireResponseResult(result2)) {
failed = true
return
}
diaconnG8Pump.maxBasalPerHours = getShortToInt(bufferData).toDouble() / 100.0 // not include tempbasal limit
diaconnG8Pump.maxBasal = diaconnG8Pump.maxBasalPerHours * 2 // include tempbasal
aapsLogger.debug(LTag.PUMPCOMM, "Result --> ${diaconnG8Pump.result}")
aapsLogger.debug(LTag.PUMPCOMM, "maxBasal --> ${diaconnG8Pump.maxBasal}")
}
override fun getFriendlyName(): String {
return "PUMP_BASAL_LIMIT_INQUIRE_RESPONSE"
}
}

View file

@ -0,0 +1,37 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* BasalPauseReportPacket
*/
class BasalPauseReportPacket(injector: HasAndroidInjector) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
var status:Int? = null
init {
msgType = 0xC3.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "BasalPauseReportPacket init ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "BasalPauseReportPacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
status = getByteToInt(bufferData) //(1: pauseed, 2: pause cancel)
aapsLogger.debug(LTag.PUMPCOMM, "status --> ${status}")
}
override fun getFriendlyName(): String {
return "PUMP_BASAL_PAUSE_REPORT"
}
}

View file

@ -0,0 +1,32 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* Basal Pause Setting Packet
*/
class BasalPauseSettingPacket(
injector: HasAndroidInjector,
private var status:Int //(1:pause, 2: cancel pause)
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x03
aapsLogger.debug(LTag.PUMPCOMM, "BasalPauseSettingPacket Init")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END);
buffer.put(status.toByte()) // (1:pause, 2: cancel pause)
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_BASAL_PAUSE_SETTING"
}
}

View file

@ -0,0 +1,48 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* BasalPauseSettingResponsePacket
*/
class BasalPauseSettingResponsePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
var result = 0
init {
msgType = 0x83.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "BasalPauseSettingResponsePacket Init")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "BasalPauseSettingResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
result = getByteToInt(bufferData)
if(!isSuccSettingResponseResult(result)) {
diaconnG8Pump.bolusStartErrorCode = result
failed = true
return
}
diaconnG8Pump.otpNumber = getIntToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "Result --> ${result}")
aapsLogger.debug(LTag.PUMPCOMM, "otpNumber --> ${diaconnG8Pump.otpNumber}")
}
override fun getFriendlyName(): String {
return "PUMP_BASAL_PAUSE_SETTING_RESPONSE"
}
}

View file

@ -0,0 +1,54 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* BasalSettingPacket
*/
class BasalSettingPacket(
injector: HasAndroidInjector,
private var pattern: Int, // pattern(1=basic, 2=life1, 3=life2, 4=life3, 5=dr1, 6=dr2)
private var group: Int, //hour group (1=00~05, 2=06~11, 3=12~17, 4=18~23)
private var amount1: Int,
private var amount2: Int,
private var amount3: Int,
private var amount4: Int,
private var amount5: Int,
private var amount6: Int
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x0B
aapsLogger.debug(LTag.PUMPCOMM, "Setting new basal rates for profile")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = if (group == 4) {
// 마지막 그룹일때
prefixEncode(msgType, msgSeq, MSG_CON_END)
} else {
// 1, 2, 3 그룹일때
prefixEncode(msgType, msgSeq, MSG_CON_CONTINUE)
}
buffer.put(pattern.toByte()) // 패턴 종류 (1=기본, 2=생활1, 3=생활2, 4=생활3, 5=닥터1, 6=닥터2)
buffer.put(group.toByte()) // 그룹 (1=00~05, 2=06~11, 3=12~17, 4=18~23)
buffer.putShort(amount1.toShort()) // 주입량 1
buffer.putShort(amount2.toShort()) // 주입량 2
buffer.putShort(amount3.toShort()) // 주입량 3
buffer.putShort(amount4.toShort()) // 주입량 4
buffer.putShort(amount5.toShort()) // 주입량 5
buffer.putShort(amount6.toShort()) // 주입량 6
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_BASAL_SETTING"
}
}

View file

@ -0,0 +1,40 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* BasalSettingReportPacket
*/
class BasalSettingReportPacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
var result = 0
init {
msgType = 0xCB.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "BasalSettingReportPacket init ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "BasalSettingReportPacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
result = getByteToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "Result --> $result")
// no Response
}
override fun getFriendlyName(): String {
return "PUMP_BASAL_SETTING_REPORT"
}
}

View file

@ -0,0 +1,46 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* BasalSettingResponsePacket
*/
class BasalSettingResponsePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
var result = 0
init {
msgType = 0x8B.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "BasalSettingResponsePacket init")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "BasalSettingResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
result = getByteToInt(bufferData)
if(!isSuccSettingResponseResult(result)) {
diaconnG8Pump.bolusStartErrorCode = result
failed = true
return
}
diaconnG8Pump.otpNumber = getIntToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "Result --> $result")
aapsLogger.debug(LTag.PUMPCOMM, "otpNumber --> ${diaconnG8Pump.otpNumber}")
}
override fun getFriendlyName(): String {
return "PUMP_BASAL_SETTING_RESPONSE"
}
}

View file

@ -0,0 +1,44 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* BatteryWarningReportPacket
*/
class BatteryWarningReportPacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0xD7.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "BatteryWarningReportPacket init ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "BatteryWarningReportPacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
diaconnG8Pump.batteryWaningGrade = getByteToInt(bufferData)
diaconnG8Pump.batteryWaningProcess = getByteToInt(bufferData)
diaconnG8Pump.batteryWaningRemain = getByteToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "batteryWaningGrade --> ${diaconnG8Pump.batteryWaningGrade} (1:info, 2: warning , 3: major , 4: critical)")
aapsLogger.debug(LTag.PUMPCOMM, "batteryWaningProcess --> ${diaconnG8Pump.batteryWaningProcess} (1:skip, 2: stop , 3: ignore ) ")
aapsLogger.debug(LTag.PUMPCOMM, "batteryWaningRemain --> ${diaconnG8Pump.batteryWaningRemain} (0~100%) )")
}
override fun getFriendlyName(): String {
return "PUMP_BATTERY_WARNING_REPORT"
}
}

View file

@ -0,0 +1,35 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* BigLogInquirePacket
*/
class BigLogInquirePacket(
injector: HasAndroidInjector,
private val start: Int,
private val end:Int,
private val delay:Int
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x72
aapsLogger.debug(LTag.PUMPCOMM, "BigLogInquirePacket init")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END)
buffer.putShort(start.toShort())
buffer.putShort(end.toShort())
buffer.put(delay.toByte())
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_BIG_LOG_INQUIRE"
}
}

View file

@ -0,0 +1,774 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.diaconn.R
import info.nightscout.androidaps.diaconn.common.RecordTypes
import info.nightscout.androidaps.diaconn.database.DiaconnHistoryRecord
import info.nightscout.androidaps.diaconn.database.DiaconnHistoryRecordDao
import info.nightscout.androidaps.diaconn.pumplog.*
import info.nightscout.androidaps.events.EventPumpStatusChanged
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.PumpDescription
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage
import info.nightscout.androidaps.plugins.pump.common.bolusInfo.TemporaryBasalStorage
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.apache.commons.lang3.time.DateUtils
import org.joda.time.DateTime
import javax.inject.Inject
/**
* BigLogInquireResponsePacket
*/
class BigLogInquireResponsePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector) {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
@Inject lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage
@Inject lateinit var temporaryBasalStorage: TemporaryBasalStorage
@Inject lateinit var sp: SP
@Inject lateinit var pumpSync: PumpSync
@Inject lateinit var diaconnHistoryRecordDao: DiaconnHistoryRecordDao
var result = 0// 조회결과
private var pumpDesc = PumpDescription(PumpType.DIACONN_G8)
init {
msgType = 0xb2.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "BigLogInquireResponsePacket init")
}
override fun handleMessage(data: ByteArray?) {
val result = defect(data)
if (result != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "BigLogInquireResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data) // 데이타 영역 15바이트 버퍼
val result2 = getByteToInt(bufferData) // 조회결과 1 byte
if(!isSuccInquireResponseResult(result2)) {
failed = true
return
}
val logLength = getByteToInt(bufferData) // 로그의 갯수. 1byte
// initalize
val dailyMaxvalInfo = mutableMapOf<String, MutableMap<String, Double>>()
dailyMaxvalInfo[""] = mutableMapOf()
// 15 byte를 로그갯수만큼 돌기.
for(i in 0 until logLength) {
val wrapingCount = getByteToInt(bufferData) // 1byte
val logNum = getShortToInt(bufferData) // 2byte
// log Data Parsing
val logdata = byteArrayOf(
PumplogUtil.getByte(bufferData),
PumplogUtil.getByte(bufferData),
PumplogUtil.getByte(bufferData),
PumplogUtil.getByte(bufferData),
PumplogUtil.getByte(bufferData),
PumplogUtil.getByte(bufferData),
PumplogUtil.getByte(bufferData),
PumplogUtil.getByte(bufferData),
PumplogUtil.getByte(bufferData),
PumplogUtil.getByte(bufferData),
PumplogUtil.getByte(bufferData),
PumplogUtil.getByte(bufferData)
)
diaconnG8Pump.apsWrappingCount = wrapingCount
diaconnG8Pump.apslastLogNum = logNum
sp.putInt(resourceHelper.gs(R.string.apslastLogNum), logNum)
sp.putInt(resourceHelper.gs(R.string.apsWrappingCount), wrapingCount)
// process Log to DB
val logDataToHexString = toNarrowHex(logdata)
val pumplogKind: Byte = PumplogUtil.getKind(logDataToHexString)
var status: String
val diaconnG8HistoryRecord = DiaconnHistoryRecord(0)
when(pumplogKind) {
LOG_INJECT_MEAL_SUCCESS.LOG_KIND -> { // 8(식사주입성공)
val logItem = LOG_INJECT_MEAL_SUCCESS.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(logDateTime, logItem.injectAmount / 100.0)
val newRecord = pumpSync.syncBolusWithPumpId(
timestamp = logDateTime,
amount = logItem.injectAmount / 100.0,
type = detailedBolusInfo?.bolusType,
pumpId = logDateTime,
pumpType = PumpType.DIACONN_G8,
pumpSerial = diaconnG8Pump.serialNo.toString())
aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT MEALBOLUS (" + pumplogKind + ") " + dateUtil.dateAndTimeString(logDateTime) + " (" + logDateTime + ")" + " Bolus: " + logItem.injectAmount / 100.0 + "U ")
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_BOLUS
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.value = logItem.injectAmount / 100.0
diaconnG8HistoryRecord.duration = logItem.getInjectTime()
diaconnG8HistoryRecord.bolusType = "M" // meal bolus
diaconnG8HistoryRecord.stringValue = resourceHelper.gs(R.string.diaconn_g8_logmealsuccess)
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "MEALBOLUSSUCCESS" + dateUtil.timeString(logDateTime)
}
LOG_INJECT_MEAL_FAIL.LOG_KIND -> {
val logItem = LOG_INJECT_MEAL_FAIL.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(logDateTime, logItem.injectAmount / 100.0)
val newRecord = pumpSync.syncBolusWithPumpId(
timestamp = logDateTime,
amount = logItem.injectAmount / 100.0,
type = detailedBolusInfo?.bolusType,
pumpId = logDateTime,
pumpType = PumpType.DIACONN_G8,
pumpSerial = diaconnG8Pump.serialNo.toString())
aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT MEALBOLUS (" + pumplogKind + ") " + dateUtil.dateAndTimeString(logDateTime) + " (" + logDateTime + ")" + " Bolus: " + logItem.injectAmount / 100.0 + "U ")
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_BOLUS
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.value = if ((logItem.injectAmount / 100.0) < 0) 0.0 else (logItem.injectAmount / 100.0)
diaconnG8HistoryRecord.duration = logItem.getInjectTime()
diaconnG8HistoryRecord.bolusType = "M" // Meal bolus
diaconnG8HistoryRecord.stringValue = resourceHelper.gs(R.string.diaconn_g8_logmealfail)
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "MEALBOLUSFAIL " + dateUtil.timeString(logDateTime)
}
LOG_INJECT_NORMAL_SUCCESS.LOG_KIND -> {
val logItem = LOG_INJECT_NORMAL_SUCCESS.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(logDateTime, logItem.injectAmount / 100.0)
val newRecord = pumpSync.syncBolusWithPumpId(
timestamp = logDateTime,
amount = logItem.injectAmount / 100.0,
type = detailedBolusInfo?.bolusType,
pumpId = logDateTime,
pumpType = PumpType.DIACONN_G8,
pumpSerial = diaconnG8Pump.serialNo.toString())
aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT BOLUS (" + pumplogKind + ") " + dateUtil.dateAndTimeString(logDateTime) + " (" + logDateTime + ")" + " Bolus: " + logItem.injectAmount / 100.0 + "U ")
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_BOLUS
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.value = logItem.injectAmount / 100.0
diaconnG8HistoryRecord.duration = logItem.getInjectTime()
diaconnG8HistoryRecord.bolusType = "B" // bolus
diaconnG8HistoryRecord.stringValue = resourceHelper.gs(R.string.diaconn_g8_logsuccess)
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "BOLUSSUCCESS" + dateUtil.timeString(logDateTime)
}
LOG_INJECT_NORMAL_FAIL.LOG_KIND -> {
val logItem = LOG_INJECT_NORMAL_FAIL.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
// APS DB process
val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(logDateTime, logItem.injectAmount / 100.0)
val newRecord = pumpSync.syncBolusWithPumpId(
timestamp = logDateTime,
amount = logItem.injectAmount / 100.0,
type = detailedBolusInfo?.bolusType,
pumpId = logDateTime,
pumpType = PumpType.DIACONN_G8,
pumpSerial = diaconnG8Pump.serialNo.toString())
aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT BOLUS (" + pumplogKind + ") " + dateUtil.dateAndTimeString(logDateTime) + " (" + logDateTime + ")" + " Bolus: " + logItem.injectAmount / 100.0 + "U ")
// Diaconn History Process
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_BOLUS
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.value = if ((logItem.injectAmount / 100.0) < 0) 0.0 else (logItem.injectAmount / 100.0)
diaconnG8HistoryRecord.duration = logItem.getInjectTime()
diaconnG8HistoryRecord.bolusType = "B" // bolus
diaconnG8HistoryRecord.stringValue = getReasonName(pumplogKind, logItem.reason)
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "BOLUSFAIL " + dateUtil.timeString(logDateTime)
}
LOG_SET_SQUARE_INJECTION.LOG_KIND -> {
val logItem = LOG_SET_SQUARE_INJECTION.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
val newRecord = pumpSync.syncExtendedBolusWithPumpId(
timestamp = logDateTime,
amount = logItem.setAmount / 100.0,
duration = T.mins((logItem.getInjectTime() * 10).toLong()).msecs(),
isEmulatingTB = false,
pumpId = logDateTime,
pumpType = PumpType.DIACONN_G8,
pumpSerial = diaconnG8Pump.serialNo.toString())
aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT EXTENDEDSTART (" + pumplogKind + ") " + dateUtil.dateAndTimeString(logDateTime) + " (" + logDateTime + ")" + " Amount: " + logItem.setAmount / 100.0 + "U Duration: " + logItem.getInjectTime() * 10 + "min")
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_BOLUS
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.value = logItem.setAmount / 100.0
diaconnG8HistoryRecord.duration = logItem.getInjectTime()
diaconnG8HistoryRecord.stringValue = resourceHelper.gs(R.string.diaconn_g8_logsquarestart)
diaconnG8HistoryRecord.bolusType = "E" // Extended
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "EXTENDEDBOLUSSTART " + dateUtil.timeString(logDateTime)
}
LOG_INJECT_SQUARE_SUCCESS.LOG_KIND -> {
val logItem = LOG_INJECT_SQUARE_SUCCESS.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_BOLUS
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.duration = logItem.getInjectTime()
diaconnG8HistoryRecord.stringValue = resourceHelper.gs(R.string.diaconn_g8_logsquaresuccess)
diaconnG8HistoryRecord.bolusType = "E" // Extended
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "EXTENDEDBOLUSEND " + dateUtil.timeString(logDateTime)
}
LOG_INJECT_SQUARE_FAIL.LOG_KIND -> {
val logItem = LOG_INJECT_SQUARE_FAIL.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
val newRecord = pumpSync.syncStopExtendedBolusWithPumpId(
timestamp = logDateTime,
endPumpId = logDateTime,
pumpType = PumpType.DIACONN_G8,
pumpSerial = diaconnG8Pump.serialNo.toString())
aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT EXTENDEDSTOP (" + pumplogKind + ") " + dateUtil.dateAndTimeString(logDateTime) + " (" + logDateTime + ")" + " Delivered: " + logItem.injectAmount / 100.0 + "U RealDuration: " + logItem.getInjectTime() + "min")
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_BOLUS
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.value = logItem.injectAmount / 100.0
diaconnG8HistoryRecord.duration = logItem.getInjectTime()
diaconnG8HistoryRecord.stringValue = getReasonName(pumplogKind, logItem.reason)
diaconnG8HistoryRecord.bolusType = "E"
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "EXTENDEDBOLUSFAIL " + dateUtil.timeString(logDateTime)
}
LOG_SET_DUAL_INJECTION.LOG_KIND -> {
val logItem = LOG_SET_DUAL_INJECTION.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
// dual square 처리.
val newRecord = pumpSync.syncExtendedBolusWithPumpId(
timestamp = logDateTime,
amount = logItem.setSquareAmount / 100.0,
duration = T.mins((logItem.getInjectTime() * 10).toLong()).msecs(),
isEmulatingTB = false,
pumpId = logDateTime,
pumpType = PumpType.DIACONN_G8,
pumpSerial = diaconnG8Pump.serialNo.toString())
aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT EXTENDEDSTART (" + pumplogKind + ") " + dateUtil.dateAndTimeString(logDateTime) + " (" + logDateTime + ")" + " Amount: " + logItem.setSquareAmount / 100.0 + "U Duration: " + logItem.getInjectTime() * 10 + "min")
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_BOLUS
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.value = logItem.setSquareAmount / 100.0
diaconnG8HistoryRecord.duration = logItem.getInjectTime() * 10 // (1~30) 1:10min 30:300min
diaconnG8HistoryRecord.stringValue = resourceHelper.gs(R.string.diaconn_g8_logdualsquarestart)
diaconnG8HistoryRecord.bolusType = "D" // Extended
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "DUALEXTENTEDSTART " + dateUtil.timeString(logDateTime)
}
LOG_INJECTION_DUAL_NORMAL.LOG_KIND -> {
val logItem = LOG_INJECTION_DUAL_NORMAL.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(logDateTime, logItem.injectAmount / 100.0)
val newRecord = pumpSync.syncBolusWithPumpId(
timestamp = logDateTime,
amount = logItem.injectAmount / 100.0,
type = detailedBolusInfo?.bolusType,
pumpId = logDateTime,
pumpType = PumpType.DIACONN_G8,
pumpSerial = diaconnG8Pump.serialNo.toString())
aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT DUALBOLUS (" + pumplogKind + ") " + dateUtil.dateAndTimeString(logDateTime) + " (" + logDateTime + ")" + " Bolus: " + logItem.injectAmount / 100.0 + "U Duration: " + logItem.getInjectTime() + "min")
//Diaconn History
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_BOLUS
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.value = logItem.injectAmount / 100.0
diaconnG8HistoryRecord.duration = logItem.getInjectTime()
diaconnG8HistoryRecord.bolusType = "D" // bolus
diaconnG8HistoryRecord.stringValue = resourceHelper.gs(R.string.diaconn_g8_logdualnormalsuccess)
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "DUALBOLUS" + dateUtil.timeString(logDateTime)
}
LOG_INJECT_DUAL_SUCCESS.LOG_KIND -> {
val logItem = LOG_INJECT_DUAL_SUCCESS.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_BOLUS
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.value = logItem.injectSquareAmount / 100.0
diaconnG8HistoryRecord.duration = logItem.getInjectTime()
diaconnG8HistoryRecord.bolusType = "D"
diaconnG8HistoryRecord.stringValue = resourceHelper.gs(R.string.diaconn_g8_logdualsquaresuccess)
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "DUALBOLUS SQUARESUCCESS " + dateUtil.timeString(logDateTime)
}
LOG_INJECT_DUAL_FAIL.LOG_KIND -> {
val logItem = LOG_INJECT_DUAL_FAIL.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_BOLUS
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.value = logItem.injectNormAmount / 100.0 + logItem.injectSquareAmount / 100.0
diaconnG8HistoryRecord.duration = logItem.getInjectTime()
diaconnG8HistoryRecord.bolusType = "D"
diaconnG8HistoryRecord.stringValue = getReasonName(pumplogKind, logItem.reason)
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "DUALBOLUS FAIL " + dateUtil.timeString(logDateTime)
}
LOG_INJECTION_1HOUR_BASAL.LOG_KIND -> {
val logItem = LOG_INJECTION_1HOUR_BASAL.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_BASALHOUR
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.value = logItem.beforeAmount / 100.0
diaconnG8HistoryRecord.stringValue = "TB before: ${logItem.beforeAmount / 100.0} / TB after: ${logItem.afterAmount / 100.0}"
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "1HOUR BASAL " + dateUtil.dateAndTimeString(logDateTime)
}
LOG_SUSPEND_V2.LOG_KIND -> {
val logItem = LOG_SUSPEND_V2.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_SUSPEND
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.stringValue = resourceHelper.gs(R.string.diaconn_g8_lgosuspend, logItem.getBasalPattern())
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "SUSPEND " + dateUtil.timeString(logDateTime)
}
LOG_SUSPEND_RELEASE_V2.LOG_KIND -> {
val logItem = LOG_SUSPEND_RELEASE_V2.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_SUSPEND
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.stringValue = resourceHelper.gs(R.string.diaconn_g8_lgorelease, logItem.getBasalPattern())
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "SUSPENDRELEASE " + dateUtil.timeString(logDateTime)
}
LOG_CHANGE_INJECTOR_SUCCESS.LOG_KIND -> {
val logItem = LOG_CHANGE_INJECTOR_SUCCESS.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
if (sp.getBoolean(R.string.key_diaconn_g8_loginsulinchange, true)) {
val newRecord = pumpSync.insertTherapyEventIfNewWithTimestamp(
timestamp = logDateTime,
type = DetailedBolusInfo.EventType.INSULIN_CHANGE,
pumpId = logDateTime,
pumpType = PumpType.DIACONN_G8,
pumpSerial = diaconnG8Pump.serialNo.toString()
)
aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT INSULINCHANGE(" + pumplogKind + ") " + dateUtil.dateAndTimeString(logDateTime) + " (" + logDateTime + ")" + " Amount: " + logItem.remainAmount / 100.0 + "U")
}
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_REFILL
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.value = logItem.remainAmount / 100.0
diaconnG8HistoryRecord.stringValue = resourceHelper.gs(R.string.diaconn_g8_loginjectorprime, logItem.primeAmount / 100.0)
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "INSULINCHANGE " + dateUtil.timeString(logDateTime)
}
LOG_CHANGE_TUBE_SUCCESS.LOG_KIND -> {
val logItem = LOG_CHANGE_TUBE_SUCCESS.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
if (sp.getBoolean(R.string.key_diaconn_g8_logtubechange, true)) {
val newRecord = pumpSync.insertTherapyEventIfNewWithTimestamp(
timestamp = logDateTime,
type = DetailedBolusInfo.EventType.NOTE,
note = resourceHelper.gs(R.string.diaconn_g8_logtubeprime, logItem.primeAmount / 100.0),
pumpId = logDateTime,
pumpType = PumpType.DIACONN_G8,
pumpSerial = diaconnG8Pump.serialNo.toString()
)
aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT TUBECHANGE(" + pumplogKind + ") " + dateUtil.dateAndTimeString(logDateTime) + " (" + logDateTime + ")" + " Amount: " + logItem.primeAmount / 100.0 + "U")
}
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_REFILL
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.value = logItem.remainAmount / 100.0
diaconnG8HistoryRecord.stringValue = resourceHelper.gs(R.string.diaconn_g8_logtubeprime, logItem.primeAmount / 100.0)
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "TUBECHANGE " + dateUtil.timeString(logDateTime)
}
LOG_INJECTION_1DAY.LOG_KIND -> { // Daily Bolus Log
val logItem = LOG_INJECTION_1DAY.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_DAILY
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.dailyBolus = logItem.extAmount / 100.0 + logItem.mealAmount / 100.0
val recordDateStr = "" + diaconnG8HistoryRecord.timestamp
var recordMap: MutableMap<String, Double> = mutableMapOf("dummy" to 0.0)
if (dailyMaxvalInfo.containsKey(recordDateStr)) {
recordMap = dailyMaxvalInfo[recordDateStr]!!
} else {
recordMap["bolus"] = 0.0
recordMap["basal"] = 0.0
dailyMaxvalInfo[recordDateStr] = recordMap
}
if (diaconnG8HistoryRecord.dailyBolus > recordMap["bolus"]!!) {
recordMap["bolus"] = diaconnG8HistoryRecord.dailyBolus
} else {
diaconnG8HistoryRecord.dailyBolus = recordMap["bolus"]!!
}
if (recordMap["basal"]!! > 0.0) {
diaconnG8HistoryRecord.dailyBasal = recordMap["basal"]!!
}
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
//If it is a TDD, store it for stats also.
pumpSync.createOrUpdateTotalDailyDose(
timestamp = diaconnG8HistoryRecord.timestamp,
bolusAmount = diaconnG8HistoryRecord.dailyBolus,
basalAmount = diaconnG8HistoryRecord.dailyBasal,
totalAmount = 0.0,
pumpId = null,
pumpType = PumpType.DIACONN_G8,
diaconnG8Pump.serialNo.toString()
)
status = "DAILYBOLUS " + dateUtil.timeString(logDateTime)
}
LOG_INJECTION_1DAY_BASAL.LOG_KIND -> { // Daily Basal Log
val logItem = LOG_INJECTION_1DAY_BASAL.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_DAILY
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.dailyBasal = logItem.amount / 100.0
val recordDateStr = "" + diaconnG8HistoryRecord.timestamp
var recordMap: MutableMap<String, Double> = mutableMapOf("dummy" to 0.0)
if (dailyMaxvalInfo.containsKey(recordDateStr)) {
recordMap = dailyMaxvalInfo[recordDateStr]!!
} else {
recordMap["bolus"] = 0.0
recordMap["basal"] = 0.0
dailyMaxvalInfo[recordDateStr] = recordMap
}
if (diaconnG8HistoryRecord.dailyBasal > recordMap["basal"]!!) {
recordMap["basal"] = diaconnG8HistoryRecord.dailyBasal
} else {
diaconnG8HistoryRecord.dailyBasal = recordMap["basal"]!!
}
if (recordMap["bolus"]!! > 0.0) {
diaconnG8HistoryRecord.dailyBolus = recordMap["bolus"]!!
}
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
//If it is a TDD, store it for stats also.
// pumpSync.createOrUpdateTotalDailyDose(
// timestamp = diaconnG8HistoryRecord.timestamp,
// bolusAmount = diaconnG8HistoryRecord.dailyBolus,
// basalAmount = diaconnG8HistoryRecord.dailyBasal,
// totalAmount = 0.0,
// pumpId = null,
// pumpType = PumpType.DIACONN_G8,
// diaconnG8Pump.serialNo.toString()
// )
status = "DAILYBASAL " + dateUtil.timeString(logDateTime)
}
LOG_CHANGE_NEEDLE_SUCCESS.LOG_KIND -> {
val logItem = LOG_CHANGE_NEEDLE_SUCCESS.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
if (sp.getBoolean(R.string.key_diaconn_g8_logneedlechange, true)) {
val newRecord = pumpSync.insertTherapyEventIfNewWithTimestamp(
timestamp = logDateTime,
type = DetailedBolusInfo.EventType.CANNULA_CHANGE,
pumpId = logDateTime,
pumpType = PumpType.DIACONN_G8,
pumpSerial = diaconnG8Pump.serialNo.toString()
)
aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT NEEDLECHANGE(" + pumplogKind + ") " + dateUtil.dateAndTimeString(logDateTime) + " (" + logDateTime + ")" + " Amount: " + logItem.remainAmount / 100.0 + "U")
}
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_REFILL
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.value = logItem.remainAmount / 100.0
diaconnG8HistoryRecord.stringValue = resourceHelper.gs(R.string.diaconn_g8_logneedleprime, logItem.primeAmount / 100.0)
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "NEEDLECHANGE " + dateUtil.timeString(logDateTime)
}
LOG_TB_START_V3.LOG_KIND -> {
val logItem = LOG_TB_START_V3.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
var absoluteRate = 0.0
if (logItem.getTbInjectRateRatio() >= 50000) {
val tempBasalPercent = logItem.getTbInjectRateRatio() - 50000
absoluteRate = pumpDesc.pumpType.determineCorrectBasalSize(diaconnG8Pump.baseAmount * (tempBasalPercent / 100.0))
}
if (logItem.getTbInjectRateRatio() in 1000..1600) {
absoluteRate = (logItem.getTbInjectRateRatio() - 1000) / 100.0
}
val temporaryBasalInfo = temporaryBasalStorage.findTemporaryBasal(logDateTime, absoluteRate)
val newRecord = pumpSync.syncTemporaryBasalWithPumpId(
timestamp = logDateTime,
rate = absoluteRate,
duration = T.mins((logItem.tbTime * 15).toLong()).msecs(),
isAbsolute = true,
type = temporaryBasalInfo?.type,
pumpId = logDateTime,
pumpType = PumpType.DIACONN_G8,
pumpSerial = diaconnG8Pump.serialNo.toString())
aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT TEMPSTART (" + pumplogKind + ") " + dateUtil.dateAndTimeString(logDateTime) + " (" + logDateTime + ")" + " Ratio: " + absoluteRate + "U Duration: " + logItem.tbTime * 15 + "min")
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_TB
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.duration = logItem.tbTime * 15
diaconnG8HistoryRecord.value = absoluteRate
diaconnG8HistoryRecord.stringValue = resourceHelper.gs(R.string.diaconn_g8_logtempstart)
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "TEMPSTART " + dateUtil.timeString(logDateTime)
}
LOG_TB_STOP_V3.LOG_KIND -> {
val logItem = LOG_TB_STOP_V3.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
var absoluteRate = 0.0
if (logItem.getTbInjectRateRatio() >= 50000) {
val tempBasalPercent = logItem.getTbInjectRateRatio() - 50000
absoluteRate = diaconnG8Pump.baseAmount * (tempBasalPercent / 100.0)
}
if (logItem.getTbInjectRateRatio() in 1000..1600) {
absoluteRate = (logItem.getTbInjectRateRatio() - 1000) / 100.0
}
val newRecord = pumpSync.syncStopTemporaryBasalWithPumpId(
timestamp = logDateTime,
endPumpId = dateUtil.now(),
pumpType = PumpType.DIACONN_G8,
pumpSerial = diaconnG8Pump.serialNo.toString())
aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT TEMPSTOP (" + pumplogKind + ") " + dateUtil.dateAndTimeString(logDateTime) + " (" + logDateTime + ")")
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_TB
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.value = absoluteRate
diaconnG8HistoryRecord.stringValue = getReasonName(pumplogKind, logItem.reason)
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "TEMPSTOP " + dateUtil.timeString(logDateTime)
}
LOG_ALARM_BATTERY.LOG_KIND -> { // BATTERY SHORTAGE ALARM
val logItem = LOG_ALARM_BATTERY.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_ALARM
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.stringValue = resourceHelper.gs(R.string.diaconn_g8_logbatteryshorage)
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "BATTERYALARM " + dateUtil.timeString(logDateTime)
}
LOG_ALARM_BLOCK.LOG_KIND -> { // INJECTION BLOCKED ALARM
val logItem = LOG_ALARM_BLOCK.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_ALARM
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.value = logItem.amount / 100.0
diaconnG8HistoryRecord.stringValue = resourceHelper.gs(R.string.diaconn_g8_logalarmblock, getReasonName(pumplogKind, logItem.reason))
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "BLOCKALARM " + dateUtil.timeString(logDateTime)
}
LOG_ALARM_SHORTAGE.LOG_KIND -> { // INSULIN SHORTAGE ALARM
val logItem = LOG_ALARM_SHORTAGE.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_ALARM
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.value = logItem.remain.toDouble()
diaconnG8HistoryRecord.stringValue = resourceHelper.gs(R.string.diaconn_g8_loginsulinshorage)
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
status = "SHORTAGEALARM " + dateUtil.timeString(logDateTime)
}
LOG_RESET_SYS_V3.LOG_KIND -> {
val logItem = LOG_RESET_SYS_V3.parse(logDataToHexString)
aapsLogger.debug(LTag.PUMPCOMM, "$logItem ")
val logStartDate = DateUtils.parseDate(logItem.dttm, "yyyy-MM-dd HH:mm:ss")
val logDateTime = logStartDate.time
diaconnG8HistoryRecord.code = RecordTypes.RECORD_TYPE_ALARM
diaconnG8HistoryRecord.timestamp = logDateTime
diaconnG8HistoryRecord.stringValue = getReasonName(pumplogKind, logItem.reason)
diaconnHistoryRecordDao.createOrUpdate(diaconnG8HistoryRecord)
if (logItem.reason == 3.toByte()) {
if (sp.getBoolean(R.string.key_diaconn_g8_logbatterychange, true)) {
val newRecord = pumpSync.insertTherapyEventIfNewWithTimestamp(
timestamp = logDateTime,
type = DetailedBolusInfo.EventType.PUMP_BATTERY_CHANGE,
pumpId = logDateTime,
pumpType = PumpType.DIACONN_G8,
pumpSerial = diaconnG8Pump.serialNo.toString()
)
aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT BATTERYCHANGE(" + pumplogKind + ") " + dateUtil.dateAndTimeString(logDateTime) + " (" + logDateTime + ")" + " remainAmount: " + logItem.batteryRemain.toInt() + "%")
}
}
status = "RESET " + dateUtil.timeString(logDateTime)
}
else -> {
status = resourceHelper.gs(R.string.diaconn_g8_logsyncinprogress)
rxBus.send(EventPumpStatusChanged(status))
continue
}
}
rxBus.send(EventPumpStatusChanged(resourceHelper.gs(R.string.processinghistory) + ": " + status))
}
}
override fun getFriendlyName(): String {
return "BIG_LOG_INQUIRE_RESPONSE"
}
private fun getReasonName(logKind: Byte, reason: Byte): String{
val logInjectNormalFail: Byte = 0x0B
val logInjectSquareFail: Byte = 0x0E
val logInjectDualFail: Byte = 0x11
val logTBStopV3: Byte = 0x13
val logResetSysV3: Byte = 0x01
val logALarmBlock: Byte = 0x29
return when (logKind) {
logInjectNormalFail, logInjectSquareFail, logInjectDualFail, logTBStopV3 -> failLog(reason)
logResetSysV3 -> resetLog(reason)
logALarmBlock -> blockLog(reason)
else -> ""
}
}
private fun failLog(reason: Byte): String {
return when (reason) {
//1=Injection blockage, 2=Battery shortage, 3=Drug shortage, 4=User shutdown, 5=System reset, 6=Other, 7=Emergency shutdown
0.toByte() -> resourceHelper.gs(R.string.diaconn_g8_reasoncomplete)
1.toByte() -> resourceHelper.gs(R.string.diaconn_g8_reasoninjectonblock)
2.toByte() -> resourceHelper.gs(R.string.diaconn_g8_reasonbatteryshortage)
3.toByte() -> resourceHelper.gs(R.string.diaconn_g8_reasoninsulinshortage)
4.toByte() -> resourceHelper.gs(R.string.diaconn_g8_reasonuserstop)
5.toByte() -> resourceHelper.gs(R.string.diaconn_g8_reasonsystemreset)
6.toByte() -> resourceHelper.gs(R.string.diaconn_g8_reasonother)
7.toByte() -> resourceHelper.gs(R.string.diaconn_g8_reasonemergencystop)
else -> "No Reason"
}
}
private fun resetLog(reason: Byte): String {
return when (reason.toInt()) {
1 -> resourceHelper.gs(R.string.diaconn_g8_resetfactoryreset)
2 -> resourceHelper.gs(R.string.diaconn_g8_resetemergencyoff)
3 -> resourceHelper.gs(R.string.diaconn_g8_resetbatteryreplacement)
4 -> resourceHelper.gs(R.string.diaconn_g8_resetaftercalibration)
5 -> resourceHelper.gs(R.string.diaconn_g8_resetpreshipment)
9 -> resourceHelper.gs(R.string.diaconn_g8_resetunexpected)
else -> ""
}
}
private fun blockLog(reason: Byte): String {
return when (reason.toInt()) {
1 -> resourceHelper.gs(R.string.diacon_g8_blockbasal)
2 -> resourceHelper.gs(R.string.diacon_g8_blockmealbolus)
3 -> resourceHelper.gs(R.string.diacon_g8_blocknormalbolus)
4 -> resourceHelper.gs(R.string.diacon_g8_blocksquarebolus)
5 -> resourceHelper.gs(R.string.diacon_g8_blockdualbolus)
6 -> resourceHelper.gs(R.string.diacon_g8_blockreplacetube)
7 -> resourceHelper.gs(R.string.diacon_g8_blockreplaceneedle)
8 -> resourceHelper.gs(R.string.diacon_g8_blockreplacesyringe)
else -> ""
}
}
}

View file

@ -0,0 +1,33 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* BigMainInfoInquirePacket
*/
class BigMainInfoInquirePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x73
aapsLogger.debug(LTag.PUMPCOMM, "BigMainInfoInquirePacket init")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END)
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_BIG_MAIN_INFO_INQUIRE"
}
}

View file

@ -0,0 +1,359 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.diaconn.R
import info.nightscout.androidaps.diaconn.pumplog.PumplogUtil
import info.nightscout.androidaps.interfaces.PumpDescription
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.joda.time.DateTime
import javax.inject.Inject
import kotlin.math.floor
/**
* BigMainInfoInquireResponsePacket
*/
class BigMainInfoInquireResponsePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
@Inject lateinit var sp: SP
@Inject lateinit var resourceHelper: ResourceHelper
private var pumpDesc = PumpDescription(PumpType.DIACONN_G8)
init {
msgType = 0xb3.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "BigMainInfoInquireResponsePacket init")
}
override fun handleMessage(data: ByteArray?) {
val result = defect(data)
if (result != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "BigMainInfoInquireResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
val result2 = getByteToInt(bufferData) // 결과비트 상위 4비트 제거
if(!isSuccInquireResponseResult(result2)) {
failed = true
return
}
// 1. pump system setting info
diaconnG8Pump.systemRemainInsulin = floor(getShortToInt(bufferData) / 100.0) // 인슐린 잔량
diaconnG8Pump.systemRemainBattery = getByteToInt(bufferData) // 베터리잔량(1~100%)
diaconnG8Pump.systemBasePattern = getByteToInt(bufferData) // 기저주입 패턴(0=없음, 1=기본, 2=생활1, 3=생활2, 4=생활3, 5=닥터1, 6=닥터2)
diaconnG8Pump.systemTbStatus = getByteToInt(bufferData) // 임시기저 상태(1=임시기저 중, 2=임시기저 해제)
diaconnG8Pump.systemInjectionMealStatus = getByteToInt(bufferData) // 식사주입 상태(1=주입중, 2=주입상태아님)
diaconnG8Pump.systemInjectionSnackStatus = getByteToInt(bufferData) // 일반간식 주입 상태(1=주입중, 2=주입상태아님)
diaconnG8Pump.systemInjectionSquareStatue = getByteToInt(bufferData) // 스퀘어회식 주입 상태(1=주입중, 2=주입상태아님)
diaconnG8Pump.systemInjectionDualStatus = getByteToInt(bufferData) // 더블회식 주입 상태(1=주입중, 2=주입상태아님)
// 2. basal injection suspend status (1:stop, 2:release)
diaconnG8Pump.basePauseStatus = getByteToInt(bufferData) // 상태(1=정지,2=해제)
// 3. Pump time
diaconnG8Pump.year = getByteToInt(bufferData) + 2000 // 년 (18~99)
diaconnG8Pump.month = getByteToInt(bufferData) // 월 (1~12)
diaconnG8Pump.day = getByteToInt(bufferData) // 일 (1~31)
diaconnG8Pump.hour = getByteToInt(bufferData) // 시 (0~23)
diaconnG8Pump.minute = getByteToInt(bufferData) // 분 (0~59)
diaconnG8Pump.second = getByteToInt(bufferData) // 초 (0~59)
//4. pump system info
diaconnG8Pump.country = getByteToInt(bufferData).toChar().toString().toInt() // ASCII
diaconnG8Pump.productType = getByteToInt(bufferData).toChar().toString().toInt() // ASCII
diaconnG8Pump.makeYear = getByteToInt(bufferData)
diaconnG8Pump.makeMonth = getByteToInt(bufferData)
diaconnG8Pump.makeDay = getByteToInt(bufferData)
diaconnG8Pump.lotNo = getByteToInt(bufferData)// LOT NO
diaconnG8Pump.serialNo = getShortToInt(bufferData)
diaconnG8Pump.majorVersion = getByteToInt(bufferData)
diaconnG8Pump.minorVersion = getByteToInt(bufferData)
sp.putString(resourceHelper.gs(R.string.pumpversion), diaconnG8Pump.majorVersion.toString() + "." + diaconnG8Pump.minorVersion.toString())
// 5. pump log status
diaconnG8Pump.pumpLastLogNum = getShortToInt(bufferData) // last saved log no
diaconnG8Pump.pumpWrappingCount = getByteToInt(bufferData) // wrapping count
// 6. bolus speed status.
diaconnG8Pump.speed = getByteToInt(bufferData) // 식사주입속도
// 7. Tempbasal status
diaconnG8Pump.tbStatus = getByteToInt(bufferData) // 임시기저 상태
diaconnG8Pump.tbTime = getByteToInt(bufferData) // 임시기저시간
diaconnG8Pump.tbInjectRateRatio = getShortToInt(bufferData) //임시기저 주입량/률
diaconnG8Pump.tbElapsedTime = getShortToInt(bufferData) // 임시기저 경과시간
// 8. Basal status
diaconnG8Pump.baseStatus = getByteToInt(bufferData) // 기저주입 상태
diaconnG8Pump.baseHour = getByteToInt(bufferData) // 현재 주입시간
diaconnG8Pump.baseAmount = getShortToInt(bufferData) / 100.0 // 주입설정량
diaconnG8Pump.baseInjAmount = getShortToInt(bufferData) / 100.0 // 현재 주입량
// 9. meal bolus status
diaconnG8Pump.mealKind = getByteToInt(bufferData) //식사주입 종류
diaconnG8Pump.mealStartTime = getIntToInt(bufferData) // 주입시작시간
diaconnG8Pump.mealStatus = getByteToInt(bufferData) // 주입상태
diaconnG8Pump.mealAmount = getShortToInt(bufferData) / 100.0 // 주입설정량
diaconnG8Pump.mealInjAmount = getShortToInt(bufferData) / 100.0 // 주입량
diaconnG8Pump.mealSpeed = getByteToInt(bufferData) // 주입속도
// 10. snack bolus status
diaconnG8Pump.snackStatus = getByteToInt(bufferData) //주입상태
diaconnG8Pump.snackAmount = getShortToInt(bufferData) / 100.0 // 주입설정량
diaconnG8Pump.snackInjAmount = getShortToInt(bufferData) / 100.0 // 현재주입량
diaconnG8Pump.snackSpeed = getByteToInt(bufferData) //주입속도
// 11. square(extended) bolus status
diaconnG8Pump.squareStatus = getByteToInt(bufferData) // 주입상태
diaconnG8Pump.squareTime = getShortToInt(bufferData) // 설정 주입시간(10~300분)
diaconnG8Pump.squareInjTime = getShortToInt(bufferData) // 경과 주입시간(10~300분)
diaconnG8Pump.squareAmount = getShortToInt(bufferData) / 100.0 // 주입 설정량
diaconnG8Pump.squareInjAmount = getShortToInt(bufferData) / 100.0 // 현재 주입량
// 12. daul bolus status
diaconnG8Pump.dualStatus = getByteToInt(bufferData) // 주입상태
diaconnG8Pump.dualAmount = getShortToInt(bufferData) / 100.0 // 일반주입 설정량
diaconnG8Pump.dualInjAmount = getShortToInt(bufferData) / 100.0 // 일반주입량
diaconnG8Pump.dualSquareTime = getShortToInt(bufferData) // 스퀘어주입 설정시간(10~300분)
diaconnG8Pump.dualInjSquareTime = getShortToInt(bufferData) // 스퀘어주입 경과시간(10~300분)
diaconnG8Pump.dualSquareAmount = getShortToInt(bufferData) / 100.0 // 스퀘어주입 설정량
diaconnG8Pump.dualInjSquareAmount = getShortToInt(bufferData) / 100.0 // 스퀘어주입량
// 13. last injection status
diaconnG8Pump.recentKind1 = getByteToInt(bufferData) // 최근-1 주입 종류(1=식사, 2=일반간식, 3=스퀘어회식, 4=더블회식)
diaconnG8Pump.recentTime1 = getIntToInt(bufferData) // 최근-1 주입 시간
diaconnG8Pump.recentAmount1 = getShortToInt(bufferData) / 100.0 // 최근-1 주입량
diaconnG8Pump.recentKind2 = getByteToInt(bufferData) // 최근-2 주입 종류(1=식사, 2=일반간식, 3=스퀘어회식, 4=더블회식)
diaconnG8Pump.recentTime2 = getIntToInt(bufferData) // 최근-2 주입 시간
diaconnG8Pump.recentAmount2 = getShortToInt(bufferData) / 100.0 // 최근-2 주입량
// 14. daily injection status
diaconnG8Pump.todayBaseAmount = getShortToInt(bufferData) / 100.0 // 기저주입 총량
diaconnG8Pump.todayMealAmount = getShortToInt(bufferData) / 100.0 // 식사주입 총량
diaconnG8Pump.todaySnackAmount = getShortToInt(bufferData) / 100.0 // 회식주입 총량
// 15. meat setting status
diaconnG8Pump.morningHour = getByteToInt(bufferData) // 아침 개시 시간(0~23)
diaconnG8Pump.morningAmount = getShortToInt(bufferData) / 100.0 // 아침 식전량
diaconnG8Pump.lunchHour = getByteToInt(bufferData) // 점심 개시 시간(0~23)
diaconnG8Pump.lunchAmount = getShortToInt(bufferData) / 100.0 // 점심 식전량
diaconnG8Pump.dinnerHour = getByteToInt(bufferData) // 저녁 개시 시간(0~23)
diaconnG8Pump.dinnerAmount = getShortToInt(bufferData) / 100.0 // 저녁 식전량
// 16. basal injection status at this hour
diaconnG8Pump.currentBasePattern = getByteToInt(bufferData) // 패턴 종류 (1=기본, 2=생활1, 3=생활2, 4=생활3, 5=닥터1, 6=닥터2)
diaconnG8Pump.currentBaseHour = getByteToInt(bufferData) // 현재주입시간(0~23)
diaconnG8Pump.currentBaseTbBeforeAmount = getShortToInt(bufferData) / 100.0 // 해당시간의 임시기저 계산 전 기저주입량: 기저주입막힘 발생 시 기저주입 막힘량 제외, 기저정지로 인해 주입되지 않은 량 제외, 리셋으로 인해 주입되지 않은 량 제외(47.5=4750)
diaconnG8Pump.currentBaseTbAfterAmount = getShortToInt(bufferData)/ 100.0 // 해당시간의 임시기저 계산 후 기저주입량: 기저주입막힘 발생 시 기저주입 막힘량 제외, 기저정지로 인해 주입되지 않은 량 제외, 리셋으로 인해 주입되지 않은 량 제외(47.5=4750)
// 17. saved basal pattern status
diaconnG8Pump.baseAmount1 = getShortToInt(bufferData) / 100.0 // 주입량 1(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount2 = getShortToInt(bufferData) / 100.0 // 주입량 2(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount3 = getShortToInt(bufferData) / 100.0 // 주입량 3(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount4 = getShortToInt(bufferData) / 100.0 // 주입량 4(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount5 = getShortToInt(bufferData) / 100.0 // 주입량 5(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount6 = getShortToInt(bufferData) / 100.0 // 주입량 6(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount7 = getShortToInt(bufferData) / 100.0 // 주입량 7(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount8 = getShortToInt(bufferData) / 100.0 // 주입량 8(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount9 = getShortToInt(bufferData) / 100.0 // 주입량 9(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount10 = getShortToInt(bufferData) / 100.0 // 주입량 10(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount11 = getShortToInt(bufferData) / 100.0 // 주입량 11(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount12 = getShortToInt(bufferData) / 100.0 // 주입량 12(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount13 = getShortToInt(bufferData) / 100.0 // 주입량 13(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount14 = getShortToInt(bufferData) / 100.0 // 주입량 14(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount15 = getShortToInt(bufferData) / 100.0 // 주입량 15(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount16 = getShortToInt(bufferData) / 100.0 // 주입량 16(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount17 = getShortToInt(bufferData) / 100.0 // 주입량 17(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount18 = getShortToInt(bufferData) / 100.0 // 주입량 18(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount19 = getShortToInt(bufferData) / 100.0 // 주입량 19(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount20 = getShortToInt(bufferData) / 100.0 // 주입량 20(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount21 = getShortToInt(bufferData) / 100.0 // 주입량 21(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount22 = getShortToInt(bufferData) / 100.0 // 주입량 22(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount23 = getShortToInt(bufferData) / 100.0 // 주입량 23(량*100, 23.25->2325, 15.2->1520)
diaconnG8Pump.baseAmount24 = getShortToInt(bufferData) / 100.0 // 주입량 24(량*100, 23.25->2325, 15.2->1520)
// tempbasal setting status
diaconnG8Pump.isTempBasalInProgress = diaconnG8Pump.tbStatus == 1
aapsLogger.debug(LTag.PUMPCOMM, "isTempBasalInProgress > " + diaconnG8Pump.isTempBasalInProgress)
// if rate type is percent
if (diaconnG8Pump.tbInjectRateRatio >= 50000) {
diaconnG8Pump.tempBasalPercent = diaconnG8Pump.tbInjectRateRatio - 50000
var absoluteValue = diaconnG8Pump.baseAmount * (diaconnG8Pump.tempBasalPercent / 100.0)
absoluteValue = pumpDesc.pumpType.determineCorrectBasalSize(absoluteValue)
diaconnG8Pump.tempBasalAbsoluteRate = absoluteValue
}
// if rate type is absolute
if(diaconnG8Pump.tbInjectRateRatio in 1000..1600) {
diaconnG8Pump.tbInjectAbsoluteValue = (diaconnG8Pump.tbInjectRateRatio -1000) / 100.0
diaconnG8Pump.tempBasalAbsoluteRate = diaconnG8Pump.tbInjectAbsoluteValue
}
// extended bolus status
diaconnG8Pump.isExtendedInProgress = diaconnG8Pump.squareStatus == 1 || diaconnG8Pump.dualStatus == 1
if(diaconnG8Pump.squareStatus == 1) { //square
diaconnG8Pump.extendedBolusMinutes = diaconnG8Pump.squareTime
diaconnG8Pump.extendedBolusAbsoluteRate = diaconnG8Pump.squareAmount
diaconnG8Pump.extendedBolusPassedMinutes = diaconnG8Pump.squareInjTime
diaconnG8Pump.extendedBolusRemainingMinutes = diaconnG8Pump.squareTime - diaconnG8Pump.squareInjTime
diaconnG8Pump.extendedBolusDeliveredSoFar = diaconnG8Pump.squareInjAmount
} else if (diaconnG8Pump.dualStatus == 1) { //dual
diaconnG8Pump.extendedBolusMinutes = diaconnG8Pump.dualSquareTime
diaconnG8Pump.extendedBolusAbsoluteRate = diaconnG8Pump.dualSquareAmount
diaconnG8Pump.extendedBolusPassedMinutes = diaconnG8Pump.dualInjSquareTime
diaconnG8Pump.extendedBolusRemainingMinutes = diaconnG8Pump.dualSquareTime - diaconnG8Pump.dualInjSquareTime
diaconnG8Pump.extendedBolusDeliveredSoFar = diaconnG8Pump.dualInjSquareAmount
}
// pump time setting 'yyyy-MM-dd'T'HH:mm:ssZ' “2019-07-04T12:30:30+0530”
val time = DateTime(diaconnG8Pump.year, diaconnG8Pump.month, diaconnG8Pump.day, diaconnG8Pump.hour, diaconnG8Pump.minute, diaconnG8Pump.second)
diaconnG8Pump.setPumpTime(time.millis)
aapsLogger.debug(LTag.PUMPCOMM, "Pump time " + dateUtil.dateAndTimeString(time.millis))
// basal pattern from pump
diaconnG8Pump.pumpProfiles = Array(4) { Array(24) { 0.0 } }
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][0] = diaconnG8Pump.baseAmount1
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][1] = diaconnG8Pump.baseAmount2
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][2] = diaconnG8Pump.baseAmount3
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][3] = diaconnG8Pump.baseAmount4
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][4] = diaconnG8Pump.baseAmount5
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][5] = diaconnG8Pump.baseAmount6
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][6] = diaconnG8Pump.baseAmount7
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][7] = diaconnG8Pump.baseAmount8
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][8] = diaconnG8Pump.baseAmount9
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][9] = diaconnG8Pump.baseAmount10
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][10] = diaconnG8Pump.baseAmount11
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][11] = diaconnG8Pump.baseAmount12
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][12] = diaconnG8Pump.baseAmount13
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][13] = diaconnG8Pump.baseAmount14
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][14] = diaconnG8Pump.baseAmount15
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][15] = diaconnG8Pump.baseAmount16
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][16] = diaconnG8Pump.baseAmount17
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][17] = diaconnG8Pump.baseAmount18
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][18] = diaconnG8Pump.baseAmount19
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][19] = diaconnG8Pump.baseAmount20
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][20] = diaconnG8Pump.baseAmount21
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][21] = diaconnG8Pump.baseAmount22
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][22] = diaconnG8Pump.baseAmount23
diaconnG8Pump.pumpProfiles!![diaconnG8Pump.activeProfile][23] = diaconnG8Pump.baseAmount24
//incarnation no 처리
diaconnG8Pump.isPumpVersionGe2_63 = PumplogUtil.isPumpVersionGe(sp.getString(resourceHelper.gs(R.string.pumpversion), ""),2, 63)
aapsLogger.debug(LTag.PUMPCOMM, "result > " + diaconnG8Pump.result)
aapsLogger.debug(LTag.PUMPCOMM, "systemRemainInsulin > " + diaconnG8Pump.systemRemainInsulin)
aapsLogger.debug(LTag.PUMPCOMM, "systemRemainBattery > " + diaconnG8Pump.systemRemainBattery)
aapsLogger.debug(LTag.PUMPCOMM, "systemBasePattern > " + diaconnG8Pump.systemBasePattern)
aapsLogger.debug(LTag.PUMPCOMM, "systemTbStatus > " + diaconnG8Pump.systemTbStatus)
aapsLogger.debug(LTag.PUMPCOMM, "systemInjectionMealStatus > " + diaconnG8Pump.systemInjectionMealStatus)
aapsLogger.debug(LTag.PUMPCOMM, "systemInjectionSnackStatus > " + diaconnG8Pump.systemInjectionSnackStatus)
aapsLogger.debug(LTag.PUMPCOMM, "systemInjectionSquareStatue > " + diaconnG8Pump.systemInjectionSquareStatue)
aapsLogger.debug(LTag.PUMPCOMM, "systemInjectionDualStatus > " + diaconnG8Pump.systemInjectionDualStatus)
aapsLogger.debug(LTag.PUMPCOMM, "basePauseStatus > " + diaconnG8Pump.basePauseStatus)
aapsLogger.debug(LTag.PUMPCOMM, "year > " + diaconnG8Pump.year)
aapsLogger.debug(LTag.PUMPCOMM, "month > " + diaconnG8Pump.month)
aapsLogger.debug(LTag.PUMPCOMM, "day > " + diaconnG8Pump.day)
aapsLogger.debug(LTag.PUMPCOMM, "hour > " + diaconnG8Pump.hour)
aapsLogger.debug(LTag.PUMPCOMM, "minute > " + diaconnG8Pump.minute)
aapsLogger.debug(LTag.PUMPCOMM, "second > " + diaconnG8Pump.second)
aapsLogger.debug(LTag.PUMPCOMM, "country > " + diaconnG8Pump.country)
aapsLogger.debug(LTag.PUMPCOMM, "productType > " + diaconnG8Pump.productType)
aapsLogger.debug(LTag.PUMPCOMM, "makeYear > " + diaconnG8Pump.makeYear)
aapsLogger.debug(LTag.PUMPCOMM, "makeMonth > " + diaconnG8Pump.makeMonth)
aapsLogger.debug(LTag.PUMPCOMM, "makeDay > " + diaconnG8Pump.makeDay)
aapsLogger.debug(LTag.PUMPCOMM, "lotNo > " + diaconnG8Pump.lotNo)
aapsLogger.debug(LTag.PUMPCOMM, "serialNo > " + diaconnG8Pump.serialNo)
aapsLogger.debug(LTag.PUMPCOMM, "majorVersion > " + diaconnG8Pump.majorVersion)
aapsLogger.debug(LTag.PUMPCOMM, "minorVersion > " + diaconnG8Pump.minorVersion)
aapsLogger.debug(LTag.PUMPCOMM, "lastNum > " + diaconnG8Pump.pumpLastLogNum)
aapsLogger.debug(LTag.PUMPCOMM, "wrappingCount > " + diaconnG8Pump.pumpWrappingCount)
aapsLogger.debug(LTag.PUMPCOMM, "speed > " + diaconnG8Pump.speed)
aapsLogger.debug(LTag.PUMPCOMM, "tbStatus > " + diaconnG8Pump.tbStatus)
aapsLogger.debug(LTag.PUMPCOMM, "tbTime> " + diaconnG8Pump.tbTime)
aapsLogger.debug(LTag.PUMPCOMM, "tbInjectRateRatio > " + diaconnG8Pump.tbInjectRateRatio)
aapsLogger.debug(LTag.PUMPCOMM, "tbElapsedTime > " + diaconnG8Pump.tbElapsedTime)
aapsLogger.debug(LTag.PUMPCOMM, "baseStatus > " + diaconnG8Pump.baseStatus)
aapsLogger.debug(LTag.PUMPCOMM, "baseHour > " + diaconnG8Pump.baseHour)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount > " + diaconnG8Pump.baseAmount)
aapsLogger.debug(LTag.PUMPCOMM, "baseInjAmount > " + diaconnG8Pump.baseInjAmount)
aapsLogger.debug(LTag.PUMPCOMM, "mealKind > " + diaconnG8Pump.mealKind)
aapsLogger.debug(LTag.PUMPCOMM, "mealStartTime > " + diaconnG8Pump.mealStartTime)
aapsLogger.debug(LTag.PUMPCOMM, "mealStatus > " + diaconnG8Pump.mealStatus)
aapsLogger.debug(LTag.PUMPCOMM, "mealAmount > " + diaconnG8Pump.mealAmount)
aapsLogger.debug(LTag.PUMPCOMM, "mealInjAmount > " + diaconnG8Pump.mealInjAmount)
aapsLogger.debug(LTag.PUMPCOMM, "mealSpeed > " + diaconnG8Pump.mealSpeed)
aapsLogger.debug(LTag.PUMPCOMM, "snackStatus > " + diaconnG8Pump.snackStatus)
aapsLogger.debug(LTag.PUMPCOMM, "snackAmount > " + diaconnG8Pump.snackAmount)
aapsLogger.debug(LTag.PUMPCOMM, "snackInjAmount > " + diaconnG8Pump.snackInjAmount)
aapsLogger.debug(LTag.PUMPCOMM, "snackSpeed > " + diaconnG8Pump.snackSpeed)
aapsLogger.debug(LTag.PUMPCOMM, "squareStatus > " + diaconnG8Pump.squareStatus)
aapsLogger.debug(LTag.PUMPCOMM, "squareTime > " + diaconnG8Pump.squareTime)
aapsLogger.debug(LTag.PUMPCOMM, "squareInjTime > " + diaconnG8Pump.squareInjTime)
aapsLogger.debug(LTag.PUMPCOMM, "squareAmount > " + diaconnG8Pump.squareAmount)
aapsLogger.debug(LTag.PUMPCOMM, "squareInjAmount > " + diaconnG8Pump.squareInjAmount)
aapsLogger.debug(LTag.PUMPCOMM, "dualStatus > " + diaconnG8Pump.dualStatus)
aapsLogger.debug(LTag.PUMPCOMM, "dualAmount > " + diaconnG8Pump.dualAmount)
aapsLogger.debug(LTag.PUMPCOMM, "dualInjAmount > " + diaconnG8Pump.dualInjAmount)
aapsLogger.debug(LTag.PUMPCOMM, "dualSquareTime > " + diaconnG8Pump.dualSquareTime)
aapsLogger.debug(LTag.PUMPCOMM, "dualInjSquareTime > " + diaconnG8Pump.dualInjSquareTime)
aapsLogger.debug(LTag.PUMPCOMM, "dualSquareAmount > " + diaconnG8Pump.dualSquareAmount)
aapsLogger.debug(LTag.PUMPCOMM, "dualInjSquareAmount> " + diaconnG8Pump.dualInjSquareAmount)
aapsLogger.debug(LTag.PUMPCOMM, "recentKind1 > " + diaconnG8Pump.recentKind1)
aapsLogger.debug(LTag.PUMPCOMM, "recentTime1 > " + diaconnG8Pump.recentTime1)
aapsLogger.debug(LTag.PUMPCOMM, "recentAmount1 > " + diaconnG8Pump.recentAmount1)
aapsLogger.debug(LTag.PUMPCOMM, "recentKind2 > " + diaconnG8Pump.recentKind2)
aapsLogger.debug(LTag.PUMPCOMM, "recentTime2 > " + diaconnG8Pump.recentTime2)
aapsLogger.debug(LTag.PUMPCOMM, "recentAmount2 > " + diaconnG8Pump.recentAmount2)
aapsLogger.debug(LTag.PUMPCOMM, "todayBaseAmount > " + diaconnG8Pump.todayBaseAmount)
aapsLogger.debug(LTag.PUMPCOMM, "todayMealAmount > " + diaconnG8Pump.todayMealAmount)
aapsLogger.debug(LTag.PUMPCOMM, "todaySnackAmount > " + diaconnG8Pump.todaySnackAmount)
aapsLogger.debug(LTag.PUMPCOMM, "morningHour > " + diaconnG8Pump.morningHour)
aapsLogger.debug(LTag.PUMPCOMM, "morningAmount > " + diaconnG8Pump.morningAmount)
aapsLogger.debug(LTag.PUMPCOMM, "lunchHour > " + diaconnG8Pump.lunchHour)
aapsLogger.debug(LTag.PUMPCOMM, "lunchAmount > " + diaconnG8Pump.lunchAmount)
aapsLogger.debug(LTag.PUMPCOMM, "dinnerHour > " + diaconnG8Pump.dinnerHour)
aapsLogger.debug(LTag.PUMPCOMM, "dinnerAmount > " + diaconnG8Pump.dinnerAmount)
aapsLogger.debug(LTag.PUMPCOMM, "currentBasePattern > " + diaconnG8Pump.currentBasePattern)
aapsLogger.debug(LTag.PUMPCOMM, "currentBaseHour > " + diaconnG8Pump.currentBaseHour)
aapsLogger.debug(LTag.PUMPCOMM, "currentBaseTbBeforeAmount > " + diaconnG8Pump.currentBaseTbBeforeAmount)
aapsLogger.debug(LTag.PUMPCOMM, "currentBaseTbAfterAmount > " + diaconnG8Pump.currentBaseTbAfterAmount)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount1 > " + diaconnG8Pump.baseAmount1)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount2 > " + diaconnG8Pump.baseAmount2)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount3 > " + diaconnG8Pump.baseAmount3)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount4 > " + diaconnG8Pump.baseAmount4)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount5 > " + diaconnG8Pump.baseAmount5)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount6 > " + diaconnG8Pump.baseAmount6)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount7 > " + diaconnG8Pump.baseAmount7)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount8 > " + diaconnG8Pump.baseAmount8)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount9 > " + diaconnG8Pump.baseAmount9)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount10 > " + diaconnG8Pump.baseAmount10)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount11 > " + diaconnG8Pump.baseAmount11)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount12 > " + diaconnG8Pump.baseAmount12)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount13 > " + diaconnG8Pump.baseAmount13)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount14 > " + diaconnG8Pump.baseAmount14)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount15 > " + diaconnG8Pump.baseAmount15)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount16 > " + diaconnG8Pump.baseAmount16)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount17 > " + diaconnG8Pump.baseAmount17)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount18 > " + diaconnG8Pump.baseAmount18)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount19 > " + diaconnG8Pump.baseAmount19)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount20 > " + diaconnG8Pump.baseAmount20)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount21 > " + diaconnG8Pump.baseAmount21)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount22 > " + diaconnG8Pump.baseAmount22)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount23 > " + diaconnG8Pump.baseAmount23)
aapsLogger.debug(LTag.PUMPCOMM, "baseAmount24 > " + diaconnG8Pump.baseAmount24)
}
override fun getFriendlyName(): String {
return "PUMP_BIG_MAIN_INFO_INQUIRE_RESPONSE"
}
}

View file

@ -0,0 +1,27 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* BolusSpeedInquirePacket
*/
class BolusSpeedInquirePacket(injector: HasAndroidInjector) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x45.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "BolusSpeedInquirePacket init ")
}
override fun encode(msgSeq:Int): ByteArray {
return suffixEncode(prefixEncode(msgType, msgSeq, MSG_CON_END))
}
override fun getFriendlyName(): String {
return "PUMP_BOLUS_SPEED_INQUIRE"
}
}

View file

@ -0,0 +1,49 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.utils.sharedPreferences.SP
import javax.inject.Inject
/**
* BolusSpeedInquireResponsePacket
*/
class BolusSpeedInquireResponsePacket(injector: HasAndroidInjector) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
@Inject lateinit var sp: SP
init {
msgType = 0x85.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "BolusSpeedInquireResponsePacket init")
}
override fun handleMessage(data: ByteArray?) {
val defectResult = defect(data)
if (defectResult != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "BolusSpeedInquireResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
val result = getByteToInt(bufferData)
if(!isSuccInquireResponseResult(result)) {
failed = true
return
}
diaconnG8Pump.speed = getByteToInt(bufferData) //주입속도
sp.putString("g8_bolusspeed", diaconnG8Pump.speed.toString())
aapsLogger.debug(LTag.PUMPCOMM, "Result --> ${diaconnG8Pump.result}")
aapsLogger.debug(LTag.PUMPCOMM, "bolusSpeed > " + diaconnG8Pump.speed)
}
override fun getFriendlyName(): String {
return "PUMP_BOLUS_SPEED_INQUIRE_RESPONSE"
}
}

View file

@ -0,0 +1,32 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* BolusSpeedSettingPacket
*/
class BolusSpeedSettingPacket(
injector: HasAndroidInjector,
private var type: Int
) : DiaconnG8Packet(injector) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x05
aapsLogger.debug(LTag.PUMPCOMM, "BolusSpeedSettingPacket init")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END)
buffer.put(type.toByte()) // 명령코드
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_BOLUS_SPEED_SETTING_PACKET"
}
}

View file

@ -0,0 +1,40 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.utils.sharedPreferences.SP
import javax.inject.Inject
/**
* BolusSpeedSettingReportPacket
*/
class BolusSpeedSettingReportPacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
@Inject lateinit var sp: SP
init {
msgType = 0xC5.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "BolusSpeedSettingReportPacket init ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "BolusSpeedSettingReportPacket Report Packet Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
diaconnG8Pump.speed = getByteToInt(bufferData) // speed result
sp.putBoolean("diaconn_g8_isbolusspeedsync", true)
aapsLogger.debug(LTag.PUMPCOMM, "bolusSpeed --> ${diaconnG8Pump.speed }")
}
override fun getFriendlyName(): String {
return "PUMP_BOLUS_SPEED_SETTING_REPORT"
}
}

View file

@ -0,0 +1,47 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* BolusSpeedSettingResponsePacket
*/
class BolusSpeedSettingResponsePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
var result = 0
init {
msgType = 0x85.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "BolusSpeedSettingResponsePacket init")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "BolusSpeedSettingResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
result = getByteToInt(bufferData)
if(!isSuccSettingResponseResult(result)) {
diaconnG8Pump.bolusStartErrorCode = result
failed = true
return
}
diaconnG8Pump.otpNumber = getIntToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "Result --> $result")
aapsLogger.debug(LTag.PUMPCOMM, "otpNumber --> ${diaconnG8Pump.otpNumber}")
}
override fun getFriendlyName(): String {
return "PUMP_BOLUS_SPEED_SETTING_RESPONSE"
}
}

View file

@ -0,0 +1,38 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* ConfirmReportPacket
*/
class ConfirmReportPacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
var reqMsgType:Int? = null
init {
msgType = 0xE8.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "ConfirmReportPacket init ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "ConfirmReportPacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
reqMsgType = getByteToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "Pump Report Confirm reqMsgType --> ${reqMsgType}")
}
override fun getFriendlyName(): String {
return "PUMP_CONFIRM_REPORT"
}
}

View file

@ -0,0 +1,300 @@
package info.nightscout.androidaps.diaconn.packet;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import javax.inject.Inject;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.utils.DateUtil;
public class DiaconnG8Packet {
@Inject AAPSLogger aapsLogger;
@Inject DateUtil dateUtil;
protected HasAndroidInjector injector;
private boolean received;
public boolean failed;
public byte msgType;
public static final int MSG_LEN = 20; // 메시지 길이(20바이트 패킷)
public static final int MSG_LEN_BIG = 182; // 메시지 길이(182바이트 대량패킷)
public static final byte SOP = (byte) 0xef; // 패킷 시작 바이트(20바이트 패킷)
public static final byte SOP_BIG = (byte) 0xed; // 대량 패킷 시작 바이트(182바이트 대량패킷)
public static final byte MSG_TYPE_LOC = 1; // 메시지 종류 위치
public static final byte MSG_SEQ_LOC = 2; // 메시지 시퀀스번호 위치
public static final byte BT_MSG_DATA_LOC = 4; // 데이터 위치
public static final byte MSG_PAD = (byte) 0xff; // 메시지 뒷부분 빈공간을 채우는
public static final byte MSG_CON_END = (byte) 0x00; // 패킷 내용
public static final byte MSG_CON_CONTINUE = (byte) 0x01; // 패킷 내용 계속
/**
* CRC 정보
*/
private static final byte[] crc_table = {
(byte) 0x00, (byte) 0x25, (byte) 0x4A, (byte) 0x6F, (byte) 0x94, (byte) 0xB1, (byte) 0xDE, (byte) 0xFB,
(byte) 0x0D, (byte) 0x28, (byte) 0x47, (byte) 0x62, (byte) 0x99, (byte) 0xBC, (byte) 0xD3, (byte) 0xF6,
(byte) 0x1A, (byte) 0x3F, (byte) 0x50, (byte) 0x75, (byte) 0x8E, (byte) 0xAB, (byte) 0xC4, (byte) 0xE1,
(byte) 0x17, (byte) 0x32, (byte) 0x5D, (byte) 0x78, (byte) 0x83, (byte) 0xA6, (byte) 0xC9, (byte) 0xEC,
(byte) 0x34, (byte) 0x11, (byte) 0x7E, (byte) 0x5B, (byte) 0xA0, (byte) 0x85, (byte) 0xEA, (byte) 0xCF,
(byte) 0x39, (byte) 0x1C, (byte) 0x73, (byte) 0x56, (byte) 0xAD, (byte) 0x88, (byte) 0xE7, (byte) 0xC2,
(byte) 0x2E, (byte) 0x0B, (byte) 0x64, (byte) 0x41, (byte) 0xBA, (byte) 0x9F, (byte) 0xF0, (byte) 0xD5,
(byte) 0x23, (byte) 0x06, (byte) 0x69, (byte) 0x4C, (byte) 0xB7, (byte) 0x92, (byte) 0xFD, (byte) 0xD8,
(byte) 0x68, (byte) 0x4D, (byte) 0x22, (byte) 0x07, (byte) 0xFC, (byte) 0xD9, (byte) 0xB6, (byte) 0x93,
(byte) 0x65, (byte) 0x40, (byte) 0x2F, (byte) 0x0A, (byte) 0xF1, (byte) 0xD4, (byte) 0xBB, (byte) 0x9E,
(byte) 0x72, (byte) 0x57, (byte) 0x38, (byte) 0x1D, (byte) 0xE6, (byte) 0xC3, (byte) 0xAC, (byte) 0x89,
(byte) 0x7F, (byte) 0x5A, (byte) 0x35, (byte) 0x10, (byte) 0xEB, (byte) 0xCE, (byte) 0xA1, (byte) 0x84,
(byte) 0x5C, (byte) 0x79, (byte) 0x16, (byte) 0x33, (byte) 0xC8, (byte) 0xED, (byte) 0x82, (byte) 0xA7,
(byte) 0x51, (byte) 0x74, (byte) 0x1B, (byte) 0x3E, (byte) 0xC5, (byte) 0xE0, (byte) 0x8F, (byte) 0xAA,
(byte) 0x46, (byte) 0x63, (byte) 0x0C, (byte) 0x29, (byte) 0xD2, (byte) 0xF7, (byte) 0x98, (byte) 0xBD,
(byte) 0x4B, (byte) 0x6E, (byte) 0x01, (byte) 0x24, (byte) 0xDF, (byte) 0xFA, (byte) 0x95, (byte) 0xB0,
(byte) 0xD0, (byte) 0xF5, (byte) 0x9A, (byte) 0xBF, (byte) 0x44, (byte) 0x61, (byte) 0x0E, (byte) 0x2B,
(byte) 0xDD, (byte) 0xF8, (byte) 0x97, (byte) 0xB2, (byte) 0x49, (byte) 0x6C, (byte) 0x03, (byte) 0x26,
(byte) 0xCA, (byte) 0xEF, (byte) 0x80, (byte) 0xA5, (byte) 0x5E, (byte) 0x7B, (byte) 0x14, (byte) 0x31,
(byte) 0xC7, (byte) 0xE2, (byte) 0x8D, (byte) 0xA8, (byte) 0x53, (byte) 0x76, (byte) 0x19, (byte) 0x3C,
(byte) 0xE4, (byte) 0xC1, (byte) 0xAE, (byte) 0x8B, (byte) 0x70, (byte) 0x55, (byte) 0x3A, (byte) 0x1F,
(byte) 0xE9, (byte) 0xCC, (byte) 0xA3, (byte) 0x86, (byte) 0x7D, (byte) 0x58, (byte) 0x37, (byte) 0x12,
(byte) 0xFE, (byte) 0xDB, (byte) 0xB4, (byte) 0x91, (byte) 0x6A, (byte) 0x4F, (byte) 0x20, (byte) 0x05,
(byte) 0xF3, (byte) 0xD6, (byte) 0xB9, (byte) 0x9C, (byte) 0x67, (byte) 0x42, (byte) 0x2D, (byte) 0x08,
(byte) 0xB8, (byte) 0x9D, (byte) 0xF2, (byte) 0xD7, (byte) 0x2C, (byte) 0x09, (byte) 0x66, (byte) 0x43,
(byte) 0xB5, (byte) 0x90, (byte) 0xFF, (byte) 0xDA, (byte) 0x21, (byte) 0x04, (byte) 0x6B, (byte) 0x4E,
(byte) 0xA2, (byte) 0x87, (byte) 0xE8, (byte) 0xCD, (byte) 0x36, (byte) 0x13, (byte) 0x7C, (byte) 0x59,
(byte) 0xAF, (byte) 0x8A, (byte) 0xE5, (byte) 0xC0, (byte) 0x3B, (byte) 0x1E, (byte) 0x71, (byte) 0x54,
(byte) 0x8C, (byte) 0xA9, (byte) 0xC6, (byte) 0xE3, (byte) 0x18, (byte) 0x3D, (byte) 0x52, (byte) 0x77,
(byte) 0x81, (byte) 0xA4, (byte) 0xCB, (byte) 0xEE, (byte) 0x15, (byte) 0x30, (byte) 0x5F, (byte) 0x7A,
(byte) 0x96, (byte) 0xB3, (byte) 0xDC, (byte) 0xF9, (byte) 0x02, (byte) 0x27, (byte) 0x48, (byte) 0x6D,
(byte) 0x9B, (byte) 0xBE, (byte) 0xD1, (byte) 0xF4, (byte) 0x0F, (byte) 0x2A, (byte) 0x45, (byte) 0x60
};
public DiaconnG8Packet(HasAndroidInjector injector) {
this.received = false;
this.failed = false;
this.injector = injector;
injector.androidInjector().inject(this);
}
public boolean success() {
return !failed;
}
public void setReceived() {
received = true;
}
public boolean isReceived() {
return received;
}
// 패킷 인코딩 앞부분
public ByteBuffer prefixEncode(byte msgType, int msgSeq, byte msgConEnd) {
ByteBuffer buffer = ByteBuffer.allocate(MSG_LEN);
buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.put(SOP);
buffer.put(msgType);
buffer.put((byte) msgSeq);
buffer.put(msgConEnd);
return buffer;
}
// 패킷 인코딩 뒷부분
public byte[] suffixEncode(ByteBuffer buffer) {
int remainSize = MSG_LEN - buffer.position() - 1;
for (int i = 0; i < remainSize; i++) {
buffer.put(MSG_PAD);
}
byte crc = getCRC(buffer.array(), MSG_LEN - 1);
buffer.put(crc);
return buffer.array();
}
// 패킷 디코딩 앞부분
protected static ByteBuffer prefixDecode(byte[] bytes) {
ByteBuffer buffer = ByteBuffer.wrap(bytes);
buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.position(BT_MSG_DATA_LOC);
return buffer;
}
public int getType(byte[] bytes) {
return (bytes[MSG_TYPE_LOC] & 0xC0) >> 6;
} //상위 2비트 획득
public int getCmd(byte[] bytes) {
return bytes[MSG_TYPE_LOC];
}
public int getSeq(byte[] bytes) {
return bytes[MSG_SEQ_LOC];
}
public static int getByteToInt(ByteBuffer buffer) {
return buffer.get() & 0xff;
}
public static int getShortToInt(ByteBuffer buffer) {
return buffer.getShort() & 0xffff;
}
public static int getIntToInt(ByteBuffer buffer) {
return buffer.getInt();
}
public static byte[] getBytes(ByteBuffer buffer, int limit) {
ByteBuffer data = ByteBuffer.allocate(MSG_LEN);
int orgPos = buffer.position();
int orgLimit = buffer.limit();
buffer.limit(buffer.position() + limit);
data.put(buffer);
buffer.position(orgPos);
buffer.limit(orgLimit);
return data.array();
}
// CRC 체크
static byte getCRC(byte[] data, int length) {
int i = 0;
byte crc = 0;
while (length-- != 0) {
crc = crc_table[(crc ^ data[i]) & 0xFF];
i++;
}
return crc;
}
// 패킷 결함 체크
public static int defect(byte[] bytes) {
int result = 0;
if (bytes[0] != SOP && bytes[0] != SOP_BIG) {
// Start Code Check
result = 98;
} else if ((bytes[0] == SOP && bytes.length != MSG_LEN) ||
(bytes[0] == SOP_BIG && bytes.length != MSG_LEN_BIG)) {
// 패킷 길이 체크
result = 97;
} else if (bytes[bytes.length - 1] != getCRC(bytes, bytes.length - 1)) {
// CRC 체크
result = 99;
}
return result;
}
public byte[] encode(int msgSeq) { return new byte[0]; }
public static String toHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (final byte b : bytes)
sb.append(String.format("%02x ", b & 0xff));
return sb.toString();
}
public static String toNarrowHex(byte[] packet) {
StringBuilder sb = new StringBuilder();
for (final byte b : packet)
sb.append(String.format("%02x", b & 0xff));
return sb.toString();
}
public void handleMessage(byte[] data) { }
public String getFriendlyName() {
return "UNKNOWN_PACKET";
}
public Boolean isSuccInquireResponseResult(int result) {
boolean isSuccess = false;
switch (result) {
case 16 :
isSuccess = true;
break;
case 17 :
aapsLogger.error(LTag.PUMPCOMM, "Packet CRC error");
break;
case 18 :
aapsLogger.error(LTag.PUMPCOMM, "Parameter error.");
break;
case 19 :
aapsLogger.error(LTag.PUMPCOMM, "Protocol specification error.");
break;
default:
aapsLogger.error(LTag.PUMPCOMM, "System error.");
break;
}
return isSuccess;
}
public Boolean isSuccSettingResponseResult(int result) {
boolean isSuccess = false;
switch (result) {
case 0:
isSuccess = true;
break;
case 1:
aapsLogger.error(LTag.PUMPCOMM, "Packet CRC error");
break;
case 2:
aapsLogger.error(LTag.PUMPCOMM, "Parameter error.");
break;
case 3:
aapsLogger.error(LTag.PUMPCOMM, "Protocol specification error.");
break;
case 4:
aapsLogger.error(LTag.PUMPCOMM, "Eating timeout, not injectable.");
break;
case 6:
aapsLogger.error(LTag.PUMPCOMM, "Pump canceled it.");
break;
case 7:
aapsLogger.error(LTag.PUMPCOMM, "In the midst of other operations, limited app setup capabilities");
break;
case 8:
aapsLogger.error(LTag.PUMPCOMM, "During another bolus injection, injection is restricted");
break;
case 9:
aapsLogger.error(LTag.PUMPCOMM, "Basal release is required.");
break;
case 10:
aapsLogger.error(LTag.PUMPCOMM, "Pump canceled due to non-response.");
break;
case 11:
aapsLogger.error(LTag.PUMPCOMM, "Injection is not possible due to low battery.");
break;
case 12:
aapsLogger.error(LTag.PUMPCOMM, "Injection is not possible due to low insulin. ");
break;
case 13:
aapsLogger.error(LTag.PUMPCOMM, "Can't inject due to 1 time limit exceeded.");
break;
case 14:
aapsLogger.error(LTag.PUMPCOMM, "It cannot be injected due to an excess of injection volume today");
break;
case 15:
aapsLogger.error(LTag.PUMPCOMM, "After base setting is completed, base injection can be made.");
break;
default:
aapsLogger.error(LTag.PUMPCOMM, "It cannot be set to a system error.");
break;
}
return isSuccess;
}
}

View file

@ -0,0 +1,52 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import java.util.*
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class DiaconnG8ResponseMessageHashTable @Inject constructor(val injector: HasAndroidInjector) {
var messages: HashMap<Int, DiaconnG8Packet> = HashMap()
fun put(message: DiaconnG8Packet) {
messages[message.msgType.toInt()] = message
}
fun findMessage(command: Int): DiaconnG8Packet {
return messages[command] ?: DiaconnG8Packet(injector)
}
init {
put(BigMainInfoInquireResponsePacket(injector))
put(BigLogInquireResponsePacket(injector))
put(InjectionSnackInquireResponsePacket(injector))
put(SneckLimitInquireResponsePacket(injector))
put(BasalLimitInquireResponsePacket(injector))
put(TempBasalInquireResponsePacket(injector))
put(TimeInquirePacket(injector))
put(TimeInquireResponsePacket(injector))
put(TimeReportPacket(injector))
put(LogStatusInquireResponsePacket(injector))
put(IncarnationInquireResponsePacket(injector))
put(BolusSpeedInquireResponsePacket(injector))
put(SoundInquireResponsePacket(injector))
put(DisplayTimeInquireResponsePacket(injector))
put(LanguageInquireResponsePacket(injector))
// Report Packet
put(BasalPauseReportPacket(injector))
put(BasalSettingReportPacket(injector))
put(ConfirmReportPacket(injector))
put(InjectionBasalReportPacket(injector))
put(RejectReportPacket(injector))
put(TempBasalReportPacket(injector))
put(InjectionSnackResultReportPacket(injector))
put(InjectionExtendedBolusResultReportPacket(injector))
put(InsulinLackReportPacket(injector))
put(BatteryWarningReportPacket(injector))
put(InjectionBlockReportPacket(injector))
put(BolusSpeedSettingReportPacket(injector))
}
}

View file

@ -0,0 +1,36 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import java.util.*
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class DiaconnG8SettingResponseMessageHashTable @Inject constructor(val injector: HasAndroidInjector) {
var messages: HashMap<Int, DiaconnG8Packet> = HashMap()
fun put(message: DiaconnG8Packet) {
messages[message.msgType.toInt()] = message
}
fun findMessage(command: Int): DiaconnG8Packet {
return messages[command] ?: DiaconnG8Packet(injector)
}
init {
put(AppCancelSettingResponsePacket(injector))
put(AppConfirmSettingResponsePacket(injector))
put(BasalPauseSettingResponsePacket(injector))
put(BasalSettingResponsePacket(injector))
put(TempBasalSettingResponsePacket(injector))
put(TimeSettingResponsePacket(injector))
put(InjectionBasalSettingResponsePacket(injector))
put(InjectionSnackSettingResponsePacket(injector))
put(InjectionExtendedBolusSettingResponsePacket(injector))
put(InjectionCancelSettingResponsePacket(injector))
put(SoundSettingResponsePacket(injector))
put(DisplayTimeoutSettingResponsePacket(injector))
put(LanguageSettingResponsePacket(injector))
put(BolusSpeedSettingResponsePacket(injector))
}
}

View file

@ -0,0 +1,30 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* DisplayTimeInquirePacket
*/
class DisplayTimeInquirePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x4E.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "DisplayTimeInquirePacket request")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END);
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_DISPLAY_TIME_INQUIRE"
}
}

View file

@ -0,0 +1,45 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* DisplayTimeInquireResponsePacket
*/
class DisplayTimeInquireResponsePacket(injector: HasAndroidInjector) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x8E.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "DisplayTimeInquireResponsePacket init")
}
override fun handleMessage(data: ByteArray?) {
val result = defect(data)
if (result != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "DisplayTimeInquireResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
val result2 = getByteToInt(bufferData)
if(!isSuccInquireResponseResult(result2)) {
failed = true
return
}
diaconnG8Pump.lcdOnTimeSec = getByteToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "Result --> ${diaconnG8Pump.result}")
aapsLogger.debug(LTag.PUMPCOMM, "lcdOnTimeSec --> ${diaconnG8Pump.lcdOnTimeSec}")
}
override fun getFriendlyName(): String {
return "PUMP_DISPLAY_TIME_INQUIRE_RESPONSE"
}
}

View file

@ -0,0 +1,32 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* DisplayTimeoutSettingPacket
*/
class DisplayTimeoutSettingPacket(
injector: HasAndroidInjector,
private var type: Int
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x0E
aapsLogger.debug(LTag.PUMPCOMM, "DisplayTimeoutSettingPacket init")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END)
buffer.put(type.toByte()) // cmd
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_DISPLAY_TIMEOUT_SETTING_PACKET"
}
}

View file

@ -0,0 +1,46 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* DisplayTimeoutSettingResponsePacket
*/
class DisplayTimeoutSettingResponsePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
var result = 0
init {
msgType = 0x8E.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "DisplayTimeoutSettingResponsePacket init ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "DisplayTimeoutSettingResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
result = getByteToInt(bufferData)
if(!isSuccSettingResponseResult(result)) {
diaconnG8Pump.bolusStartErrorCode = result
failed = true
return
}
diaconnG8Pump.otpNumber = getIntToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "Result --> $result")
aapsLogger.debug(LTag.PUMPCOMM, "otpNumber --> ${diaconnG8Pump.otpNumber}")
}
override fun getFriendlyName(): String {
return "PUMP_DISPLAY_TIMEOUT_SETTING_RESPONSE"
}
}

View file

@ -0,0 +1,29 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* IncarnationInquirePacket
*/
class IncarnationInquirePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x7A
aapsLogger.debug(LTag.PUMPCOMM, "IncarnationInquirePacket init")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END)
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_INCARNATION_INQUIRE"
}
}

View file

@ -0,0 +1,50 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import javax.inject.Inject
/**
* IncarnationInquireResponsePacket
*/
open class IncarnationInquireResponsePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
@Inject lateinit var sp: SP
@Inject lateinit var resourceHelper: ResourceHelper
var result = 0
init {
msgType = 0xBA.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "IncarnationInquireResponsePacket init")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "IncarnationInquireResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
result = getByteToInt(bufferData)
if(!isSuccInquireResponseResult(result)) {
failed = true
return
}
// 5. 로그상태 조회
diaconnG8Pump.pumpIncarnationNum = getShortToInt(bufferData) // 펌프 Incarnation 번호
aapsLogger.debug(LTag.PUMPCOMM, "Result --> $result")
aapsLogger.debug(LTag.PUMPCOMM, "pumpIncarnationNum > " + diaconnG8Pump.pumpIncarnationNum)
}
override fun getFriendlyName(): String {
return "PUMP_INCARNATION_INQUIRE_RESPONSE"
}
}

View file

@ -0,0 +1,37 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* InjectionBasalReportPacket
*/
class InjectionBasalReportPacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0xCC.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "InjectionBasalReportPacket init ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "InjectionBasalReportPacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
diaconnG8Pump.systemBasePattern = getByteToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "Pump Report BasalPattern --> ${diaconnG8Pump.systemBasePattern} (1:basic, 2: life1 , 3: life2 , 4: life3 , 5:dr1, 6:dr2) ")
}
override fun getFriendlyName(): String {
return "PUMP_INJECTION_BASAL_REPORT"
}
}

View file

@ -0,0 +1,31 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* InjectionBasalSettingPacket
*/
class InjectionBasalSettingPacket(
injector: HasAndroidInjector,
private val pattern:Int
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x0C.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "InjectionBasalSettingPacket init ")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END);
buffer.put(pattern.toByte())
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_INJECTION_BASAL_SETTING"
}
}

View file

@ -0,0 +1,47 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* InjectionBasalSettingResponsePacket
*/
class InjectionBasalSettingResponsePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
var result = 0
init {
msgType = 0x8C.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "InjectionBasalSettingResponsePacket init ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "InjectionBasalSettingResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
result = getByteToInt(bufferData)
if(!isSuccSettingResponseResult(result)) {
diaconnG8Pump.bolusStartErrorCode = result
failed = true
return
}
diaconnG8Pump.otpNumber = getIntToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "Result --> $result")
aapsLogger.debug(LTag.PUMPCOMM, "otpNumber --> ${diaconnG8Pump.otpNumber}")
}
override fun getFriendlyName(): String {
return "PUMP_INJECTION_BASAL_SETTING_RESPONSE"
}
}

View file

@ -0,0 +1,45 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* InjectionBlockReportPacket
*/
class InjectionBlockReportPacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0xD8.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "InjectionBlockReportPacket init ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "InjectionBasalReportPacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
diaconnG8Pump.injectionBlockGrade = getByteToInt(bufferData)
diaconnG8Pump.injectionBlockProcess = getByteToInt(bufferData)
diaconnG8Pump.injectionBlockRemainAmount = getShortToInt(bufferData) / 100.0
diaconnG8Pump.injectionBlockType = getByteToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "injectionBlockGrade --> ${diaconnG8Pump.injectionBlockGrade} (1:info, 2: warning , 3: major , 4: critical)")
aapsLogger.debug(LTag.PUMPCOMM, "injectionBlockProcess --> ${diaconnG8Pump.injectionBlockProcess} (1:skip, 2: stop , 3: ignore ) ")
aapsLogger.debug(LTag.PUMPCOMM, "injectionBlockReaminAmount --> ${diaconnG8Pump.injectionBlockRemainAmount} ")
aapsLogger.debug(LTag.PUMPCOMM, "injectionBlockType --> ${diaconnG8Pump.injectionBlockType} (1:basal, 2: meal , 3: normal , 4: square , 5:dual, 6:tube, 7:needle) ")
}
override fun getFriendlyName(): String {
return "PUMP_INJECTION_BLOCK_REPORT"
}
}

View file

@ -0,0 +1,32 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* InjectionCancelSettingPacket
*/
class InjectionCancelSettingPacket(
injector: HasAndroidInjector,
private var reqMsgType: Byte, // 명령코드
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x2B
aapsLogger.debug(LTag.PUMPCOMM, "InjectionCancelSettingPacket INIT")
}
override fun encode(msgSeq:Int): ByteArray {
var buffer = prefixEncode(msgType, msgSeq, MSG_CON_END)
buffer.put(reqMsgType)
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_INJECTION_CANCEL_SETTING_REQUEST"
}
}

View file

@ -0,0 +1,46 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* InjectionCancelSettingResponsePacket
*/
class InjectionCancelSettingResponsePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
var result = 0
init {
msgType = 0xAB.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "InjectionCancelSettingResponsePacket init ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "InjectionCancelSettingResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
result = getByteToInt(bufferData)
if(!isSuccSettingResponseResult(result)) {
diaconnG8Pump.bolusStartErrorCode = result
failed = true
return
}
diaconnG8Pump.otpNumber = getIntToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "Result --> $result")
aapsLogger.debug(LTag.PUMPCOMM, "otpNumber --> ${diaconnG8Pump.otpNumber}")
}
override fun getFriendlyName(): String {
return "PUMP_INJECTION_CANCEL_SETTING_RESPONSE"
}
}

View file

@ -0,0 +1,59 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject
/**
* InjectionExtendedBolusResultReportPacket
*/
class InjectionExtendedBolusResultReportPacket(injector: HasAndroidInjector) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var resourceHelper: ResourceHelper
init {
msgType = 0xe5.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "InjectionExtendedBolusResultReportPacket init ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "InjectionExtendedBolusResultReportPacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
val result = getByteToInt(bufferData) // 0: success , 1: user stop, 2:fail
val settingMinutes = getShortToInt(bufferData)
val elapsedTime = getShortToInt(bufferData)
val bolusAmountToBeDelivered = getShortToInt(bufferData) / 100.0
val deliveredBolusAmount = getShortToInt(bufferData) / 100.0
diaconnG8Pump.isExtendedInProgress = result == 0
diaconnG8Pump.extendedBolusMinutes = settingMinutes
diaconnG8Pump.extendedBolusAbsoluteRate = bolusAmountToBeDelivered
diaconnG8Pump.extendedBolusPassedMinutes = elapsedTime
diaconnG8Pump.extendedBolusRemainingMinutes = settingMinutes - elapsedTime
diaconnG8Pump.extendedBolusDeliveredSoFar = deliveredBolusAmount
aapsLogger.debug(LTag.PUMPCOMM, "Result: $result")
aapsLogger.debug(LTag.PUMPCOMM, "Is extended bolus running: " + diaconnG8Pump.isExtendedInProgress)
aapsLogger.debug(LTag.PUMPCOMM, "Extended bolus running: " + diaconnG8Pump.extendedBolusAbsoluteRate + " U/h")
aapsLogger.debug(LTag.PUMPCOMM, "Extended bolus duration: " + diaconnG8Pump.extendedBolusMinutes + " min")
aapsLogger.debug(LTag.PUMPCOMM, "Extended bolus so far: " + diaconnG8Pump.extendedBolusSoFarInMinutes + " min")
aapsLogger.debug(LTag.PUMPCOMM, "Extended bolus remaining minutes: " + diaconnG8Pump.extendedBolusRemainingMinutes + " min")
aapsLogger.debug(LTag.PUMPCOMM, "Extended bolus delivered so far: " + diaconnG8Pump.extendedBolusDeliveredSoFar + " U")
}
override fun getFriendlyName(): String {
return "PUMP_INJECTION_EXTENDED_BOLUS_RESULT_REPORT"
}
}

View file

@ -0,0 +1,35 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* InjectionExtendedBolusSettingPacket
*/
class InjectionExtendedBolusSettingPacket(
injector: HasAndroidInjector,
private val amount: Int,
private val minutes: Int,
private val bcDttm:Long
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x08.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "InjectionExtendedBolusSettingPacket init ")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END)
buffer.putShort(minutes.toShort())
buffer.putShort(amount.toShort())
buffer.putInt(bcDttm.toInt())
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_INJECTION_EXTENDED_BOLUS_SETTING"
}
}

View file

@ -0,0 +1,46 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* InjectionExtendedBolusSettingResponsePacket
*/
class InjectionExtendedBolusSettingResponsePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
var result = 0
init {
msgType = 0x88.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "InjectionExtendedBolusSettingResponsePacket init ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "InjectionExtendedBolusSettingResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
result = getByteToInt(bufferData)
if(!isSuccSettingResponseResult(result)) {
diaconnG8Pump.bolusStartErrorCode = result
failed = true
return
}
diaconnG8Pump.otpNumber = getIntToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "Result --> $result")
aapsLogger.debug(LTag.PUMPCOMM, "otpNumber --> ${diaconnG8Pump.otpNumber}")
}
override fun getFriendlyName(): String {
return "PUMP_INJECTION_EXTENDED_BOLUS_SETTING_RESPONSE"
}
}

View file

@ -0,0 +1,33 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* InjectionMealSettingPacket
*/
class InjectionMealSettingPacket(
injector: HasAndroidInjector,
private val amount:Int,
private val bcDttm:Long
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x06.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "InjectionMealSettingPacket init ")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END);
buffer.putShort(amount.toShort())
buffer.putLong(bcDttm)
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_INJECTION_MEAL_SETTING"
}
}

View file

@ -0,0 +1,46 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* InjectionMealSettingResponsePacket
*/
class InjectionMealSettingResponsePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
var result = 0
init {
msgType = 0x86.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "InjectionMealSettingResponsePacket init ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "InjectionMealSettingResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
result = getByteToInt(bufferData)
if(!isSuccSettingResponseResult(result)) {
diaconnG8Pump.bolusStartErrorCode = result
failed = true
return
}
diaconnG8Pump.otpNumber = getIntToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "Result --> $result")
aapsLogger.debug(LTag.PUMPCOMM, "otpNumber --> ${diaconnG8Pump.otpNumber}")
}
override fun getFriendlyName(): String {
return "PUMP_INJECTION_MEAL_SETTING_RESPONSE"
}
}

View file

@ -0,0 +1,26 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* InjectionSneckInquirePacket
*/
class InjectionSnackInquirePacket(injector: HasAndroidInjector) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x47.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "InjectionSnackInquirePacket init ")
}
override fun encode(msgSeq:Int): ByteArray {
return suffixEncode(prefixEncode(msgType, msgSeq, MSG_CON_END))
}
override fun getFriendlyName(): String {
return "PUMP_INJECTION_SNACK_INQUIRE"
}
}

View file

@ -0,0 +1,51 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* InjectionSnackInquireResponsePacket
*/
class InjectionSnackInquireResponsePacket(injector: HasAndroidInjector) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x87.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "InjectionSnackInquireResponsePacket init")
}
override fun handleMessage(data: ByteArray?) {
val result = defect(data)
if (result != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "InjectionSnackInquireResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
val result2 = getByteToInt(bufferData)
if(!isSuccInquireResponseResult(result2)) {
failed = true
return
}
diaconnG8Pump.snackStatus = getByteToInt(bufferData) //주입상태
diaconnG8Pump.snackAmount = getShortToInt(bufferData) / 100.0 // 주입설정량
diaconnG8Pump.snackInjAmount = getShortToInt(bufferData) / 100.0 // 현재주입량
diaconnG8Pump.snackSpeed = getByteToInt(bufferData) //주입속도
aapsLogger.debug(LTag.PUMPCOMM, "Result --> $result2")
aapsLogger.debug(LTag.PUMPCOMM, "snackStatus > " + diaconnG8Pump.snackStatus)
aapsLogger.debug(LTag.PUMPCOMM, "snackAmount > " + diaconnG8Pump.snackAmount)
aapsLogger.debug(LTag.PUMPCOMM, "snackInjAmount > " + diaconnG8Pump.snackInjAmount)
aapsLogger.debug(LTag.PUMPCOMM, "snackSpeed > " + diaconnG8Pump.snackSpeed)
}
override fun getFriendlyName(): String {
return "PUMP_INJECTION_SNACK_INQUIRE_RESPONSE"
}
}

View file

@ -0,0 +1,60 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject
/**
* InjectionSnackResultReportPacket
*/
class InjectionSnackResultReportPacket(injector: HasAndroidInjector) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var resourceHelper: ResourceHelper
init {
msgType = 0xe4.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "InjectionSnackResultReportPacket init ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "InjectionSnackResultReportPacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
val result = getByteToInt(bufferData)
val bolusAmountToBeDelivered = getShortToInt(bufferData)/100.0
val deliveredBolusAmount = getShortToInt(bufferData)/100.0
diaconnG8Pump.bolusAmountToBeDelivered = bolusAmountToBeDelivered
diaconnG8Pump.lastBolusAmount = deliveredBolusAmount
diaconnG8Pump.lastBolusTime = dateUtil.now()
diaconnG8Pump.bolusingTreatment?.insulin = deliveredBolusAmount
if(result == 1) {
diaconnG8Pump.bolusStopped = true // 주입 중 취소 처리!
}
diaconnG8Pump.bolusDone = true // 주입완료 처리!
aapsLogger.debug(LTag.PUMPCOMM, "Result --> $result")
aapsLogger.debug(LTag.PUMPCOMM, "bolusAmountToBeDelivered --> ${diaconnG8Pump.bolusAmountToBeDelivered}")
aapsLogger.debug(LTag.PUMPCOMM, "lastBolusAmount --> ${diaconnG8Pump.lastBolusAmount}")
aapsLogger.debug(LTag.PUMPCOMM, "lastBolusTime --> ${diaconnG8Pump.lastBolusTime}")
aapsLogger.debug(LTag.PUMPCOMM, "diaconnG8Pump.bolusingTreatment?.insulin --> ${diaconnG8Pump.bolusingTreatment?.insulin}")
aapsLogger.debug(LTag.PUMPCOMM, "bolusDone --> ${diaconnG8Pump.bolusDone}")
}
override fun getFriendlyName(): String {
return "PUMP_INJECTION_SNACK_REPORT"
}
}

View file

@ -0,0 +1,31 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* InjectionSnackSettingPacket
*/
class InjectionSnackSettingPacket(
injector: HasAndroidInjector,
private val amount:Int
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x07.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "InjectionSnackSettingPacket init ")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END);
buffer.putShort(amount.toShort())
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_INJECTION_SNACK_SETTING"
}
}

View file

@ -0,0 +1,46 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* InjectionSnackSettingResponsePacket
*/
class InjectionSnackSettingResponsePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
var result = 0
init {
msgType = 0x87.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "InjectionSnackSettingResponsePacket init ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "InjectionSnackSettingResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
result = getByteToInt(bufferData)
if(!isSuccSettingResponseResult(result)) {
diaconnG8Pump.bolusStartErrorCode = result
failed = true
return
}
diaconnG8Pump.otpNumber = getIntToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "Result --> $result")
aapsLogger.debug(LTag.PUMPCOMM, "otpNumber --> ${diaconnG8Pump.otpNumber}")
}
override fun getFriendlyName(): String {
return "PUMP_INJECTION_SNACK_SETTING_RESPONSE"
}
}

View file

@ -0,0 +1,44 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* InsulinLackReportPacket
*/
class InsulinLackReportPacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0xD8.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "InsulinLackReportPacket init ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "InsulinLackReportPacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
diaconnG8Pump.insulinWarningGrade = getByteToInt(bufferData)
diaconnG8Pump.insulinWarningProcess = getByteToInt(bufferData)
diaconnG8Pump.insulinWarningRemain = getByteToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "insulinWarningGrade --> ${diaconnG8Pump.insulinWarningGrade} (1:info, 2: warning , 3: major , 4: critical)")
aapsLogger.debug(LTag.PUMPCOMM, "insulinWarningProcess --> ${diaconnG8Pump.insulinWarningProcess} (1:skip, 2: stop , 3: ignore ) ")
aapsLogger.debug(LTag.PUMPCOMM, "insulinWarningRemain --> ${diaconnG8Pump.insulinWarningRemain} (0~100%) ")
}
override fun getFriendlyName(): String {
return "PUMP_INJECTION_LACK_REPORT"
}
}

View file

@ -0,0 +1,30 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* LanguageInquirePacket
*/
class LanguageInquirePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x60.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "LanguageInquirePacket init")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END);
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_LANGUAGE_INQUIRE"
}
}

View file

@ -0,0 +1,44 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* LanguageInquireResponsePacket
*/
class LanguageInquireResponsePacket(injector: HasAndroidInjector) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0xA0.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "LanguageInquireResponsePacket init")
}
override fun handleMessage(data: ByteArray?) {
val result = defect(data)
if (result != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "LanguageInquireResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
val result2 = getByteToInt(bufferData)
if(!isSuccInquireResponseResult(result2)) {
failed = true
return
}
diaconnG8Pump.selectedLanguage = getByteToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "Result --> ${diaconnG8Pump.result}")
aapsLogger.debug(LTag.PUMPCOMM, "selectedLanguage --> ${diaconnG8Pump.selectedLanguage}")
}
override fun getFriendlyName(): String {
return "PUMP_LANGUAGE_INQUIRE_RESPONSE"
}
}

View file

@ -0,0 +1,32 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* LanguageSettingPacket
*/
class LanguageSettingPacket(
injector: HasAndroidInjector,
private var type: Int
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x20
aapsLogger.debug(LTag.PUMPCOMM, "LanguageSettingPacket init")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END)
buffer.put(type.toByte()) // 명령코드
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_LANGUAGE_SETTING"
}
}

View file

@ -0,0 +1,47 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* LanguageSettingResponsePacket
*/
class LanguageSettingResponsePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
var result = 0
init {
msgType = 0xA0.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "LanguageSettingResponsePacket init")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "LanguageSettingResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
result = getByteToInt(bufferData)
if(!isSuccSettingResponseResult(result)) {
diaconnG8Pump.bolusStartErrorCode = result
failed = true
return
}
diaconnG8Pump.otpNumber = getIntToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "Result --> $result")
aapsLogger.debug(LTag.PUMPCOMM, "otpNumber --> ${diaconnG8Pump.otpNumber}")
}
override fun getFriendlyName(): String {
return "PUMP_LANGUAGE_SETTING_RESPONSE"
}
}

View file

@ -0,0 +1,28 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* LogStatusInquirePacket
*/
class LogStatusInquirePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x56
aapsLogger.debug(LTag.PUMPCOMM, "LogStatusInquirePacket INIT")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END)
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_OG_STATUS_INQUIRE"
}
}

View file

@ -0,0 +1,49 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* LogStatusInquireResponsePacket
*/
open class LogStatusInquireResponsePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
var result = 0
init {
msgType = 0x96.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "LogStatusInquireResponsePacket init")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "LogStatusInquireResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
result = getByteToInt(bufferData)
if(!isSuccInquireResponseResult(result)) {
failed = true
return
}
// 5. 로그상태 조회
diaconnG8Pump.pumpLastLogNum = getShortToInt(bufferData) // 마지막 저장로그번호
diaconnG8Pump.pumpWrappingCount = getByteToInt(bufferData) // wrapping 카운트
aapsLogger.debug(LTag.PUMPCOMM, "Result --> $result")
aapsLogger.debug(LTag.PUMPCOMM, "pumpLastLogNum > " + diaconnG8Pump.pumpLastLogNum)
aapsLogger.debug(LTag.PUMPCOMM, "pumpWrappingCount> " + diaconnG8Pump.pumpWrappingCount)
}
override fun getFriendlyName(): String {
return "PUMP_LOG_STATUS_INQUIRE_RESPONSE"
}
}

View file

@ -0,0 +1,41 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* RejectReportPacket
*/
class RejectReportPacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
var reqMsgType:Int? = null
var reason:Int? = null
init {
msgType = 0xE2.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "RejectReportPacket init ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "RejectReportPacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
reqMsgType = getByteToInt(bufferData)
reason = getByteToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "reqMsgType --> $reqMsgType")
aapsLogger.debug(LTag.PUMPCOMM, "Reject Reason --> $reason (6:cancel, 10:timeout) ")
}
override fun getFriendlyName(): String {
return "PUMP_REJECT_REPORT"
}
}

View file

@ -0,0 +1,30 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* SneckLimitInquirePacket
*/
class SneckLimitInquirePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x50.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "SneckLimitInquirePacket limit request")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END);
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_SNECK_LIMIT_REQUEST"
}
}

View file

@ -0,0 +1,47 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* SneckLimitInquireResponsePacket
*/
class SneckLimitInquireResponsePacket(injector: HasAndroidInjector) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x90.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "SneckLimitInquireResponsePacket init")
}
override fun handleMessage(data: ByteArray?) {
val result = defect(data)
if (result != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "SneckLimitInquireResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
val result2 = getByteToInt(bufferData)
if(!isSuccInquireResponseResult(result2)) {
failed = true
return
}
diaconnG8Pump.maxBolus = getShortToInt(bufferData).toDouble() / 100
diaconnG8Pump.maxBolusePerDay = getShortToInt(bufferData).toDouble() / 100
aapsLogger.debug(LTag.PUMPCOMM, "Result --> ${diaconnG8Pump.result}")
aapsLogger.debug(LTag.PUMPCOMM, "maxBolusePerDay --> ${diaconnG8Pump.maxBolusePerDay}")
aapsLogger.debug(LTag.PUMPCOMM, "maxBolus --> ${diaconnG8Pump.maxBolus}")
}
override fun getFriendlyName(): String {
return "PUMP_SNACK_LIMIT_INQUIRE_RESPONSE"
}
}

View file

@ -0,0 +1,30 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* SoundInquirePacket
*/
class SoundInquirePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x4D.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "SoundInquirePacket request")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END);
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_SOUND_INQUIRE"
}
}

View file

@ -0,0 +1,47 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* SoundInquireResponsePacket
*/
class SoundInquireResponsePacket(injector: HasAndroidInjector) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x8D.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "SoundInquireResponsePacket init")
}
override fun handleMessage(data: ByteArray?) {
val result = defect(data)
if (result != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "SoundInquireResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
val result2 = getByteToInt(bufferData)
if(!isSuccInquireResponseResult(result2)) {
failed = true
return
}
diaconnG8Pump.beepAndAlarm = getByteToInt(bufferData) -1
diaconnG8Pump.alarmIntesity = getByteToInt(bufferData) -1
aapsLogger.debug(LTag.PUMPCOMM, "Result --> ${diaconnG8Pump.result}")
aapsLogger.debug(LTag.PUMPCOMM, "beepAndAlarm --> ${diaconnG8Pump.beepAndAlarm}")
aapsLogger.debug(LTag.PUMPCOMM, "alarmIntesity --> ${diaconnG8Pump.alarmIntesity}")
}
override fun getFriendlyName(): String {
return "PUMP_SOUND_INQUIRE_RESPONSE"
}
}

View file

@ -0,0 +1,34 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* SoundSettingPacket
*/
class SoundSettingPacket(
injector: HasAndroidInjector,
private var type: Int, //
private var intensity: Int //
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x0D
aapsLogger.debug(LTag.PUMPCOMM, "SoundSettingPacket init")
}
override fun encode(msgSeq:Int): ByteArray {
val buffer = prefixEncode(msgType, msgSeq, MSG_CON_END)
buffer.put(type.toByte()) // 명령코드
buffer.put(intensity.toByte()) // 명령코드
return suffixEncode(buffer)
}
override fun getFriendlyName(): String {
return "PUMP_SOUND_SETTING"
}
}

View file

@ -0,0 +1,47 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* SoundSettingResponsePacket
*/
class SoundSettingResponsePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
var result = 0
init {
msgType = 0x8D.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "SoundSettingResponsePacket init")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "SoundSettingResponsePacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
result = getByteToInt(bufferData)
if(!isSuccSettingResponseResult(result)) {
diaconnG8Pump.bolusStartErrorCode = result
failed = true
return
}
diaconnG8Pump.otpNumber = getIntToInt(bufferData)
aapsLogger.debug(LTag.PUMPCOMM, "Result --> $result")
aapsLogger.debug(LTag.PUMPCOMM, "otpNumber --> ${diaconnG8Pump.otpNumber}")
}
override fun getFriendlyName(): String {
return "PUMP_SOUND_SETTING_RESPONSE"
}
}

View file

@ -0,0 +1,29 @@
package info.nightscout.androidaps.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.diaconn.DiaconnG8Pump
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject
/**
* TempBasalInquirePacket
*/
class TempBasalInquirePacket(
injector: HasAndroidInjector
) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
init {
msgType = 0x4A
aapsLogger.debug(LTag.PUMPCOMM, "TempBasalInquirePacket Init")
}
override fun encode(msgSeq:Int): ByteArray {
return suffixEncode(prefixEncode(msgType, msgSeq, MSG_CON_END))
}
override fun getFriendlyName(): String {
return "PUMP_TEMP_BASAL_INQUIRE_REQUEST"
}
}

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