Merge remote-tracking branch 'Nightscout/dev' into Fix/ProfileTotalBasal

This commit is contained in:
Philoul 2021-09-17 18:10:39 +02:00
commit bafc8e951a
216 changed files with 3409 additions and 2150 deletions

View file

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

View file

@ -1,42 +1,7 @@
package info.nightscout.androidaps package info.nightscout.androidaps
import android.os.SystemClock
import android.view.View
import android.view.ViewGroup
import androidx.test.espresso.Espresso.onData
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.scrollTo
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withClassName
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withTagValue
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest import androidx.test.filters.LargeTest
import androidx.test.rule.ActivityTestRule
import androidx.test.rule.GrantPermissionRule
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
import info.nightscout.androidaps.plugins.source.RandomBgPlugin
import info.nightscout.androidaps.setupwizard.SetupWizardActivity
import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.extensions.isRunningTest
import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.Description
import org.hamcrest.Matcher
import org.hamcrest.Matchers
import org.hamcrest.TypeSafeMatcher
import org.junit.Assert
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@LargeTest @LargeTest

View file

@ -243,20 +243,6 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".plugins.general.openhumans.OpenHumansLoginActivity"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="setup-openhumans"
android:scheme="androidaps" />
</intent-filter>
</activity>
<uses-library android:name="org.apache.http.legacy" android:required="false"/> <uses-library android:name="org.apache.http.legacy" android:required="false"/>
</application> </application>

View file

@ -95,7 +95,6 @@ class MainActivity : NoSplashAppCompatActivity() {
private lateinit var binding: ActivityMainBinding private lateinit var binding: ActivityMainBinding
@kotlin.ExperimentalStdlibApi
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
Iconify.with(FontAwesomeModule()) Iconify.with(FontAwesomeModule())
@ -361,7 +360,6 @@ class MainActivity : NoSplashAppCompatActivity() {
// Correct place for calling setUserStats() would be probably MainApp // Correct place for calling setUserStats() would be probably MainApp
// but we need to have it called at least once a day. Thus this location // but we need to have it called at least once a day. Thus this location
@kotlin.ExperimentalStdlibApi
private fun setUserStats() { private fun setUserStats() {
if (!fabricPrivacy.fabricEnabled()) return if (!fabricPrivacy.fabricEnabled()) return
val closedLoopEnabled = if (constraintChecker.isClosedLoopAllowed().value()) "CLOSED_LOOP_ENABLED" else "CLOSED_LOOP_DISABLED" val closedLoopEnabled = if (constraintChecker.isClosedLoopAllowed().value()) "CLOSED_LOOP_ENABLED" else "CLOSED_LOOP_DISABLED"

View file

@ -151,7 +151,11 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() {
} }
val dm = DisplayMetrics() val dm = DisplayMetrics()
windowManager?.defaultDisplay?.getMetrics(dm) if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R)
display?.getRealMetrics(dm)
else
@Suppress("DEPRECATION") windowManager.defaultDisplay.getMetrics(dm)
axisWidth = if (dm.densityDpi <= 120) 3 else if (dm.densityDpi <= 160) 10 else if (dm.densityDpi <= 320) 35 else if (dm.densityDpi <= 420) 50 else if (dm.densityDpi <= 560) 70 else 80 axisWidth = if (dm.densityDpi <= 120) 3 else if (dm.densityDpi <= 160) 10 else if (dm.densityDpi <= 320) 35 else if (dm.densityDpi <= 420) 50 else if (dm.densityDpi <= 560) 70 else 80
binding.bgGraph.gridLabelRenderer?.gridColor = resourceHelper.gc(R.color.graphgrid) binding.bgGraph.gridLabelRenderer?.gridColor = resourceHelper.gc(R.color.graphgrid)

View file

@ -20,6 +20,7 @@ import info.nightscout.androidaps.events.EventPreferenceChange
import info.nightscout.androidaps.events.EventRebuildTabs import info.nightscout.androidaps.events.EventRebuildTabs
import info.nightscout.androidaps.interfaces.PluginBase import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.plugin.general.openhumans.OpenHumansUploader
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
@ -30,7 +31,6 @@ import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin
import info.nightscout.androidaps.plugins.general.wear.WearPlugin import info.nightscout.androidaps.plugins.general.wear.WearPlugin

View file

@ -7,10 +7,8 @@ import javax.inject.Inject
class RequestDexcomPermissionActivity : DialogAppCompatActivity() { class RequestDexcomPermissionActivity : DialogAppCompatActivity() {
@Inject lateinit var dexcomPlugin: DexcomPlugin @Inject lateinit var dexcomPlugin: DexcomPlugin
@kotlin.ExperimentalStdlibApi
private val requestCode = "AndroidAPS <3".map { it.code }.sum() private val requestCode = "AndroidAPS <3".map { it.code }.sum()
@kotlin.ExperimentalStdlibApi
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
requestPermissions(arrayOf(DexcomPlugin.PERMISSION), requestCode) requestPermissions(arrayOf(DexcomPlugin.PERMISSION), requestCode)

View file

@ -190,7 +190,6 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
override fun getItemCount(): Int = tempBasalList.size override fun getItemCount(): Int = tempBasalList.size
@Deprecated("remove remove functionality after finish")
inner class TempBasalsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { inner class TempBasalsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val binding = TreatmentsTempbasalsItemBinding.bind(itemView) val binding = TreatmentsTempbasalsItemBinding.bind(itemView)

View file

@ -6,7 +6,6 @@ import info.nightscout.androidaps.MainActivity
import info.nightscout.androidaps.activities.* import info.nightscout.androidaps.activities.*
import info.nightscout.androidaps.activities.HistoryBrowseActivity import info.nightscout.androidaps.activities.HistoryBrowseActivity
import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansLoginActivity
import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity
import info.nightscout.androidaps.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity import info.nightscout.androidaps.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity
import info.nightscout.androidaps.setupwizard.SetupWizardActivity import info.nightscout.androidaps.setupwizard.SetupWizardActivity
@ -28,6 +27,5 @@ abstract class ActivitiesModule {
@ContributesAndroidInjector abstract fun contributesStatsActivity(): StatsActivity @ContributesAndroidInjector abstract fun contributesStatsActivity(): StatsActivity
@ContributesAndroidInjector abstract fun contributesSurveyActivity(): SurveyActivity @ContributesAndroidInjector abstract fun contributesSurveyActivity(): SurveyActivity
@ContributesAndroidInjector abstract fun contributesDefaultProfileActivity(): ProfileHelperActivity @ContributesAndroidInjector abstract fun contributesDefaultProfileActivity(): ProfileHelperActivity
@ContributesAndroidInjector abstract fun contributesOpenHumansLoginActivity(): OpenHumansLoginActivity
} }

View file

@ -16,6 +16,7 @@ import info.nightscout.androidaps.di.CoreModule
import info.nightscout.androidaps.diaconn.di.DiaconnG8Module import info.nightscout.androidaps.diaconn.di.DiaconnG8Module
import info.nightscout.androidaps.insight.di.InsightDatabaseModule import info.nightscout.androidaps.insight.di.InsightDatabaseModule
import info.nightscout.androidaps.insight.di.InsightModule import info.nightscout.androidaps.insight.di.InsightModule
import info.nightscout.androidaps.plugin.general.openhumans.dagger.OpenHumansModule
import info.nightscout.androidaps.plugins.pump.common.di.PumpCommonModule import info.nightscout.androidaps.plugins.pump.common.di.PumpCommonModule
import info.nightscout.androidaps.plugins.pump.common.di.RileyLinkModule import info.nightscout.androidaps.plugins.pump.common.di.RileyLinkModule
import info.nightscout.androidaps.plugins.pump.medtronic.di.MedtronicModule import info.nightscout.androidaps.plugins.pump.medtronic.di.MedtronicModule
@ -57,8 +58,8 @@ import javax.inject.Singleton
InsightModule::class, InsightModule::class,
InsightDatabaseModule::class, InsightDatabaseModule::class,
WorkersModule::class, WorkersModule::class,
OHUploaderModule::class, DiaconnG8Module::class,
DiaconnG8Module::class OpenHumansModule::class
] ]
) )
interface AppComponent : AndroidInjector<MainApp> { interface AppComponent : AndroidInjector<MainApp> {

View file

@ -20,8 +20,6 @@ import info.nightscout.androidaps.plugins.general.automation.dialogs.EditTrigger
import info.nightscout.androidaps.plugins.general.food.FoodFragment import info.nightscout.androidaps.plugins.general.food.FoodFragment
import info.nightscout.androidaps.plugins.general.maintenance.MaintenanceFragment import info.nightscout.androidaps.plugins.general.maintenance.MaintenanceFragment
import info.nightscout.androidaps.plugins.general.nsclient.NSClientFragment import info.nightscout.androidaps.plugins.general.nsclient.NSClientFragment
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansFragment
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansLoginActivity
import info.nightscout.androidaps.plugins.general.overview.OverviewFragment import info.nightscout.androidaps.plugins.general.overview.OverviewFragment
import info.nightscout.androidaps.plugins.general.overview.dialogs.EditQuickWizardDialog import info.nightscout.androidaps.plugins.general.overview.dialogs.EditQuickWizardDialog
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorFragment import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorFragment
@ -70,8 +68,6 @@ abstract class FragmentsModule {
@ContributesAndroidInjector abstract fun contributesVirtualPumpFragment(): VirtualPumpFragment @ContributesAndroidInjector abstract fun contributesVirtualPumpFragment(): VirtualPumpFragment
@ContributesAndroidInjector abstract fun contributesOpenHumansFragment(): OpenHumansFragment
@ContributesAndroidInjector abstract fun contributesCalibrationDialog(): CalibrationDialog @ContributesAndroidInjector abstract fun contributesCalibrationDialog(): CalibrationDialog
@ContributesAndroidInjector abstract fun contributesCarbsDialog(): CarbsDialog @ContributesAndroidInjector abstract fun contributesCarbsDialog(): CarbsDialog
@ContributesAndroidInjector abstract fun contributesCareDialog(): CareDialog @ContributesAndroidInjector abstract fun contributesCareDialog(): CareDialog
@ -95,7 +91,5 @@ abstract class FragmentsModule {
@ContributesAndroidInjector abstract fun contributesWizardDialog(): WizardDialog @ContributesAndroidInjector abstract fun contributesWizardDialog(): WizardDialog
@ContributesAndroidInjector abstract fun contributesWizardInfoDialog(): WizardInfoDialog @ContributesAndroidInjector abstract fun contributesWizardInfoDialog(): WizardInfoDialog
@ContributesAndroidInjector abstract fun contributesExchangeAuthTokenDialog(): OpenHumansLoginActivity.ExchangeAuthTokenDialog
@ContributesAndroidInjector abstract fun contributesPasswordCheck(): PasswordCheck @ContributesAndroidInjector abstract fun contributesPasswordCheck(): PasswordCheck
} }

View file

@ -1,12 +0,0 @@
package info.nightscout.androidaps.dependencyInjection
import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.plugins.general.openhumans.OHUploadWorker
@Module
@Suppress("unused")
abstract class OHUploaderModule {
@ContributesAndroidInjector abstract fun contributesOHUploadWorkerInjector(): OHUploadWorker
}

View file

@ -10,6 +10,7 @@ import info.nightscout.androidaps.danar.DanaRPlugin
import info.nightscout.androidaps.danars.DanaRSPlugin import info.nightscout.androidaps.danars.DanaRSPlugin
import info.nightscout.androidaps.diaconn.DiaconnG8Plugin import info.nightscout.androidaps.diaconn.DiaconnG8Plugin
import info.nightscout.androidaps.interfaces.PluginBase import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.plugin.general.openhumans.OpenHumansUploader
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
@ -345,6 +346,12 @@ abstract class PluginsModule {
// @IntKey(480) // @IntKey(480)
// abstract fun bindOpenHumansPlugin(plugin: OpenHumansUploader): PluginBase // abstract fun bindOpenHumansPlugin(plugin: OpenHumansUploader): PluginBase
@Binds
@NotNSClient
@IntoMap
@IntKey(480)
abstract fun bindsOpenHumansPlugin(plugin: OpenHumansUploader): PluginBase
@Binds @Binds
@AllConfigs @AllConfigs
@IntoMap @IntoMap

View file

@ -35,6 +35,7 @@ import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.extensions.toVisibility import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
@ -60,6 +61,7 @@ class LoopDialog : DaggerDialogFragment() {
@Inject lateinit var uel: UserEntryLogger @Inject lateinit var uel: UserEntryLogger
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@Inject lateinit var repository: AppRepository @Inject lateinit var repository: AppRepository
@Inject lateinit var objectivePlugin: ObjectivesPlugin
private var showOkCancel: Boolean = true private var showOkCancel: Boolean = true
private var _binding: DialogLoopBinding? = null private var _binding: DialogLoopBinding? = null
@ -74,7 +76,10 @@ class LoopDialog : DaggerDialogFragment() {
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) dialog?.window?.setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
} }
override fun onSaveInstanceState(savedInstanceState: Bundle) { override fun onSaveInstanceState(savedInstanceState: Bundle) {
@ -156,21 +161,74 @@ class LoopDialog : DaggerDialogFragment() {
aapsLogger.debug("UpdateGUI from $from") aapsLogger.debug("UpdateGUI from $from")
val pumpDescription: PumpDescription = activePlugin.activePump.pumpDescription val pumpDescription: PumpDescription = activePlugin.activePump.pumpDescription
val closedLoopAllowed = constraintChecker.isClosedLoopAllowed(Constraint(true)) val closedLoopAllowed = constraintChecker.isClosedLoopAllowed(Constraint(true))
val closedLoopAllowed2 = objectivePlugin.objectives[ObjectivesPlugin.MAXIOB_OBJECTIVE].isCompleted
val lgsEnabled = constraintChecker.isLgsAllowed(Constraint(true)) val lgsEnabled = constraintChecker.isLgsAllowed(Constraint(true))
val apsMode = sp.getString(R.string.key_aps_mode, "open") val apsMode = sp.getString(R.string.key_aps_mode, "open")
if (profileFunction.isProfileValid("LoopDialogUpdateGUI")) { val pump = activePlugin.activePump
if (loopPlugin.isEnabled(PluginType.LOOP)) {
binding.overviewDisconnect15m.visibility = pumpDescription.tempDurationStep15mAllowed.toVisibility()
binding.overviewDisconnect30m.visibility = pumpDescription.tempDurationStep30mAllowed.toVisibility()
when {
pump.isSuspended() -> {
binding.overviewLoop.visibility = View.GONE
binding.overviewSuspend.visibility = View.GONE
binding.overviewPump.visibility = View.GONE
}
!profileFunction.isProfileValid("LoopDialogUpdateGUI") -> {
binding.overviewLoop.visibility = View.GONE
binding.overviewSuspend.visibility = View.GONE
binding.overviewPump.visibility = View.GONE
}
loopPlugin.isDisconnected -> {
binding.overviewLoop.visibility = View.GONE
binding.overviewSuspend.visibility = View.GONE
binding.overviewPump.visibility = View.VISIBLE
binding.overviewPumpHeader.text = resourceHelper.gs(R.string.reconnect)
binding.overviewDisconnectButtons.visibility = View.VISIBLE
binding.overviewReconnect.visibility = View.VISIBLE
}
!loopPlugin.isEnabled(PluginType.LOOP) -> {
binding.overviewLoop.visibility = View.VISIBLE
binding.overviewEnable.visibility = View.VISIBLE
binding.overviewDisable.visibility = View.GONE
binding.overviewSuspend.visibility = View.GONE
binding.overviewPump.visibility = View.VISIBLE
binding.overviewReconnect.visibility = View.GONE
}
loopPlugin.isSuspended -> {
binding.overviewLoop.visibility = View.GONE
binding.overviewSuspend.visibility = View.VISIBLE
binding.overviewSuspendHeader.text = resourceHelper.gs(R.string.resumeloop)
binding.overviewSuspendButtons.visibility = View.VISIBLE
binding.overviewResume.visibility = View.VISIBLE
binding.overviewPump.visibility = View.GONE
binding.overviewReconnect.visibility = View.GONE
}
else -> {
binding.overviewLoop.visibility = View.VISIBLE
binding.overviewEnable.visibility = View.GONE
when { when {
closedLoopAllowed.value() -> { apsMode == "closed" -> {
binding.overviewCloseloop.visibility = (apsMode != "closed").toVisibility() binding.overviewCloseloop.visibility = View.GONE
binding.overviewLgsloop.visibility = (apsMode != "lgs").toVisibility() binding.overviewLgsloop.visibility = View.VISIBLE
binding.overviewOpenloop.visibility = (apsMode != "open").toVisibility() binding.overviewOpenloop.visibility = View.VISIBLE
} }
lgsEnabled.value() -> { apsMode == "lgs" -> {
binding.overviewCloseloop.visibility = View.GONE binding.overviewCloseloop.visibility = closedLoopAllowed.value().toVisibility() //show Close loop button only if Close loop allowed
binding.overviewLgsloop.visibility = (apsMode != "lgs").toVisibility() binding.overviewLgsloop.visibility = View.GONE
binding.overviewOpenloop.visibility = (apsMode != "open").toVisibility() binding.overviewOpenloop.visibility = View.VISIBLE
}
apsMode == "open" -> {
binding.overviewCloseloop.visibility = closedLoopAllowed2.toVisibility() //show CloseLoop button only if Objective 6 is completed (closedLoopAllowed always false in open loop mode)
binding.overviewLgsloop.visibility = lgsEnabled.value().toVisibility()
binding.overviewOpenloop.visibility = View.GONE
} }
else -> { else -> {
@ -179,49 +237,18 @@ class LoopDialog : DaggerDialogFragment() {
binding.overviewOpenloop.visibility = View.GONE binding.overviewOpenloop.visibility = View.GONE
} }
} }
binding.overviewEnable.visibility = View.GONE binding.overviewSuspend.visibility = View.VISIBLE
binding.overviewDisable.visibility = View.VISIBLE binding.overviewSuspendHeader.text = resourceHelper.gs(R.string.suspendloop)
if (!loopPlugin.isSuspended) { binding.overviewSuspendButtons.visibility = View.VISIBLE
binding.overviewSuspendHeader.text = resourceHelper.gs(R.string.suspendloop) binding.overviewResume.visibility = View.GONE
binding.overviewResume.visibility = View.GONE
binding.overviewSuspendButtons.visibility = View.VISIBLE binding.overviewPump.visibility = View.VISIBLE
binding.overviewSuspend.visibility = View.VISIBLE
} else {
if (!loopPlugin.isDisconnected) {
binding.overviewSuspendHeader.text = resourceHelper.gs(R.string.resumeloop)
binding.overviewResume.visibility = View.VISIBLE
binding.overviewSuspendButtons.visibility = View.GONE
binding.overviewSuspend.visibility = View.VISIBLE
} else
binding.overviewSuspend.visibility = View.GONE
}
} else {
binding.overviewEnable.visibility = View.VISIBLE
binding.overviewDisable.visibility = View.GONE
binding.overviewSuspend.visibility = View.GONE
}
if (!loopPlugin.isDisconnected) {
binding.overviewPumpHeader.text = resourceHelper.gs(R.string.disconnectpump) binding.overviewPumpHeader.text = resourceHelper.gs(R.string.disconnectpump)
binding.overviewDisconnect15m.visibility = pumpDescription.tempDurationStep15mAllowed.toVisibility()
binding.overviewDisconnect30m.visibility = pumpDescription.tempDurationStep30mAllowed.toVisibility()
binding.overviewDisconnectButtons.visibility = View.VISIBLE binding.overviewDisconnectButtons.visibility = View.VISIBLE
binding.overviewReconnect.visibility = View.GONE binding.overviewReconnect.visibility = View.GONE
} else {
binding.overviewPumpHeader.text = resourceHelper.gs(R.string.reconnect)
binding.overviewDisconnectButtons.visibility = View.GONE
binding.overviewReconnect.visibility = View.VISIBLE
} }
binding.overviewLoop.visibility = (!loopPlugin.isSuspended && !loopPlugin.isDisconnected).toVisibility()
} }
val profile = profileFunction.getProfile()
val profileStore = activePlugin.activeProfileSource.profile
if (profile == null || profileStore == null) {
ToastUtils.showToastInUiThread(ctx, resourceHelper.gs(R.string.noprofile))
dismiss()
return
}
} }
private fun onClickOkCancelEnabled(v: View): Boolean { private fun onClickOkCancelEnabled(v: View): Boolean {

View file

@ -8,14 +8,18 @@ import android.widget.ArrayAdapter
import com.google.common.base.Joiner import com.google.common.base.Joiner
import info.nightscout.androidaps.Constants import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.databinding.DialogProfileswitchBinding import info.nightscout.androidaps.databinding.DialogProfileswitchBinding
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.HtmlHelper import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
@ -31,6 +35,9 @@ class ProfileSwitchDialog : DialogFragmentWithDate() {
@Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var repository: AppRepository @Inject lateinit var repository: AppRepository
@Inject lateinit var uel: UserEntryLogger @Inject lateinit var uel: UserEntryLogger
@Inject lateinit var config: Config
@Inject lateinit var hardLimits: HardLimits
@Inject lateinit var rxBus: RxBusWrapper
private var profileIndex: Int? = null private var profileIndex: Int? = null
@ -129,22 +136,33 @@ class ProfileSwitchDialog : DialogFragmentWithDate() {
actions.add(resourceHelper.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(eventTime)) actions.add(resourceHelper.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(eventTime))
activity?.let { activity -> activity?.let { activity ->
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.careportal_profileswitch), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), { val ps = profileFunction.buildProfileSwitch(profileStore, profileName, duration, percent, timeShift, eventTime)
profileFunction.createProfileSwitch(profileStore, val validity = ProfileSealed.PS(ps).isValid(resourceHelper.gs(R.string.careportal_profileswitch), activePlugin.activePump, config, resourceHelper, rxBus, hardLimits)
profileName = profileName, if (validity.isValid)
durationInMinutes = duration, OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.careportal_profileswitch), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
percentage = percent, profileFunction.createProfileSwitch(profileStore,
timeShiftInHours = timeShift, profileName = profileName,
timestamp = eventTime) durationInMinutes = duration,
uel.log(Action.PROFILE_SWITCH, percentage = percent,
Sources.ProfileSwitchDialog, timeShiftInHours = timeShift,
notes, timestamp = eventTime)
ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, uel.log(Action.PROFILE_SWITCH,
ValueWithUnit.SimpleString(profileName), Sources.ProfileSwitchDialog,
ValueWithUnit.Percent(percent), notes,
ValueWithUnit.Hour(timeShift).takeIf { timeShift != 0 }, ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged },
ValueWithUnit.Minute(duration).takeIf { duration != 0 }) ValueWithUnit.SimpleString(profileName),
}) ValueWithUnit.Percent(percent),
ValueWithUnit.Hour(timeShift).takeIf { timeShift != 0 },
ValueWithUnit.Minute(duration).takeIf { duration != 0 })
})
else {
OKDialog.show(
activity,
resourceHelper.gs(R.string.careportal_profileswitch),
HtmlHelper.fromHtml(Joiner.on("<br/>").join(validity.reasons))
)
return false
}
} }
return true return true
} }

View file

@ -46,7 +46,6 @@ import info.nightscout.androidaps.plugins.general.wear.events.EventWearConfirmAc
import info.nightscout.androidaps.plugins.general.wear.events.EventWearInitiateAction import info.nightscout.androidaps.plugins.general.wear.events.EventWearInitiateAction
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.androidaps.receivers.ReceiverStatusStore import info.nightscout.androidaps.receivers.ReceiverStatusStore
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy

View file

@ -17,7 +17,6 @@ import info.nightscout.androidaps.plugins.aps.logger.LoggerCallback
import info.nightscout.androidaps.plugins.aps.loop.ScriptReader import info.nightscout.androidaps.plugins.aps.loop.ScriptReader
import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.json.JSONArray import org.json.JSONArray
@ -40,7 +39,6 @@ class DetermineBasalAdapterAMAJS internal constructor(scriptReader: ScriptReader
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var iobCobCalculator: IobCobCalculator @Inject lateinit var iobCobCalculator: IobCobCalculator
@Inject lateinit var openHumansUploader: OpenHumansUploader
private val mScriptReader: ScriptReader private val mScriptReader: ScriptReader
private var profile = JSONObject() private var profile = JSONObject()
@ -116,7 +114,6 @@ class DetermineBasalAdapterAMAJS internal constructor(scriptReader: ScriptReader
aapsLogger.debug(LTag.APS, "Result: $result") aapsLogger.debug(LTag.APS, "Result: $result")
try { try {
val resultJson = JSONObject(result) val resultJson = JSONObject(result)
openHumansUploader.enqueueAMAData(profile, glucoseStatus, iobData, mealData, currentTemp, autosensData, resultJson)
determineBasalResultAMA = DetermineBasalResultAMA(injector, jsResult, resultJson) determineBasalResultAMA = DetermineBasalResultAMA(injector, jsResult, resultJson)
} catch (e: JSONException) { } catch (e: JSONException) {
aapsLogger.error(LTag.APS, "Unhandled exception", e) aapsLogger.error(LTag.APS, "Unhandled exception", e)

View file

@ -58,7 +58,6 @@ class OpenAPSAMAFragment : DaggerFragment() {
} }
@Synchronized @Synchronized
@kotlin.ExperimentalStdlibApi
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
@ -91,7 +90,6 @@ class OpenAPSAMAFragment : DaggerFragment() {
} }
@Synchronized @Synchronized
@kotlin.ExperimentalStdlibApi
private fun updateGUI() { private fun updateGUI() {
if (_binding == null) return if (_binding == null) return
openAPSAMAPlugin.lastAPSResult?.let { lastAPSResult -> openAPSAMAPlugin.lastAPSResult?.let { lastAPSResult ->

View file

@ -125,11 +125,11 @@ class OpenAPSAMAPlugin @Inject constructor(
maxBg = hardLimits.verifyHardLimits(tempTarget.value.highTarget, R.string.temp_target_high_target, HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1].toDouble()) maxBg = hardLimits.verifyHardLimits(tempTarget.value.highTarget, R.string.temp_target_high_target, HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1].toDouble())
targetBg = hardLimits.verifyHardLimits(tempTarget.value.target(), R.string.temp_target_value, HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1].toDouble()) targetBg = hardLimits.verifyHardLimits(tempTarget.value.target(), R.string.temp_target_value, HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1].toDouble())
} }
if (!hardLimits.checkOnlyHardLimits(profile.dia, R.string.profile_dia, hardLimits.minDia(), hardLimits.maxDia())) return if (!hardLimits.checkHardLimits(profile.dia, R.string.profile_dia, hardLimits.minDia(), hardLimits.maxDia())) return
if (!hardLimits.checkOnlyHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), R.string.profile_carbs_ratio_value, hardLimits.minIC(), hardLimits.maxIC())) return if (!hardLimits.checkHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), R.string.profile_carbs_ratio_value, hardLimits.minIC(), hardLimits.maxIC())) return
if (!hardLimits.checkOnlyHardLimits(profile.getIsfMgdl(), R.string.profile_sensitivity_value, HardLimits.MIN_ISF, HardLimits.MAX_ISF)) return if (!hardLimits.checkHardLimits(profile.getIsfMgdl(), R.string.profile_sensitivity_value, HardLimits.MIN_ISF, HardLimits.MAX_ISF)) return
if (!hardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), R.string.profile_max_daily_basal_value, 0.02, hardLimits.maxBasal())) return if (!hardLimits.checkHardLimits(profile.getMaxDailyBasal(), R.string.profile_max_daily_basal_value, 0.02, hardLimits.maxBasal())) return
if (!hardLimits.checkOnlyHardLimits(pump.baseBasalRate, R.string.current_basal_value, 0.01, hardLimits.maxBasal())) return if (!hardLimits.checkHardLimits(pump.baseBasalRate, R.string.current_basal_value, 0.01, hardLimits.maxBasal())) return
startPart = System.currentTimeMillis() startPart = System.currentTimeMillis()
if (constraintChecker.isAutosensModeEnabled().value()) { if (constraintChecker.isAutosensModeEnabled().value()) {
val autosensData = iobCobCalculator.getLastAutosensDataWithWaitForCalculationFinish("OpenAPSPlugin") val autosensData = iobCobCalculator.getLastAutosensDataWithWaitForCalculationFinish("OpenAPSPlugin")

View file

@ -17,7 +17,6 @@ import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.aps.logger.LoggerCallback import info.nightscout.androidaps.plugins.aps.logger.LoggerCallback
import info.nightscout.androidaps.plugins.aps.loop.ScriptReader import info.nightscout.androidaps.plugins.aps.loop.ScriptReader
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.utils.SafeParse import info.nightscout.androidaps.utils.SafeParse
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
@ -41,7 +40,6 @@ class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader:
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var iobCobCalculator: IobCobCalculator @Inject lateinit var iobCobCalculator: IobCobCalculator
@Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var openHumansUploader: OpenHumansUploader
private var profile = JSONObject() private var profile = JSONObject()
private var mGlucoseStatus = JSONObject() private var mGlucoseStatus = JSONObject()
@ -129,7 +127,6 @@ class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader:
aapsLogger.debug(LTag.APS, "Result: $result") aapsLogger.debug(LTag.APS, "Result: $result")
try { try {
val resultJson = JSONObject(result) val resultJson = JSONObject(result)
openHumansUploader.enqueueSMBData(profile, mGlucoseStatus, iobData, mealData, currentTemp, autosensData, microBolusAllowed, smbAlwaysAllowed, resultJson)
determineBasalResultSMB = DetermineBasalResultSMB(injector, resultJson) determineBasalResultSMB = DetermineBasalResultSMB(injector, resultJson)
} catch (e: JSONException) { } catch (e: JSONException) {
aapsLogger.error(LTag.APS, "Unhandled exception", e) aapsLogger.error(LTag.APS, "Unhandled exception", e)

View file

@ -59,7 +59,6 @@ class OpenAPSSMBFragment : DaggerFragment() {
} }
@Synchronized @Synchronized
@kotlin.ExperimentalStdlibApi
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
disposable += rxBus disposable += rxBus
@ -91,7 +90,6 @@ class OpenAPSSMBFragment : DaggerFragment() {
} }
@Synchronized @Synchronized
@kotlin.ExperimentalStdlibApi
fun updateGUI() { fun updateGUI() {
if (_binding == null) return if (_binding == null) return
openAPSSMBPlugin.lastAPSResult?.let { lastAPSResult -> openAPSSMBPlugin.lastAPSResult?.let { lastAPSResult ->

View file

@ -130,11 +130,11 @@ class OpenAPSSMBPlugin @Inject constructor(
maxBg = hardLimits.verifyHardLimits(tempTarget.value.highTarget, R.string.temp_target_high_target, HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1].toDouble()) maxBg = hardLimits.verifyHardLimits(tempTarget.value.highTarget, R.string.temp_target_high_target, HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1].toDouble())
targetBg = hardLimits.verifyHardLimits(tempTarget.value.target(), R.string.temp_target_value, HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1].toDouble()) targetBg = hardLimits.verifyHardLimits(tempTarget.value.target(), R.string.temp_target_value, HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1].toDouble())
} }
if (!hardLimits.checkOnlyHardLimits(profile.dia, R.string.profile_dia, hardLimits.minDia(), hardLimits.maxDia())) return if (!hardLimits.checkHardLimits(profile.dia, R.string.profile_dia, hardLimits.minDia(), hardLimits.maxDia())) return
if (!hardLimits.checkOnlyHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), R.string.profile_carbs_ratio_value, hardLimits.minIC(), hardLimits.maxIC())) return if (!hardLimits.checkHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), R.string.profile_carbs_ratio_value, hardLimits.minIC(), hardLimits.maxIC())) return
if (!hardLimits.checkOnlyHardLimits(profile.getIsfMgdl(), R.string.profile_sensitivity_value, HardLimits.MIN_ISF, HardLimits.MAX_ISF)) return if (!hardLimits.checkHardLimits(profile.getIsfMgdl(), R.string.profile_sensitivity_value, HardLimits.MIN_ISF, HardLimits.MAX_ISF)) return
if (!hardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), R.string.profile_max_daily_basal_value, 0.02, hardLimits.maxBasal())) return if (!hardLimits.checkHardLimits(profile.getMaxDailyBasal(), R.string.profile_max_daily_basal_value, 0.02, hardLimits.maxBasal())) return
if (!hardLimits.checkOnlyHardLimits(pump.baseBasalRate, R.string.current_basal_value, 0.01, hardLimits.maxBasal())) return if (!hardLimits.checkHardLimits(pump.baseBasalRate, R.string.current_basal_value, 0.01, hardLimits.maxBasal())) return
startPart = System.currentTimeMillis() startPart = System.currentTimeMillis()
if (constraintChecker.isAutosensModeEnabled().value()) { if (constraintChecker.isAutosensModeEnabled().value()) {
val autosensData = iobCobCalculator.getLastAutosensDataWithWaitForCalculationFinish("OpenAPSPlugin") val autosensData = iobCobCalculator.getLastAutosensDataWithWaitForCalculationFinish("OpenAPSPlugin")

View file

@ -91,10 +91,10 @@ class ProfileFunctionImplementation @Inject constructor(
if (sp.getString(R.string.key_units, Constants.MGDL) == Constants.MGDL) GlucoseUnit.MGDL if (sp.getString(R.string.key_units, Constants.MGDL) == Constants.MGDL) GlucoseUnit.MGDL
else GlucoseUnit.MMOL else GlucoseUnit.MMOL
override fun createProfileSwitch(profileStore: ProfileStore, profileName: String, durationInMinutes: Int, percentage: Int, timeShiftInHours: Int, timestamp: Long) { override fun buildProfileSwitch(profileStore: ProfileStore, profileName: String, durationInMinutes: Int, percentage: Int, timeShiftInHours: Int, timestamp: Long) : ProfileSwitch {
val pureProfile = profileStore.getSpecificProfile(profileName) val pureProfile = profileStore.getSpecificProfile(profileName)
?: throw InvalidParameterSpecException(profileName) ?: throw InvalidParameterSpecException(profileName)
val ps = ProfileSwitch( return ProfileSwitch(
timestamp = timestamp, timestamp = timestamp,
basalBlocks = pureProfile.basalBlocks, basalBlocks = pureProfile.basalBlocks,
isfBlocks = pureProfile.isfBlocks, isfBlocks = pureProfile.isfBlocks,
@ -105,8 +105,14 @@ class ProfileFunctionImplementation @Inject constructor(
timeshift = T.hours(timeShiftInHours.toLong()).msecs(), timeshift = T.hours(timeShiftInHours.toLong()).msecs(),
percentage = percentage, percentage = percentage,
duration = T.mins(durationInMinutes.toLong()).msecs(), duration = T.mins(durationInMinutes.toLong()).msecs(),
insulinConfiguration = activePlugin.activeInsulin.insulinConfiguration.also { it.insulinEndTime = (pureProfile.dia * 3600 * 1000).toLong() } insulinConfiguration = activePlugin.activeInsulin.insulinConfiguration.also {
it.insulinEndTime = (pureProfile.dia * 3600 * 1000).toLong()
}
) )
}
override fun createProfileSwitch(profileStore: ProfileStore, profileName: String, durationInMinutes: Int, percentage: Int, timeShiftInHours: Int, timestamp: Long) {
val ps = buildProfileSwitch(profileStore, profileName, durationInMinutes, percentage, timeShiftInHours, timestamp)
disposable += repository.runTransactionForResult(InsertOrUpdateProfileSwitch(ps)) disposable += repository.runTransactionForResult(InsertOrUpdateProfileSwitch(ps))
.subscribe({ result -> .subscribe({ result ->
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted ProfileSwitch $it") } result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted ProfileSwitch $it") }

View file

@ -100,7 +100,6 @@ class ObjectivesPlugin @Inject constructor(
sp.putBoolean(R.string.key_objectiveusescale, false) sp.putBoolean(R.string.key_objectiveusescale, false)
} }
@kotlin.ExperimentalStdlibApi
fun completeObjectives(activity: FragmentActivity, request: String) { fun completeObjectives(activity: FragmentActivity, request: String) {
val requestCode = sp.getString(R.string.key_objectives_request_code, "") val requestCode = sp.getString(R.string.key_objectives_request_code, "")
var url = sp.getString(R.string.key_nsclientinternal_url, "").lowercase(Locale.getDefault()) var url = sp.getString(R.string.key_nsclientinternal_url, "").lowercase(Locale.getDefault())

View file

@ -29,7 +29,6 @@ class Objective3 @Inject constructor(injector: HasAndroidInjector) : Objective(i
override fun specialActionEnabled(): Boolean = override fun specialActionEnabled(): Boolean =
nsClientPlugin.nsClientService?.isConnected == true && nsClientPlugin.nsClientService?.hasWriteAuth == true nsClientPlugin.nsClientService?.isConnected == true && nsClientPlugin.nsClientService?.hasWriteAuth == true
@kotlin.ExperimentalStdlibApi
override fun specialAction(activity: FragmentActivity, input: String) { override fun specialAction(activity: FragmentActivity, input: String) {
objectivesPlugin.completeObjectives(activity, input) objectivesPlugin.completeObjectives(activity, input)
} }

View file

@ -152,7 +152,6 @@ class SignatureVerifierPlugin @Inject constructor(
return sb.toString() return sb.toString()
} }
@kotlin.ExperimentalStdlibApi
fun singleCharUnMap(shortHash: String): String { fun singleCharUnMap(shortHash: String): String {
val array = ByteArray(shortHash.length) val array = ByteArray(shortHash.length)
val sb = StringBuilder() val sb = StringBuilder()

View file

@ -115,7 +115,10 @@ class ActionsFragment : DaggerFragment() {
savedInstanceState: Bundle?): View? { savedInstanceState: Bundle?): View? {
//check screen width //check screen width
dm = DisplayMetrics() dm = DisplayMetrics()
activity?.windowManager?.defaultDisplay?.getMetrics(dm) if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R)
activity?.display?.getRealMetrics(dm)
else
@Suppress("DEPRECATION") activity?.windowManager?.defaultDisplay?.getMetrics(dm)
val screenWidth = dm.widthPixels val screenWidth = dm.widthPixels
val screenHeight = dm.heightPixels val screenHeight = dm.heightPixels

View file

@ -67,7 +67,6 @@ class FoodFragment : DaggerFragment() {
return binding.root return binding.root
} }
@kotlin.ExperimentalStdlibApi
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
@ -129,7 +128,6 @@ class FoodFragment : DaggerFragment() {
} }
@Synchronized @Synchronized
@kotlin.ExperimentalStdlibApi
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
disposable.add(rxBus disposable.add(rxBus
@ -141,7 +139,6 @@ class FoodFragment : DaggerFragment() {
swapAdapter() swapAdapter()
} }
@kotlin.ExperimentalStdlibApi
private fun swapAdapter() { private fun swapAdapter() {
disposable += repository disposable += repository
.getFoodData() .getFoodData()
@ -202,7 +199,6 @@ class FoodFragment : DaggerFragment() {
} }
} }
@kotlin.ExperimentalStdlibApi
private fun filterData() { private fun filterData() {
val textFilter = binding.filter.text.toString() val textFilter = binding.filter.text.toString()
val categoryFilter = binding.category.selectedItem?.toString() val categoryFilter = binding.category.selectedItem?.toString()

View file

@ -73,6 +73,7 @@ class MaintenancePlugin @Inject constructor(
val files = logDir.listFiles { _: File?, name: String -> val files = logDir.listFiles { _: File?, name: String ->
(name.startsWith("AndroidAPS") && name.endsWith(".zip")) (name.startsWith("AndroidAPS") && name.endsWith(".zip"))
} }
if (files == null || files.isEmpty()) return
Arrays.sort(files) { f1: File, f2: File -> f2.name.compareTo(f1.name) } Arrays.sort(files) { f1: File, f2: File -> f2.name.compareTo(f1.name) }
var delFiles = listOf(*files) var delFiles = listOf(*files)
val amount = sp.getInt(R.string.key_logshipper_amount, keep) val amount = sp.getInt(R.string.key_logshipper_amount, keep)
@ -108,7 +109,7 @@ class MaintenancePlugin @Inject constructor(
(name.startsWith("AndroidAPS") (name.startsWith("AndroidAPS")
&& (name.endsWith(".log") && (name.endsWith(".log")
|| name.endsWith(".zip") && !name.endsWith(loggerUtils.suffix))) || name.endsWith(".zip") && !name.endsWith(loggerUtils.suffix)))
} } ?: emptyArray()
Arrays.sort(files) { f1: File, f2: File -> f2.name.compareTo(f1.name) } Arrays.sort(files) { f1: File, f2: File -> f2.name.compareTo(f1.name) }
val result = listOf(*files) val result = listOf(*files)
var toIndex = amount var toIndex = amount

View file

@ -112,7 +112,6 @@ class NSClientService : DaggerService() {
var latestDateInReceivedData: Long = 0 var latestDateInReceivedData: Long = 0
@SuppressLint("WakelockTimeout") @SuppressLint("WakelockTimeout")
@kotlin.ExperimentalStdlibApi
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
wakeLock = (getSystemService(Context.POWER_SERVICE) as PowerManager).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AndroidAPS:NSClientService") wakeLock = (getSystemService(Context.POWER_SERVICE) as PowerManager).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AndroidAPS:NSClientService")
@ -236,7 +235,6 @@ class NSClientService : DaggerService() {
return START_STICKY return START_STICKY
} }
@kotlin.ExperimentalStdlibApi
fun initialize() { fun initialize() {
dataCounter = 0 dataCounter = 0
readPreferences() readPreferences()
@ -651,7 +649,6 @@ class NSClientService : DaggerService() {
} }
} }
@kotlin.ExperimentalStdlibApi
fun restart() { fun restart() {
destroy() destroy()
initialize() initialize()

View file

@ -1,70 +0,0 @@
package info.nightscout.androidaps.plugins.general.openhumans
import android.app.Notification
import android.content.Context
import android.net.wifi.WifiManager
import androidx.core.app.NotificationCompat
import androidx.work.ForegroundInfo
import androidx.work.RxWorker
import androidx.work.WorkerParameters
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader.Companion.NOTIFICATION_CHANNEL
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader.Companion.UPLOAD_NOTIFICATION_ID
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.Single
import java.util.concurrent.TimeUnit
import javax.inject.Inject
class OHUploadWorker(context: Context, workerParameters: WorkerParameters)
: RxWorker(context, workerParameters) {
@Inject
lateinit var sp: SP
@Inject
lateinit var openHumansUploader: OpenHumansUploader
@Inject
lateinit var resourceHelper: ResourceHelper
@kotlin.ExperimentalStdlibApi
override fun createWork(): Single<Result> =Single.just(Result.success())
/*
= Single.defer {
// Here we inject every time we create work
// We could build our own WorkerFactory with dagger but this will create conflicts with other Workers
// (see https://medium.com/wonderquill/how-to-pass-custom-parameters-to-rxworker-worker-using-dagger-2-f4cfbc9892ba)
// This class will be replaced with new DB
(applicationContext as MainApp).androidInjector().inject(this)
val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as? WifiManager
val wifiOnly = sp.getBoolean("key_oh_wifi_only", true)
val isConnectedToWifi = wifiManager?.isWifiEnabled ?: false && wifiManager?.connectionInfo?.networkId != -1
if (!wifiOnly || (wifiOnly && isConnectedToWifi)) {
setForegroundAsync(createForegroundInfo())
openHumansUploader.uploadDataSegmentally()
.andThen(Single.just(Result.success()))
.onErrorResumeNext { Single.just(Result.retry()) }
} else {
Single.just(Result.retry())
}
}
*/
private fun createForegroundInfo(): ForegroundInfo {
val title = resourceHelper.gs(info.nightscout.androidaps.R.string.open_humans)
val notification: Notification = NotificationCompat.Builder(applicationContext, NOTIFICATION_CHANNEL)
.setContentTitle(title)
.setTicker(title)
.setContentText(resourceHelper.gs(info.nightscout.androidaps.R.string.your_phone_is_upload_data))
.setSmallIcon(info.nightscout.androidaps.R.drawable.notif_icon)
.setOngoing(true)
.setProgress(0, 0 , true)
.build()
return ForegroundInfo(UPLOAD_NOTIFICATION_ID, notification)
}
}

View file

@ -1,191 +0,0 @@
package info.nightscout.androidaps.plugins.general.openhumans
import android.annotation.SuppressLint
import android.util.Base64
import io.reactivex.Completable
import io.reactivex.Single
import io.reactivex.disposables.Disposables
import okhttp3.*
import okio.BufferedSink
import org.json.JSONArray
import org.json.JSONObject
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*
class OpenHumansAPI(
private val baseUrl: String,
clientId: String,
clientSecret: String,
private val redirectUri: String
) {
private val authHeader = "Basic " + Base64.encodeToString("$clientId:$clientSecret".toByteArray(), Base64.NO_WRAP)
private val client = OkHttpClient()
fun exchangeAuthToken(code: String): Single<OAuthTokens> = sendTokenRequest(FormBody.Builder()
.add("grant_type", "authorization_code")
.add("redirect_uri", redirectUri)
.add("code", code)
.build())
fun refreshAccessToken(refreshToken: String): Single<OAuthTokens> = sendTokenRequest(FormBody.Builder()
.add("grant_type", "refresh_token")
.add("redirect_uri", redirectUri)
.add("refresh_token", refreshToken)
.build())
private fun sendTokenRequest(body: FormBody) = Request.Builder()
.url("$baseUrl/oauth2/token/")
.addHeader("Authorization", authHeader)
.post(body)
.build()
.toSingle()
.map { response ->
response.use { _ ->
val responseBody = response.body
val jsonObject = responseBody?.let { JSONObject(it.string()) }
if (!response.isSuccessful) throw OHHttpException(response.code, response.message, jsonObject?.getString("error"))
if (jsonObject == null) throw OHHttpException(response.code, response.message, "No body")
if (!jsonObject.has("expires_in")) throw OHMissingFieldException("expires_in")
OAuthTokens(
accessToken = jsonObject.getString("access_token")
?: throw OHMissingFieldException("access_token"),
refreshToken = jsonObject.getString("refresh_token")
?: throw OHMissingFieldException("refresh_token"),
expiresAt = response.sentRequestAtMillis + jsonObject.getInt("expires_in") * 1000L
)
}
}
fun getProjectMemberId(accessToken: String): Single<String> = Request.Builder()
.url("$baseUrl/api/direct-sharing/project/exchange-member/?access_token=$accessToken")
.get()
.build()
.toSingle()
.map {
it.jsonBody.getString("project_member_id")
?: throw OHMissingFieldException("project_member_id")
}
fun prepareFileUpload(accessToken: String, fileName: String, metadata: FileMetadata): Single<PreparedUpload> = Request.Builder()
.url("$baseUrl/api/direct-sharing/project/files/upload/direct/?access_token=$accessToken")
.post(FormBody.Builder()
.add("filename", fileName)
.add("metadata", metadata.toJSON().toString())
.build())
.build()
.toSingle()
.map {
val json = it.jsonBody
PreparedUpload(
fileId = json.getString("id") ?: throw OHMissingFieldException("id"),
uploadURL = json.getString("url") ?: throw OHMissingFieldException("url")
)
}
fun uploadFile(url: String, content: ByteArray): Completable = Request.Builder()
.url(url)
.put(object : RequestBody() {
override fun contentType(): MediaType? = null
override fun contentLength() = content.size.toLong()
override fun writeTo(sink: BufferedSink) {
sink.write(content)
}
})
.build()
.toSingle()
.doOnSuccess { response ->
response.use { _ ->
if (!response.isSuccessful) throw OHHttpException(response.code, response.message, null)
}
}
.ignoreElement()
fun completeFileUpload(accessToken: String, fileId: String): Completable = Request.Builder()
.url("$baseUrl/api/direct-sharing/project/files/upload/complete/?access_token=$accessToken")
.post(FormBody.Builder()
.add("file_id", fileId)
.build())
.build()
.toSingle()
.doOnSuccess { it.jsonBody }
.ignoreElement()
private fun Request.toSingle() = Single.create<Response> {
val call = client.newCall(this)
call.enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
it.tryOnError(e)
}
override fun onResponse(call: Call, response: Response) {
it.onSuccess(response)
}
})
it.setDisposable(Disposables.fromRunnable { call.cancel() })
}
private val Response.jsonBody
get() = use { _ ->
val jsonObject = body?.let { JSONObject(it.string()) }
?: throw OHHttpException(code, message, null)
if (!isSuccessful) throw OHHttpException(code, message, jsonObject.getString("detail"))
jsonObject
}
data class OAuthTokens(
val accessToken: String,
val refreshToken: String,
val expiresAt: Long
)
data class FileMetadata(
val tags: List<String>,
val description: String,
val md5: String? = null,
val creationDate: Long? = null,
val startDate: Long? = null,
val endDate: Long? = null
) {
fun toJSON(): JSONObject {
val jsonObject = JSONObject()
jsonObject.put("tags", JSONArray().apply { tags.forEach { put(it) } })
jsonObject.put("description", description)
jsonObject.put("md5", md5)
creationDate?.let { jsonObject.put("creation_date", iso8601DateFormatter.format(Date(it))) }
startDate?.let { jsonObject.put("start_date", iso8601DateFormatter.format(Date(it))) }
endDate?.let { jsonObject.put("end_date", iso8601DateFormatter.format(Date(it))) }
return jsonObject
}
}
data class PreparedUpload(
val fileId: String,
val uploadURL: String
)
data class OHHttpException(
val code: Int,
val meaning: String,
val detail: String?
) : RuntimeException() {
override val message: String get() = toString()
}
data class OHMissingFieldException(
val name: String
) : RuntimeException() {
override val message: String get() = toString()
}
companion object {
@SuppressLint("SimpleDateFormat")
private val iso8601DateFormatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
}
}

View file

@ -1,114 +0,0 @@
package info.nightscout.androidaps.plugins.general.openhumans
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import androidx.work.WorkManager
import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.Event
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import io.reactivex.BackpressureStrategy
import io.reactivex.Single
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import java.util.concurrent.TimeUnit
import javax.inject.Inject
class OpenHumansFragment : DaggerFragment() {
private var viewsCreated = false
private var login: Button? = null
private var logout: Button? = null
private var memberId: TextView? = null
private var queueSize: TextView? = null
private var workerState: TextView? = null
private var queueSizeValue = 0L
private val compositeDisposable = CompositeDisposable()
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var openHumansUploader: OpenHumansUploader
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var aapsSchedulers: AapsSchedulers
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// compositeDisposable += Single.fromCallable { databaseHelper.getOHQueueSize() }
// .subscribeOn(aapsSchedulers.io)
// .repeatWhen {
// rxBus.toObservable(UpdateViewEvent::class.java)
// .cast(Any::class.java)
// .mergeWith(rxBus.toObservable(UpdateQueueEvent::class.java)
// .throttleLatest(5, TimeUnit.SECONDS))
// .toFlowable(BackpressureStrategy.LATEST)
// }
// .observeOn(aapsSchedulers.main)
// .subscribe({
// queueSizeValue = it
// updateGUI()
// }, {})
context?.applicationContext?.let { appContext ->
WorkManager.getInstance(appContext).getWorkInfosForUniqueWorkLiveData(OpenHumansUploader.WORK_NAME).observe(this, {
val workInfo = it.lastOrNull()
if (workInfo == null) {
workerState?.visibility = View.GONE
} else {
workerState?.visibility = View.VISIBLE
workerState?.text = getString(R.string.worker_state, workInfo.state.toString())
}
})
}
}
override fun onDestroy() {
compositeDisposable.clear()
super.onDestroy()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val view = inflater.inflate(R.layout.fragment_open_humans, container, false)
login = view.findViewById(R.id.login)
logout = view.findViewById(R.id.logout)
memberId = view.findViewById(R.id.member_id)
queueSize = view.findViewById(R.id.queue_size)
workerState = view.findViewById(R.id.worker_state)
login!!.setOnClickListener { startActivity(Intent(context, OpenHumansLoginActivity::class.java)) }
logout!!.setOnClickListener {
activity?.let { activity -> OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.oh_logout_confirmation)) { openHumansUploader.logout() } }
}
viewsCreated = true
updateGUI()
return view
}
override fun onDestroyView() {
viewsCreated = false
login = null
logout = null
memberId = null
queueSize = null
super.onDestroyView()
}
fun updateGUI() {
if (viewsCreated) {
queueSize!!.text = getString(R.string.queue_size, queueSizeValue)
val projectMemberId = openHumansUploader.projectMemberId
memberId!!.text = getString(R.string.project_member_id, projectMemberId
?: getString(R.string.not_logged_in))
login!!.visibility = if (projectMemberId == null) View.VISIBLE else View.GONE
logout!!.visibility = if (projectMemberId != null) View.VISIBLE else View.GONE
}
}
object UpdateViewEvent : Event()
object UpdateQueueEvent : Event()
}

View file

@ -1,138 +0,0 @@
package info.nightscout.androidaps.plugins.general.openhumans
import android.app.Dialog
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.widget.Button
import android.widget.CheckBox
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.browser.customtabs.CustomTabsIntent
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity
import dagger.android.support.DaggerDialogFragment
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import io.reactivex.disposables.Disposable
import javax.inject.Inject
class OpenHumansLoginActivity : NoSplashAppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_open_humans_login)
val button = findViewById<Button>(R.id.button)
val checkbox = findViewById<CheckBox>(R.id.checkbox)
button.setOnClickListener {
if (checkbox.isChecked) {
CustomTabsIntent.Builder().build().launchUrl(this, Uri.parse(OpenHumansUploader.AUTH_URL))
} else {
Toast.makeText(this, R.string.you_need_to_accept_the_of_use_first, Toast.LENGTH_SHORT).show()
}
}
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
val code = intent.data?.getQueryParameter("code")
if (supportFragmentManager.fragments.size == 0 && code != null) {
ExchangeAuthTokenDialog(code).show(supportFragmentManager, "ExchangeAuthTokenDialog")
}
}
class ExchangeAuthTokenDialog : DaggerDialogFragment() {
@Inject lateinit var openHumansUploader: OpenHumansUploader
@Inject lateinit var aapsSchedulers: AapsSchedulers
private var disposable: Disposable? = null
init {
isCancelable = false
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return AlertDialog.Builder(requireActivity())
.setTitle(R.string.completing_login)
.setMessage(R.string.please_wait)
.create()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
disposable = openHumansUploader.login(arguments?.getString("authToken")!!).subscribeOn(aapsSchedulers.io).subscribe({
dismiss()
SetupDoneDialog().show(parentFragmentManager, "SetupDoneDialog")
}, {
dismiss()
ErrorDialog(it.message).show(parentFragmentManager, "ErrorDialog")
})
}
override fun onDestroy() {
disposable?.dispose()
super.onDestroy()
}
companion object {
operator fun invoke(authToken: String): ExchangeAuthTokenDialog {
val dialog = ExchangeAuthTokenDialog()
val args = Bundle()
args.putString("authToken", authToken)
dialog.arguments = args
return dialog
}
}
}
class ErrorDialog : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val message = arguments?.getString("message")
val shownMessage = if (message == null) getString(R.string.there_was_an_error)
else "${getString(R.string.there_was_an_error)}\n\n$message"
return AlertDialog.Builder(requireActivity())
.setTitle(R.string.error)
.setMessage(shownMessage)
.setPositiveButton(R.string.close, null)
.create()
}
companion object {
operator fun invoke(message: String?): ErrorDialog {
val dialog = ErrorDialog()
val args = Bundle()
args.putString("message", message)
dialog.arguments = args
return dialog
}
}
}
class SetupDoneDialog : DialogFragment() {
init {
isCancelable = false
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return AlertDialog.Builder(requireActivity())
.setTitle(R.string.successfully_logged_in)
.setMessage(R.string.setup_will_continue_in_background)
.setCancelable(false)
.setPositiveButton(R.string.close) { _, _ ->
requireActivity().run {
setResult(FragmentActivity.RESULT_OK)
requireActivity().finish()
}
}
.create()
}
}
}

View file

@ -1,651 +0,0 @@
package info.nightscout.androidaps.plugins.general.openhumans
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.PowerManager
import android.util.DisplayMetrics
import android.view.WindowManager
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.work.*
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.BuildConfig
import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.database.entities.TemporaryTarget
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.db.*
import info.nightscout.androidaps.events.EventPreferenceChange
import info.nightscout.androidaps.extensions.toConstant
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.Completable
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.rxkotlin.plusAssign
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import java.io.ByteArrayOutputStream
import java.security.MessageDigest
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.TimeUnit
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class OpenHumansUploader @Inject constructor(
injector: HasAndroidInjector,
resourceHelper: ResourceHelper,
aapsLogger: AAPSLogger,
private val aapsSchedulers: AapsSchedulers,
private val sp: SP,
private val rxBus: RxBusWrapper,
private val context: Context,
val repository: AppRepository
) : PluginBase(
PluginDescription()
.mainType(PluginType.GENERAL)
.pluginIcon(R.drawable.open_humans_white)
.pluginName(R.string.open_humans)
.shortName(R.string.open_humans_short)
.description(R.string.donate_your_data_to_science)
.fragmentClass(OpenHumansFragment::class.qualifiedName)
.preferencesId(R.xml.pref_openhumans),
aapsLogger, resourceHelper, injector) {
companion object {
private const val OPEN_HUMANS_URL = "https://www.openhumans.org"
private const val CLIENT_ID = "oie6DvnaEOagTxSoD6BukkLPwDhVr6cMlN74Ihz1"
private const val CLIENT_SECRET = "jR0N8pkH1jOwtozHc7CsB1UPcJzFN95ldHcK4VGYIApecr8zGJox0v06xLwPLMASScngT12aIaIHXAVCJeKquEXAWG1XekZdbubSpccgNiQBmuVmIF8nc1xSKSNJltCf"
private const val REDIRECT_URL = "androidaps://setup-openhumans"
const val AUTH_URL = "https://www.openhumans.org/direct-sharing/projects/oauth2/authorize/?client_id=$CLIENT_ID&response_type=code"
const val WORK_NAME = "Open Humans"
const val NOTIFICATION_CHANNEL = "OpenHumans"
private const val COPY_NOTIFICATION_ID = 3122
private const val FAILURE_NOTIFICATION_ID = 3123
private const val SUCCESS_NOTIFICATION_ID = 3124
private const val SIGNED_OUT_NOTIFICATION_ID = 3125
const val UPLOAD_NOTIFICATION_ID = 3126
private const val UPLOAD_SEGMENT_SIZE = 10000L
}
private val openHumansAPI = OpenHumansAPI(OPEN_HUMANS_URL, CLIENT_ID, CLIENT_SECRET, REDIRECT_URL)
@Suppress("PrivatePropertyName")
private val FILE_NAME_DATE_FORMAT = SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.US).apply { timeZone = TimeZone.getTimeZone("UTC") }
private var isSetup
get() = sp.getBoolean("openhumans_is_setup", false)
set(value) = sp.putBoolean("openhumans_is_setup", value)
private var oAuthTokens: OpenHumansAPI.OAuthTokens?
get() {
return if (sp.contains("openhumans_access_token") && sp.contains("openhumans_refresh_token") && sp.contains("openhumans_expires_at")) {
OpenHumansAPI.OAuthTokens(
accessToken = sp.getStringOrNull("openhumans_access_token", null)!!,
refreshToken = sp.getStringOrNull("openhumans_refresh_token", null)!!,
expiresAt = sp.getLong("openhumans_expires_at", 0)
)
} else {
null
}
}
set(value) {
if (value != null) {
sp.putString("openhumans_access_token", value.accessToken)
sp.putString("openhumans_refresh_token", value.refreshToken)
sp.putLong("openhumans_expires_at", value.expiresAt)
} else {
sp.remove("openhumans_access_token")
sp.remove("openhumans_refresh_token")
sp.remove("openhumans_expires_at")
sp.remove("openhumans_expires_at")
}
}
var projectMemberId: String?
get() = sp.getStringOrNull("openhumans_project_member_id", null)
private set(value) {
if (value == null) sp.remove("openhumans_project_member_id")
else sp.putString("openhumans_project_member_id", value)
}
private var uploadCounter: Int
get() = sp.getInt("openhumans_counter", 1)
set(value) = sp.putInt("openhumans_counter", value)
private val appId: UUID
get() {
val id = sp.getStringOrNull("openhumans_appid", null)
return if (id == null) {
val generated = UUID.randomUUID()
sp.putString("openhumans_appid", generated.toString())
generated
} else {
UUID.fromString(id)
}
}
private var copyDisposable: Disposable? = null
private val wakeLock = (context.getSystemService(Context.POWER_SERVICE) as PowerManager)
.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AndroidAPS::OpenHumans")
private val preferenceChangeDisposable = CompositeDisposable()
override fun onStart() {
super.onStart()
setupNotificationChannel()
if (isSetup) scheduleWorker(false)
preferenceChangeDisposable += rxBus.toObservable(EventPreferenceChange::class.java).subscribe {
onSharedPreferenceChanged(it)
}
}
override fun onStop() {
copyDisposable?.dispose()
cancelWorker()
preferenceChangeDisposable.clear()
super.onStop()
}
fun enqueueBGReading(glucoseValue: GlucoseValue?) = glucoseValue?.let {
insertQueueItem("BgReadings") {
put("date", glucoseValue.timestamp)
put("isValid", glucoseValue.isValid)
put("value", glucoseValue.value)
put("direction", glucoseValue.trendArrow)
put("raw", glucoseValue.raw)
put("source", glucoseValue.sourceSensor)
put("nsId", glucoseValue.interfaceIDs.nightscoutId)
}
}
// @JvmOverloads
// fun enqueueTreatment(treatment: Treatment?, deleted: Boolean = false) = treatment?.let {
// insertQueueItem("Treatments") {
// put("date", treatment.date)
// put("isValid", treatment.isValid)
// put("source", treatment.source)
// put("nsId", treatment._id)
// put("boluscalc", treatment.boluscalc)
// put("carbs", treatment.carbs)
// put("dia", treatment.dia)
// put("insulin", treatment.insulin)
// put("insulinInterfaceID", treatment.insulinInterfaceID)
// put("isSMB", treatment.isSMB)
// put("mealBolus", treatment.mealBolus)
// put("bolusCalcJson", treatment.getBoluscalc())
// put("isDeletion", deleted)
// }
// }
@JvmOverloads
fun enqueueTherapyEvent(therapyEvent: TherapyEvent, deleted: Boolean = false) = insertQueueItem("TherapyEvents") {
put("date", therapyEvent.timestamp)
put("isValid", therapyEvent.isValid)
put("nsId", therapyEvent.interfaceIDs.nightscoutId)
put("eventType", therapyEvent.type.text)
put("glucose", therapyEvent.glucose)
put("units", therapyEvent.glucoseUnit.toConstant())
put("glucoseType", therapyEvent.glucoseType?.text)
put("duration", therapyEvent.duration)
put("isDeletion", deleted)
}
// @JvmOverloads
// fun enqueueExtendedBolus(extendedBolus: ExtendedBolus, deleted: Boolean = false) = insertQueueItem("ExtendedBoluses") {
// put("date", extendedBolus.date)
// put("isValid", extendedBolus.isValid)
// put("source", extendedBolus.source)
// put("nsId", extendedBolus._id)
// put("pumpId", extendedBolus.pumpId)
// put("insulin", extendedBolus.insulin)
// put("durationInMinutes", extendedBolus.durationInMinutes)
// put("isDeletion", deleted)
// }
// @JvmOverloads
// fun enqueueProfileSwitch(profileSwitch: ProfileSwitch, deleted: Boolean = false) = insertQueueItem("ProfileSwitches") {
// put("date", profileSwitch.date)
// put("isValid", profileSwitch.isValid)
// put("source", profileSwitch.source)
// put("nsId", profileSwitch._id)
// put("isCPP", profileSwitch.isCPP)
// put("timeshift", profileSwitch.timeshift)
// put("percentage", profileSwitch.percentage)
// put("profile", JSONObject(profileSwitch.profileJson))
// put("profilePlugin", profileSwitch.profilePlugin)
// put("durationInMinutes", profileSwitch.durationInMinutes)
// put("isDeletion", deleted)
// }
// fun enqueueTotalDailyDose(tdd: TDD) = insertQueueItem("TotalDailyDoses") {
// put("double", tdd.date)
// put("double", tdd.bolus)
// put("double", tdd.basal)
// put("double", tdd.total)
// }
// @JvmOverloads
// fun enqueueTemporaryBasal(temporaryBasal: TemporaryBasal?, deleted: Boolean = false) = temporaryBasal?.let {
// insertQueueItem("TemporaryBasals") {
// put("date", temporaryBasal.date)
// put("isValid", temporaryBasal.isValid)
// put("source", temporaryBasal.source)
// put("nsId", temporaryBasal._id)
// put("pumpId", temporaryBasal.pumpId)
// put("durationInMinutes", temporaryBasal.durationInMinutes)
// put("durationInMinutes", temporaryBasal.durationInMinutes)
// put("isAbsolute", temporaryBasal.isAbsolute)
// put("percentRate", temporaryBasal.percentRate)
// put("absoluteRate", temporaryBasal.absoluteRate)
// put("isDeletion", deleted)
// }
// }
@JvmOverloads
fun enqueueTempTarget(tempTarget: TemporaryTarget?, deleted: Boolean = false) = tempTarget?.let {
insertQueueItem("TempTargets") {
put("date", tempTarget.timestamp)
put("isValid", tempTarget.isValid)
put("nsId", tempTarget.interfaceIDs_backing?.nightscoutId)
put("low", tempTarget.lowTarget)
put("high", tempTarget.highTarget)
put("reason", tempTarget.reason)
put("durationInMinutes", tempTarget.duration)
put("isDeletion", deleted)
}
}
fun enqueueSMBData(profile: JSONObject?, glucoseStatus: JSONObject?, iobData: JSONArray?, mealData: JSONObject?, currentTemp: JSONObject?, autosensData: JSONObject?, smbAllowed: Boolean, smbAlwaysAllowed: Boolean, result: JSONObject?) = insertQueueItem("APSData") {
put("algorithm", "SMB")
put("profile", profile)
put("glucoseStatus", glucoseStatus)
put("iobData", iobData)
put("mealData", mealData)
put("currentTemp", currentTemp)
put("autosensData", autosensData)
put("smbAllowed", smbAllowed)
put("smbAlwaysAllowed", smbAlwaysAllowed)
put("result", result)
}
fun enqueueAMAData(profile: JSONObject?, glucoseStatus: JSONObject?, iobData: JSONArray?, mealData: JSONObject?, currentTemp: JSONObject?, autosensData: JSONObject?, result: JSONObject?) = insertQueueItem("APSData") {
put("algorithm", "AMA")
put("profile", profile)
put("glucoseStatus", glucoseStatus)
put("iobData", iobData)
put("mealData", mealData)
put("currentTemp", currentTemp)
put("autosensData", autosensData)
put("result", result)
}
private fun insertQueueItem(file: String, structureVersion: Int = 1, generator: JSONObject.() -> Unit) {
if (oAuthTokens != null && this.isEnabled(PluginType.GENERAL)) {
try {
val jsonObject = JSONObject()
jsonObject.put("structureVersion", structureVersion)
jsonObject.put("queuedOn", System.currentTimeMillis())
generator(jsonObject)
// val queueItem = OHQueueItem(
// file = file,
// content = jsonObject.toString()
// )
// databaseHelper.createOrUpdate(queueItem)
rxBus.send(OpenHumansFragment.UpdateQueueEvent)
} catch (e: JSONException) {
e.printStackTrace()
}
}
}
fun login(authCode: String): Completable =
openHumansAPI.exchangeAuthToken(authCode)
.doOnSuccess {
oAuthTokens = it
}
.flatMap { openHumansAPI.getProjectMemberId(it.accessToken) }
.doOnSuccess {
projectMemberId = it
copyExistingDataToQueue()
rxBus.send(OpenHumansFragment.UpdateViewEvent)
}
.doOnError {
aapsLogger.error("Failed to login to Open Humans", it)
}
.ignoreElement()
fun logout() {
cancelWorker()
copyDisposable?.dispose()
isSetup = false
oAuthTokens = null
projectMemberId = null
// databaseHelper.clearOpenHumansQueue()
rxBus.send(OpenHumansFragment.UpdateViewEvent)
}
private fun copyExistingDataToQueue() {
copyDisposable?.dispose()
var currentProgress = 0L
var maxProgress = 0L
val increaseCounter = {
currentProgress++
//Updating the notification for every item drastically slows down the operation
if (currentProgress % 1000L == 0L) showOngoingNotification(maxProgress, currentProgress)
}
// copyDisposable = Completable.fromCallable { databaseHelper.clearOpenHumansQueue() }
// .andThen(Single.defer { Single.just(databaseHelper.getCountOfAllRows() + treatmentsPlugin.service.count()) })
// .doOnSuccess { maxProgress = it }
// .flatMapObservable { Observable.defer { Observable.fromIterable(treatmentsPlugin.service.getTreatmentData()) } }
// .map { enqueueTreatment(it); increaseCounter() }
// .ignoreElements()
// .andThen(Observable.defer { Observable.fromIterable(repository.compatGetBgReadingsDataFromTime(0, true).blockingGet()) })
// .map { enqueueBGReading(it); increaseCounter() }
// .ignoreElements()
// .andThen(Observable.defer { Observable.fromIterable(repository.compatGetTherapyEventDataFromTime(0, true).blockingGet()) })
// .map { enqueueTherapyEvent(it); increaseCounter() }
// .ignoreElements()
// .andThen(Observable.defer { Observable.fromIterable(databaseHelper.getAllExtendedBoluses()) })
// .map { enqueueExtendedBolus(it); increaseCounter() }
// .ignoreElements()
// .andThen(Observable.defer { Observable.fromIterable(databaseHelper.getAllProfileSwitches()) })
// .map { enqueueProfileSwitch(it); increaseCounter() }
// .ignoreElements()
// .andThen(Observable.defer { Observable.fromIterable(databaseHelper.getAllTDDs()) })
// .map { enqueueTotalDailyDose(it); increaseCounter() }
// .ignoreElements()
// .andThen(Observable.defer { Observable.fromIterable(databaseHelper.getAllTemporaryBasals()) })
// .map { enqueueTemporaryBasal(it); increaseCounter() }
// .ignoreElements()
// .andThen(Observable.defer { Observable.fromIterable(repository.compatGetTemporaryTargetData().blockingGet()) })
// .map { enqueueTempTarget(it); increaseCounter() }
// .ignoreElements()
// .doOnSubscribe {
// wakeLock.acquire(TimeUnit.MINUTES.toMillis(30))
// showOngoingNotification()
// }
// .doOnComplete {
// isSetup = true
// scheduleWorker(false)
// showSetupFinishedNotification()
// }
// .doOnError {
// logout()
// showSetupFailedNotification()
// }
// .doFinally {
// copyDisposable = null
// NotificationManagerCompat.from(context).cancel(COPY_NOTIFICATION_ID)
// wakeLock.release()
// }
// .onErrorComplete()
// .subscribeOn(aapsSchedulers.io)
// .subscribe()
}
private fun showOngoingNotification(maxProgress: Long? = null, currentProgress: Long? = null) {
val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL)
.setContentTitle(resourceHelper.gs(R.string.finishing_open_humans_setup))
.setContentText(resourceHelper.gs(R.string.this_may_take_a_while))
.setStyle(NotificationCompat.BigTextStyle())
.setProgress(maxProgress?.toInt() ?: 0, currentProgress?.toInt()
?: 0, maxProgress == null || currentProgress == null)
.setOngoing(true)
.setAutoCancel(false)
.setSmallIcon(R.drawable.notif_icon)
.build()
NotificationManagerCompat.from(context).notify(COPY_NOTIFICATION_ID, notification)
}
private fun showSetupFinishedNotification() {
val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL)
.setContentTitle(resourceHelper.gs(R.string.setup_finished))
.setContentText(resourceHelper.gs(R.string.your_phone_will_upload_data))
.setStyle(NotificationCompat.BigTextStyle())
.setSmallIcon(R.drawable.notif_icon)
.build()
val notificationManager = NotificationManagerCompat.from(context)
notificationManager.notify(SUCCESS_NOTIFICATION_ID, notification)
}
private fun showSetupFailedNotification() {
val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL)
.setContentTitle(resourceHelper.gs(R.string.setup_failed))
.setContentText(resourceHelper.gs(R.string.there_was_an_error))
.setStyle(NotificationCompat.BigTextStyle())
.setSmallIcon(R.drawable.notif_icon)
.build()
val notificationManager = NotificationManagerCompat.from(context)
notificationManager.notify(FAILURE_NOTIFICATION_ID, notification)
}
/*
@kotlin.ExperimentalStdlibApi
fun uploadDataSegmentally(): Completable =
uploadData(UPLOAD_SEGMENT_SIZE)
.repeatUntil { databaseHelper.getOHQueueSize() == 0L }
.doOnSubscribe {
aapsLogger.info(LTag.OHUPLOADER, "Starting segmental upload")
}
.doOnComplete {
aapsLogger.info(LTag.OHUPLOADER, "Segmental upload successful")
}
.doOnError {
aapsLogger.error(LTag.OHUPLOADER, "Segmental upload exceptional", it)
}
@kotlin.ExperimentalStdlibApi
@Suppress("SameParameterValue")
private fun uploadData(maxEntries: Long): Completable = gatherData(maxEntries)
.flatMap { data -> refreshAccessTokensIfNeeded().map { accessToken -> accessToken to data } }
.flatMap { uploadFile(it.first, it.second).andThen(Single.just(it.second)) }
.flatMapCompletable {
if (it.highestQueueId != null) {
removeUploadedEntriesFromQueue(it.highestQueueId)
} else {
Completable.complete()
}
}
.doOnError {
if (it is OpenHumansAPI.OHHttpException && it.code == 401 && it.detail == "Invalid token.") {
handleSignOut()
}
aapsLogger.error("Error while uploading to Open Humans", it)
}
.doOnComplete {
aapsLogger.info(LTag.OHUPLOADER, "Upload successful")
rxBus.send(OpenHumansFragment.UpdateQueueEvent)
}
.doOnSubscribe {
aapsLogger.info(LTag.OHUPLOADER, "Starting upload")
}
*/
private fun uploadFile(accessToken: String, uploadData: UploadData) = Completable.defer {
openHumansAPI.prepareFileUpload(accessToken, uploadData.fileName, uploadData.metadata)
.flatMap { openHumansAPI.uploadFile(it.uploadURL, uploadData.content).andThen(Single.just(it.fileId)) }
.flatMapCompletable { openHumansAPI.completeFileUpload(accessToken, it) }
}
private fun refreshAccessTokensIfNeeded() = Single.defer {
val oAuthTokens = this.oAuthTokens!!
if (oAuthTokens.expiresAt <= System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1)) {
openHumansAPI.refreshAccessToken(oAuthTokens.refreshToken)
.doOnSuccess { this.oAuthTokens = it }
.map { it.accessToken }
} else {
Single.just(oAuthTokens.accessToken)
}
}
/*
@kotlin.ExperimentalStdlibApi
private fun gatherData(maxEntries: Long) = Single.defer {
val items = databaseHelper.getAllOHQueueItems(maxEntries)
val baos = ByteArrayOutputStream()
val zos = ZipOutputStream(baos)
val tags = mutableListOf<String>()
items.groupBy { it.file }.forEach { entry ->
tags.add(entry.key)
val jsonArray = JSONArray()
entry.value.map { it.content }.forEach { jsonArray.put(JSONObject(it)) }
zos.writeFile("${entry.key}.json", jsonArray.toString().toByteArray())
}
val applicationInfo = JSONObject()
applicationInfo.put("versionName", BuildConfig.VERSION_NAME)
applicationInfo.put("versionCode", BuildConfig.VERSION_CODE)
val hasGitInfo = !BuildConfig.HEAD.endsWith("NoGitSystemAvailable", true)
val customRemote = !BuildConfig.REMOTE.equals("https://github.com/nightscout/AndroidAPS.git", true)
applicationInfo.put("hasGitInfo", hasGitInfo)
applicationInfo.put("customRemote", customRemote)
applicationInfo.put("applicationId", appId.toString())
zos.writeFile("ApplicationInfo.json", applicationInfo.toString().toByteArray())
tags.add("ApplicationInfo")
val preferences = JSONObject(sp.getAll().filterKeys { it.isAllowedKey() })
zos.writeFile("Preferences.json", preferences.toString().toByteArray())
tags.add("Preferences")
val deviceInfo = JSONObject()
deviceInfo.put("brand", Build.BRAND)
deviceInfo.put("device", Build.DEVICE)
deviceInfo.put("manufacturer", Build.MANUFACTURER)
deviceInfo.put("model", Build.MODEL)
deviceInfo.put("product", Build.PRODUCT)
zos.writeFile("DeviceInfo.json", deviceInfo.toString().toByteArray())
tags.add("DeviceInfo")
val displayMetrics = DisplayMetrics()
(context.getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay.getMetrics(displayMetrics)
val displayInfo = JSONObject()
displayInfo.put("height", displayMetrics.heightPixels)
displayInfo.put("width", displayMetrics.widthPixels)
displayInfo.put("density", displayMetrics.density)
displayInfo.put("scaledDensity", displayMetrics.scaledDensity)
displayInfo.put("xdpi", displayMetrics.xdpi)
displayInfo.put("ydpi", displayMetrics.ydpi)
zos.writeFile("DisplayInfo.json", displayInfo.toString().toByteArray())
tags.add("DisplayInfo")
val uploadNumber = this.uploadCounter++
val uploadDate = Date()
val uploadInfo = JSONObject()
uploadInfo.put("fileVersion", 1)
uploadInfo.put("counter", uploadNumber)
uploadInfo.put("timestamp", uploadDate.time)
uploadInfo.put("utcOffset", TimeZone.getDefault().getOffset(uploadDate.time))
zos.writeFile("UploadInfo.json", uploadInfo.toString().toByteArray())
tags.add("UploadInfo")
zos.close()
val bytes = baos.toByteArray()
Single.just(UploadData(
fileName = "upload-num$uploadNumber-ver1-date${FILE_NAME_DATE_FORMAT.format(uploadDate)}-appid${appId.toString().replace("-", "")}.zip",
metadata = OpenHumansAPI.FileMetadata(
tags = tags,
description = "AndroidAPS Database Upload",
md5 = MessageDigest.getInstance("MD5").digest(bytes).toHexString(),
creationDate = uploadDate.time
),
content = bytes,
highestQueueId = items.map { it.id }.maxOrNull()
))
}
*/
private fun ZipOutputStream.writeFile(name: String, bytes: ByteArray) {
putNextEntry(ZipEntry(name))
write(bytes)
closeEntry()
}
private fun removeUploadedEntriesFromQueue(highestId: Long) = Completable.fromCallable {
// databaseHelper.removeAllOHQueueItemsWithIdSmallerThan(highestId)
}
private fun handleSignOut() {
val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL)
.setContentTitle(resourceHelper.gs(R.string.you_have_been_signed_out_of_open_humans))
.setContentText(resourceHelper.gs(R.string.click_here_to_sign_in_again_if_this_wasnt_on_purpose))
.setStyle(NotificationCompat.BigTextStyle())
.setSmallIcon(R.drawable.notif_icon)
.setAutoCancel(true)
.setContentIntent(PendingIntent.getActivity(
context,
0,
Intent(context, OpenHumansLoginActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
},
0
))
.build()
NotificationManagerCompat.from(context).notify(SIGNED_OUT_NOTIFICATION_ID, notification)
logout()
}
private fun cancelWorker() {
WorkManager.getInstance(context).cancelUniqueWork(WORK_NAME)
}
private fun scheduleWorker(replace: Boolean) {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresCharging(sp.getBoolean("key_oh_charging_only", false))
.build()
val workRequest = PeriodicWorkRequestBuilder<OHUploadWorker>(1, TimeUnit.DAYS)
.setConstraints(constraints)
.setBackoffCriteria(BackoffPolicy.LINEAR, 20, TimeUnit.MINUTES)
.build()
WorkManager.getInstance(context).enqueueUniquePeriodicWork(WORK_NAME, if (replace) ExistingPeriodicWorkPolicy.REPLACE else ExistingPeriodicWorkPolicy.KEEP, workRequest)
}
private fun setupNotificationChannel() {
val notificationManagerCompat = NotificationManagerCompat.from(context)
notificationManagerCompat.createNotificationChannel(NotificationChannel(
NOTIFICATION_CHANNEL,
resourceHelper.gs(R.string.open_humans),
NotificationManager.IMPORTANCE_DEFAULT
))
}
private class UploadData(
val fileName: String,
val metadata: OpenHumansAPI.FileMetadata,
val content: ByteArray,
val highestQueueId: Long?
)
@Suppress("PrivatePropertyName")
private val HEX_DIGITS = "0123456789ABCDEF".toCharArray()
private fun ByteArray.toHexString(): String {
val stringBuilder = StringBuilder()
map { it.toInt() }.forEach {
stringBuilder.append(HEX_DIGITS[(it shr 4) and 0x0F])
stringBuilder.append(HEX_DIGITS[it and 0x0F])
}
return stringBuilder.toString()
}
private fun onSharedPreferenceChanged(event: EventPreferenceChange) {
if (event.changedKey == "key_oh_charging_only" && isSetup) scheduleWorker(true)
}
}

View file

@ -548,14 +548,14 @@ class OverviewData @Inject constructor(
// val start = dateUtil.now() // val start = dateUtil.now()
maxTreatmentsValue = 0.0 maxTreatmentsValue = 0.0
val filteredTreatments: MutableList<DataPointWithLabelInterface> = java.util.ArrayList() val filteredTreatments: MutableList<DataPointWithLabelInterface> = java.util.ArrayList()
repository.getBolusesIncludingInvalidFromTimeToTime(fromTime, endTime, true).blockingGet() repository.getBolusesDataFromTimeToTime(fromTime, endTime, true).blockingGet()
.map { BolusDataPoint(it, resourceHelper, activePlugin, defaultValueHelper) } .map { BolusDataPoint(it, resourceHelper, activePlugin, defaultValueHelper) }
.filter { it.data.type != Bolus.Type.SMB || it.data.isValid } .filter { it.data.type == Bolus.Type.NORMAL || it.data.type == Bolus.Type.SMB }
.forEach { .forEach {
it.y = getNearestBg(it.x.toLong()) it.y = getNearestBg(it.x.toLong())
filteredTreatments.add(it) filteredTreatments.add(it)
} }
repository.getCarbsIncludingInvalidFromTimeToTimeExpanded(fromTime, endTime, true).blockingGet() repository.getCarbsDataFromTimeToTimeExpanded(fromTime, endTime, true).blockingGet()
.map { CarbsDataPoint(it, resourceHelper) } .map { CarbsDataPoint(it, resourceHelper) }
.forEach { .forEach {
it.y = getNearestBg(it.x.toLong()) it.y = getNearestBg(it.x.toLong())

View file

@ -138,7 +138,10 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
_binding = it _binding = it
//check screen width //check screen width
dm = DisplayMetrics() dm = DisplayMetrics()
activity?.windowManager?.defaultDisplay?.getMetrics(dm) if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R)
activity?.display?.getRealMetrics(dm)
else
@Suppress("DEPRECATION") activity?.windowManager?.defaultDisplay?.getMetrics(dm)
}.root }.root
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -175,6 +178,8 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
overviewData.rangeToDisplay = if (overviewData.rangeToDisplay > 24) 6 else overviewData.rangeToDisplay overviewData.rangeToDisplay = if (overviewData.rangeToDisplay > 24) 6 else overviewData.rangeToDisplay
sp.putInt(R.string.key_rangetodisplay, overviewData.rangeToDisplay) sp.putInt(R.string.key_rangetodisplay, overviewData.rangeToDisplay)
overviewData.initRange() overviewData.initRange()
overviewData.prepareBucketedData("EventBucketedDataCreated")
overviewData.prepareBgData("EventBucketedDataCreated")
updateGUI("rangeChange", OverviewData.Property.GRAPH) updateGUI("rangeChange", OverviewData.Property.GRAPH)
rxBus.send(EventPreferenceChange(resourceHelper, R.string.key_rangetodisplay)) rxBus.send(EventPreferenceChange(resourceHelper, R.string.key_rangetodisplay))
sp.putBoolean(R.string.key_objectiveusescale, true) sp.putBoolean(R.string.key_objectiveusescale, true)
@ -737,7 +742,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
graphData.addTreatments() graphData.addTreatments()
if (menuChartSettings[0][OverviewMenus.CharType.ACT.ordinal]) if (menuChartSettings[0][OverviewMenus.CharType.ACT.ordinal])
graphData.addActivity(0.8) graphData.addActivity(0.8)
if (pump.pumpDescription.isTempBasalCapable && menuChartSettings[0][OverviewMenus.CharType.BAS.ordinal]) if ((pump.pumpDescription.isTempBasalCapable || config.NSCLIENT) && menuChartSettings[0][OverviewMenus.CharType.BAS.ordinal])
graphData.addBasals() graphData.addBasals()
graphData.addTargetLine() graphData.addTargetLine()
graphData.addNowLine(dateUtil.now()) graphData.addNowLine(dateUtil.now())

View file

@ -64,12 +64,12 @@ class QuickWizardListActivity : NoSplashAppCompatActivity() {
val manager = fragmentManager val manager = fragmentManager
val editQuickWizardDialog = EditQuickWizardDialog() val editQuickWizardDialog = EditQuickWizardDialog()
val bundle = Bundle() val bundle = Bundle()
bundle.putInt("position", adapterPosition) bundle.putInt("position", bindingAdapterPosition)
editQuickWizardDialog.arguments = bundle editQuickWizardDialog.arguments = bundle
editQuickWizardDialog.show(manager, "EditQuickWizardDialog") editQuickWizardDialog.show(manager, "EditQuickWizardDialog")
} }
removeButton.setOnClickListener { removeButton.setOnClickListener {
quickWizard.remove(adapterPosition) quickWizard.remove(bindingAdapterPosition)
rxBus.send(EventQuickWizardChange()) rxBus.send(EventQuickWizardChange())
} }
} }

View file

@ -181,7 +181,6 @@ class SmsCommunicatorPlugin @Inject constructor(
} }
@Suppress("SpellCheckingInspection") @Suppress("SpellCheckingInspection")
@kotlin.ExperimentalStdlibApi
override fun doWork(): Result { override fun doWork(): Result {
val bundle = dataWorker.pickupBundle(inputData.getLong(DataWorker.STORE_KEY, -1)) val bundle = dataWorker.pickupBundle(inputData.getLong(DataWorker.STORE_KEY, -1))
?: return Result.failure(workDataOf("Error" to "missing input data")) ?: return Result.failure(workDataOf("Error" to "missing input data"))
@ -224,7 +223,6 @@ class SmsCommunicatorPlugin @Inject constructor(
return false return false
} }
@kotlin.ExperimentalStdlibApi
fun processSms(receivedSms: Sms) { fun processSms(receivedSms: Sms) {
if (!isEnabled(PluginType.GENERAL)) { if (!isEnabled(PluginType.GENERAL)) {
aapsLogger.debug(LTag.SMS, "Ignoring SMS. Plugin disabled.") aapsLogger.debug(LTag.SMS, "Ignoring SMS. Plugin disabled.")
@ -341,7 +339,6 @@ class SmsCommunicatorPlugin @Inject constructor(
receivedSms.processed = true receivedSms.processed = true
} }
@kotlin.ExperimentalStdlibApi
private fun processLOOP(divided: Array<String>, receivedSms: Sms) { private fun processLOOP(divided: Array<String>, receivedSms: Sms) {
when (divided[1].uppercase(Locale.getDefault())) { when (divided[1].uppercase(Locale.getDefault())) {
"DISABLE", "STOP" -> { "DISABLE", "STOP" -> {
@ -470,7 +467,6 @@ class SmsCommunicatorPlugin @Inject constructor(
} }
} }
@kotlin.ExperimentalStdlibApi
private fun processNSCLIENT(divided: Array<String>, receivedSms: Sms) { private fun processNSCLIENT(divided: Array<String>, receivedSms: Sms) {
if (divided[1].uppercase(Locale.getDefault()) == "RESTART") { if (divided[1].uppercase(Locale.getDefault()) == "RESTART") {
rxBus.send(EventNSClientRestart()) rxBus.send(EventNSClientRestart())
@ -480,7 +476,6 @@ class SmsCommunicatorPlugin @Inject constructor(
sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat))) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
} }
@kotlin.ExperimentalStdlibApi
private fun processHELP(divided: Array<String>, receivedSms: Sms) { private fun processHELP(divided: Array<String>, receivedSms: Sms) {
when { when {
divided.size == 1 -> { divided.size == 1 -> {
@ -567,7 +562,6 @@ class SmsCommunicatorPlugin @Inject constructor(
} }
} }
@kotlin.ExperimentalStdlibApi
private fun processPROFILE(divided: Array<String>, receivedSms: Sms) { // load profiles private fun processPROFILE(divided: Array<String>, receivedSms: Sms) { // load profiles
val anInterface = activePlugin.activeProfileSource val anInterface = activePlugin.activeProfileSource
val store = anInterface.profile val store = anInterface.profile
@ -621,7 +615,6 @@ class SmsCommunicatorPlugin @Inject constructor(
receivedSms.processed = true receivedSms.processed = true
} }
@kotlin.ExperimentalStdlibApi
private fun processBASAL(divided: Array<String>, receivedSms: Sms) { private fun processBASAL(divided: Array<String>, receivedSms: Sms) {
if (divided[1].uppercase(Locale.getDefault()) == "CANCEL" || divided[1].uppercase(Locale.getDefault()) == "STOP") { if (divided[1].uppercase(Locale.getDefault()) == "CANCEL" || divided[1].uppercase(Locale.getDefault()) == "STOP") {
val passCode = generatePassCode() val passCode = generatePassCode()
@ -738,7 +731,6 @@ class SmsCommunicatorPlugin @Inject constructor(
} }
} }
@kotlin.ExperimentalStdlibApi
private fun processEXTENDED(divided: Array<String>, receivedSms: Sms) { private fun processEXTENDED(divided: Array<String>, receivedSms: Sms) {
if (divided[1].uppercase(Locale.getDefault()) == "CANCEL" || divided[1].uppercase(Locale.getDefault()) == "STOP") { if (divided[1].uppercase(Locale.getDefault()) == "CANCEL" || divided[1].uppercase(Locale.getDefault()) == "STOP") {
val passCode = generatePassCode() val passCode = generatePassCode()
@ -905,7 +897,6 @@ class SmsCommunicatorPlugin @Inject constructor(
return retVal return retVal
} }
@kotlin.ExperimentalStdlibApi
private fun processCARBS(divided: Array<String>, receivedSms: Sms) { private fun processCARBS(divided: Array<String>, receivedSms: Sms) {
var grams = SafeParse.stringToInt(divided[1]) var grams = SafeParse.stringToInt(divided[1])
var time = dateUtil.now() var time = dateUtil.now()
@ -949,7 +940,6 @@ class SmsCommunicatorPlugin @Inject constructor(
} }
} }
@kotlin.ExperimentalStdlibApi
private fun processTARGET(divided: Array<String>, receivedSms: Sms) { private fun processTARGET(divided: Array<String>, receivedSms: Sms) {
val isMeal = divided[1].equals("MEAL", ignoreCase = true) val isMeal = divided[1].equals("MEAL", ignoreCase = true)
val isActivity = divided[1].equals("ACTIVITY", ignoreCase = true) val isActivity = divided[1].equals("ACTIVITY", ignoreCase = true)

View file

@ -106,16 +106,17 @@ class LocalProfilePlugin @Inject constructor(
if (dia < hardLimits.minDia() || dia > hardLimits.maxDia()) return false if (dia < hardLimits.minDia() || dia > hardLimits.maxDia()) return false
if (name.isNullOrEmpty()) return false if (name.isNullOrEmpty()) return false
if (blockFromJsonArray(ic, dateUtil)?.any { it.amount < hardLimits.minIC() || it.amount > hardLimits.maxIC() } != false) return false if (blockFromJsonArray(ic, dateUtil)?.any { it.amount < hardLimits.minIC() || it.amount > hardLimits.maxIC() } != false) return false
if (blockFromJsonArray(isf, dateUtil)?.any { it.amount < HardLimits.MIN_ISF || it.amount > HardLimits.MAX_ISF } != false) return false
if (blockFromJsonArray(basal, dateUtil)?.any { it.amount < pumpDescription.basalMinimumRate || it.amount > 10.0 } != false) return false if (blockFromJsonArray(basal, dateUtil)?.any { it.amount < pumpDescription.basalMinimumRate || it.amount > 10.0 } != false) return false
val low = blockFromJsonArray(targetLow, dateUtil) val low = blockFromJsonArray(targetLow, dateUtil)
val high = blockFromJsonArray(targetHigh, dateUtil) val high = blockFromJsonArray(targetHigh, dateUtil)
if (profileFunction.getUnits() == GlucoseUnit.MGDL) { if (profileFunction.getUnits() == GlucoseUnit.MGDL) {
if (low?.any { it.amount < HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble() || it.amount > HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble() } != false) return false if (low?.any { it.amount < HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble() || it.amount > HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble() } != false) return false
if (high?.any { it.amount < HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble() || it.amount > HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble() } != false) return false if (high?.any { it.amount < HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble() || it.amount > HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble() } != false) return false
if (blockFromJsonArray(isf, dateUtil)?.any { it.amount < HardLimits.MIN_ISF || it.amount > HardLimits.MAX_ISF } != false) return false
} else { } else {
if (low?.any { it.amount < Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), GlucoseUnit.MMOL) || it.amount > Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), GlucoseUnit.MMOL) } != false) return false if (low?.any { it.amount < Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), GlucoseUnit.MMOL) || it.amount > Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), GlucoseUnit.MMOL) } != false) return false
if (high?.any { it.amount < Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), GlucoseUnit.MMOL) || it.amount > Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), GlucoseUnit.MMOL) } != false) return false if (high?.any { it.amount < Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), GlucoseUnit.MMOL) || it.amount > Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), GlucoseUnit.MMOL) } != false) return false
if (blockFromJsonArray(isf, dateUtil)?.any { it.amount < Profile.fromMgdlToUnits(HardLimits.MIN_ISF, GlucoseUnit.MMOL) || it.amount > Profile.fromMgdlToUnits(HardLimits.MAX_ISF, GlucoseUnit.MMOL) } != false) return false
} }
for (i in low.indices) if (low[i].amount > high[i].amount) return false for (i in low.indices) if (low[i].amount > high[i].amount) return false
} }
@ -357,16 +358,18 @@ class LocalProfilePlugin @Inject constructor(
try { try {
for (i in 0 until numOfProfiles) { for (i in 0 until numOfProfiles) {
profiles[i].run { profiles[i].run {
val profile = JSONObject() name?.let { name ->
profile.put("dia", dia) val profile = JSONObject()
profile.put("carbratio", ic) profile.put("dia", dia)
profile.put("sens", isf) profile.put("carbratio", ic)
profile.put("basal", basal) profile.put("sens", isf)
profile.put("target_low", targetLow) profile.put("basal", basal)
profile.put("target_high", targetHigh) profile.put("target_low", targetLow)
profile.put("units", if (mgdl) Constants.MGDL else Constants.MMOL) profile.put("target_high", targetHigh)
profile.put("timezone", TimeZone.getDefault().id) profile.put("units", if (mgdl) Constants.MGDL else Constants.MMOL)
store.put(name, profile) profile.put("timezone", TimeZone.getDefault().id)
store.put(name, profile)
}
} }
} }
if (numOfProfiles > 0) json.put("defaultProfile", currentProfile()?.name) if (numOfProfiles > 0) json.put("defaultProfile", currentProfile()?.name)
@ -410,7 +413,7 @@ class LocalProfilePlugin @Inject constructor(
override fun doWork(): Result { override fun doWork(): Result {
val profileJson = dataWorker.pickupJSONObject(inputData.getLong(DataWorker.STORE_KEY, -1)) val profileJson = dataWorker.pickupJSONObject(inputData.getLong(DataWorker.STORE_KEY, -1))
?: return Result.failure(workDataOf("Error" to "missing input data")) ?: return Result.failure(workDataOf("Error" to "missing input data"))
if (sp.getBoolean(R.string.key_ns_receive_profile_store, false) || config.NSCLIENT) { if (sp.getBoolean(R.string.key_ns_receive_profile_store, true) || config.NSCLIENT) {
val store = ProfileStore(injector, profileJson, dateUtil) val store = ProfileStore(injector, profileJson, dateUtil)
val startDate = store.getStartDate() val startDate = store.getStartDate()
val lastLocalChange = sp.getLong(R.string.key_local_profile_last_change, 0) val lastLocalChange = sp.getLong(R.string.key_local_profile_last_change, 0)

View file

@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.pump.virtual
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.HandlerThread
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -10,6 +11,7 @@ import info.nightscout.androidaps.R
import info.nightscout.androidaps.databinding.VirtualpumpFragmentBinding import info.nightscout.androidaps.databinding.VirtualpumpFragmentBinding
import info.nightscout.androidaps.events.EventExtendedBolusChange import info.nightscout.androidaps.events.EventExtendedBolusChange
import info.nightscout.androidaps.events.EventTempBasalChange import info.nightscout.androidaps.events.EventTempBasalChange
import info.nightscout.androidaps.extensions.toStringFull
import info.nightscout.androidaps.interfaces.IobCobCalculator import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
@ -17,7 +19,6 @@ import info.nightscout.androidaps.plugins.pump.virtual.events.EventVirtualPumpUp
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.extensions.toStringFull
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
@ -37,15 +38,8 @@ class VirtualPumpFragment : DaggerFragment() {
private val disposable = CompositeDisposable() private val disposable = CompositeDisposable()
private val loopHandler = Handler()
private lateinit var refreshLoop: Runnable private lateinit var refreshLoop: Runnable
private lateinit var handler: Handler
init {
refreshLoop = Runnable {
activity?.runOnUiThread { updateGui() }
loopHandler.postDelayed(refreshLoop, T.mins(1).msecs())
}
}
private var _binding: VirtualpumpFragmentBinding? = null private var _binding: VirtualpumpFragmentBinding? = null
@ -58,7 +52,11 @@ class VirtualPumpFragment : DaggerFragment() {
return binding.root return binding.root
} }
@Synchronized override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper)
}
@Synchronized
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
disposable += rxBus disposable += rxBus
@ -73,7 +71,11 @@ class VirtualPumpFragment : DaggerFragment() {
.toObservable(EventExtendedBolusChange::class.java) .toObservable(EventExtendedBolusChange::class.java)
.observeOn(aapsSchedulers.main) .observeOn(aapsSchedulers.main)
.subscribe({ updateGui() }, fabricPrivacy::logException) .subscribe({ updateGui() }, fabricPrivacy::logException)
loopHandler.postDelayed(refreshLoop, T.mins(1).msecs()) refreshLoop = Runnable {
activity?.runOnUiThread { updateGui() }
handler.postDelayed(refreshLoop, T.mins(1).msecs())
}
handler.postDelayed(refreshLoop, T.mins(1).msecs())
updateGui() updateGui()
} }
@ -81,7 +83,7 @@ class VirtualPumpFragment : DaggerFragment() {
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
disposable.clear() disposable.clear()
loopHandler.removeCallbacks(refreshLoop) handler.removeCallbacksAndMessages(null)
} }
@Synchronized @Synchronized

View file

@ -28,6 +28,7 @@ import info.nightscout.androidaps.setupwizard.elements.*
import info.nightscout.androidaps.setupwizard.events.EventSWUpdate import info.nightscout.androidaps.setupwizard.events.EventSWUpdate
import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.androidaps.utils.AndroidPermission
import info.nightscout.androidaps.utils.CryptoUtil import info.nightscout.androidaps.utils.CryptoUtil
import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.extensions.isRunningTest import info.nightscout.androidaps.utils.extensions.isRunningTest
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -53,7 +54,8 @@ class SWDefinition @Inject constructor(
private val importExportPrefs: ImportExportPrefs, private val importExportPrefs: ImportExportPrefs,
private val androidPermission: AndroidPermission, private val androidPermission: AndroidPermission,
private val cryptoUtil: CryptoUtil, private val cryptoUtil: CryptoUtil,
private val config: Config private val config: Config,
private val hardLimits: HardLimits
) { ) {
lateinit var activity: AppCompatActivity lateinit var activity: AppCompatActivity
@ -255,7 +257,7 @@ class SWDefinition @Inject constructor(
.add(SWFragment(injector, this) .add(SWFragment(injector, this)
.add(LocalProfileFragment())) .add(LocalProfileFragment()))
.validator { .validator {
localProfilePlugin.profile?.getDefaultProfile()?.let { ProfileSealed.Pure(it).isValid("StartupWizard", activePlugin.activePump, config, resourceHelper, rxBus) } localProfilePlugin.profile?.getDefaultProfile()?.let { ProfileSealed.Pure(it).isValid("StartupWizard", activePlugin.activePump, config, resourceHelper, rxBus, hardLimits).isValid }
?: false ?: false
} }
.visibility { localProfilePlugin.isEnabled() } .visibility { localProfilePlugin.isEnabled() }

View file

@ -17,7 +17,6 @@ class JSONFormatter @Inject constructor(
private val aapsLogger: AAPSLogger private val aapsLogger: AAPSLogger
) { ) {
@kotlin.ExperimentalStdlibApi
fun format(jsonString: String?): Spanned { fun format(jsonString: String?): Spanned {
jsonString ?: return fromHtml("") jsonString ?: return fromHtml("")
val visitor = JsonVisitor(1, '\t') val visitor = JsonVisitor(1, '\t')

View file

@ -15,6 +15,6 @@ object PercentageSplitter {
*/ */
fun pureName(name: String): String { fun pureName(name: String): String {
val percentageMatch = splitPattern.matcher(name) val percentageMatch = splitPattern.matcher(name)
return if (percentageMatch.find()) percentageMatch.group(1).trim { it <= ' ' } else name return if (percentageMatch.find()) (percentageMatch.group(1) as String).trim { it <= ' ' } else name
} }
} }

View file

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector android:height="100.5272dp" android:viewportHeight="108.36626"
android:viewportWidth="107.79796" android:width="100dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#ff9161" android:pathData="m59.75,62.316c5.179,-2.256 8.801,-7.417 8.801,-13.427 0,-8.086 -6.555,-14.641 -14.641,-14.641 -8.086,0 -14.641,6.555 -14.641,14.641 0,6.01 3.622,11.171 8.801,13.427 -7.849,1.589 -14.555,6.318 -18.76,12.817 5.968,6.896 14.774,11.272 24.589,11.272 9.821,0 18.633,-4.382 24.601,-11.286 -4.205,-6.491 -10.907,-11.215 -18.75,-12.803z"/>
<path android:fillColor="#ff9161" android:pathData="M21.689,33.33 L10.002,21.643c-5.155,7 -8.677,15.271 -10.002,24.25l16.523,0c0.968,-4.535 2.741,-8.776 5.166,-12.563z"/>
<path android:fillColor="#ff9161" android:pathData="m91.275,45.893l16.523,0C106.473,36.909 102.947,28.634 97.787,21.631L86.101,33.317c2.429,3.79 4.205,8.035 5.174,12.576z"/>
<path android:fillColor="#ff9161" android:pathData="M86.305,10.106C79.304,4.91 71.02,1.351 62.022,0l0,15.422l13.059,5.908z"/>
<path android:fillColor="#ff9161" android:pathData="M45.754,15.339L45.754,0.003c-8.995,1.354 -17.276,4.915 -24.274,10.113l10.963,10.963z"/>
<path android:fillColor="#4bc0c7" android:pathData="m26.558,80.554c-4.881,-5.002 -8.405,-11.333 -9.971,-18.394l-16.546,0c4.001,26.128 26.629,46.206 53.858,46.206 27.229,0 49.857,-20.077 53.858,-46.206l-16.546,0c-1.564,7.053 -5.082,13.378 -9.955,18.378 -6.946,7.127 -16.643,11.56 -27.357,11.56 -10.706,0 -20.396,-4.427 -27.341,-11.544z"/>
</vector>

View file

@ -1,58 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/uploaded_data"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Headline" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/the_following_data_will_be_uploaded_to_your_open_humans_account"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/terms_of_use"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Headline" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/open_humans_terms"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
<CheckBox
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/i_understand_and_agree" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/login" />
</LinearLayout>
</ScrollView>

View file

@ -275,6 +275,7 @@
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/overview_pump"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">

View file

@ -164,6 +164,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="5dp" android:layout_marginStart="5dp"
android:visibility="gone"
android:text="@string/remove_button" android:text="@string/remove_button"
android:textAlignment="viewEnd" android:textAlignment="viewEnd"
android:textColor="@android:color/holo_orange_light" /> android:textColor="@android:color/holo_orange_light" />

View file

@ -826,36 +826,6 @@
<string name="formatwithweight">Възраст: %1$.0f Тегло: %2$.0f кг</string> <string name="formatwithweight">Възраст: %1$.0f Тегло: %2$.0f кг</string>
<string name="basalpctfromtdd_label">% от базата</string> <string name="basalpctfromtdd_label">% от базата</string>
<string name="dpvdefaultprofile">Профил по подразбиране</string> <string name="dpvdefaultprofile">Профил по подразбиране</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Довършване на Open Humans инсталация…</string>
<string name="this_may_take_a_while">Това може да отнеме време. Не изключвайте телефона или тази приставка.</string>
<string name="setup_finished">Настройката е завършена</string>
<string name="your_phone_will_upload_data">Телефонът ви скоро ще качва данни в \"Open Humans\".</string>
<string name="your_phone_is_upload_data">Телефонът ви качва данни в \"Open Humans\".</string>
<string name="setup_failed">Настройката е НЕУСПЕШНА</string>
<string name="there_was_an_error">Имаше грешка. Моля, опитайте се да влезете отново, за да продължите. Съжаляваме и ви благодарим!</string>
<string name="open_humans_terms">Това е отворен код, който ще копира данните ви в Open Humans. Ние не запазваме никакви права да споделяме вашите данни с трети страни без изричното ви разрешение. Данните, които проектът и приложението получават, се идентифицират чрез случаен идентификатор на потребител и ще бъдат надеждно предадени на Open Humans акаунт с вашето разрешение за този процес. Можете да спрете качването и да изтриете данните за качване по всяко време чрез www.openhumans.org.</string>
<string name="i_understand_and_agree">Разбирам и съм съгласен.</string>
<string name="login">Вход</string>
<string name="logout">Изход</string>
<string name="oh_logout_confirmation">Наистина ли искате да излезете и да спрете да дарявате данни на науката?</string>
<string name="project_member_id">Project Member ID: %s</string>
<string name="queue_size">Големина на опашката: %d</string>
<string name="terms_of_use">Условия за ползване</string>
<string name="not_logged_in">Не сте влезнали в профила си</string>
<string name="you_need_to_accept_the_of_use_first">Трябва да се съгласите с условията за ползване.</string>
<string name="successfully_logged_in">Успешно влизане</string>
<string name="setup_will_continue_in_background">Настройката ще бъде завършена във фонов режим. Благодаря, че дарявате данните.\n\nМоля, задръжте този плъгин и телефона ви включени, докато настройката да завърши.</string>
<string name="completing_login">Завършване на вход…</string>
<string name="donate_your_data_to_science">Дарете данните си на науката.</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Излязохте от \"Open Humans\".</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Натиснете тук за да влезете отново, ако това не е било нарочно.</string>
<string name="only_upload_if_connected_to_wifi">Качване, само при свързано WiFi</string>
<string name="only_upload_if_charging">Качване само при зареждане</string>
<string name="worker_state">Статус: %s</string>
<string name="uploaded_data">Качени данни</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">Следните данни ще бъдат качвани във вашия Open Humans акаунт: Глюкозни стойности, болуси, въглехидрати, удължени болуси, профилни смени, общи дневни дози, временни базали, временни цели, предпочитания, версия на AAPS, модел на телефона и размери на екрана. Тайна или лична информация, като например вашия адрес на Nightscout или API, няма да бъдат качени.</string>
<string name="setupwizard_pump_riley_link_status">RileyLink статус:</string> <string name="setupwizard_pump_riley_link_status">RileyLink статус:</string>
<string name="filter">Филтър</string> <string name="filter">Филтър</string>
<string name="copytolocalprofile_invalid">Не може да се създаде локален профил. Профилът е невалиден.</string> <string name="copytolocalprofile_invalid">Не може да се създаде локален профил. Профилът е невалиден.</string>

View file

@ -132,7 +132,7 @@
<string name="wronginsulin_label">Chyby v podání inzulínu</string> <string name="wronginsulin_label">Chyby v podání inzulínu</string>
<string name="wronginsulin_whattodo">Co byste měli udělat, pokud jste dostali méně inzulínu, než ukazuje historie pumpy, např. v důsledku okluze, vadné kanyly nebo zapomenutí na opětovné připojení pumpy po sprše? </string> <string name="wronginsulin_whattodo">Co byste měli udělat, pokud jste dostali méně inzulínu, než ukazuje historie pumpy, např. v důsledku okluze, vadné kanyly nebo zapomenutí na opětovné připojení pumpy po sprše? </string>
<string name="wronginsulin_careportal">Odstraňte data z Nightscoutu pro odstranění z historie pumpy.</string> <string name="wronginsulin_careportal">Odstraňte data z Nightscoutu pro odstranění z historie pumpy.</string>
<string name="wronginsulin_compare">Porovnejte hodnoty v AndroidAPS a historii pumpy.</string> <string name="wronginsulin_compare">Porovnat hodnoty v AndroidAPS s hodnotami v historii pumpy (pokud to pumpa podporuje).</string>
<string name="wronginsulin_prime">Pošlete bolus na vypočtený „chybějící“ inzulín buď injekční stříkačkou nebo perem nebo pomocí plnění na pumpě.</string> <string name="wronginsulin_prime">Pošlete bolus na vypočtený „chybějící“ inzulín buď injekční stříkačkou nebo perem nebo pomocí plnění na pumpě.</string>
<string name="wronginsulin_donothing">Neudělejte nic a dovolte AndroidAPS opravit jakoukoliv výslednou vysokou hladinu glukózy v krvi.</string> <string name="wronginsulin_donothing">Neudělejte nic a dovolte AndroidAPS opravit jakoukoliv výslednou vysokou hladinu glukózy v krvi.</string>
<string name="iob_label">Aktivní inzulín (IOB)</string> <string name="iob_label">Aktivní inzulín (IOB)</string>

View file

@ -832,36 +832,6 @@
<string name="formatwithweight">Věk: %1$.0f Hmotnost: %2$.0f kg</string> <string name="formatwithweight">Věk: %1$.0f Hmotnost: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% bazálu</string> <string name="basalpctfromtdd_label">% bazálu</string>
<string name="dpvdefaultprofile">Výchozí profil DPV</string> <string name="dpvdefaultprofile">Výchozí profil DPV</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Dokončit nastavení Open Humans…</string>
<string name="this_may_take_a_while">Může to chvíli trvat. Nevypínejte telefon nebo tento plugin.</string>
<string name="setup_finished">Nastavení dokončeno</string>
<string name="your_phone_will_upload_data">Váš telefon brzy odešle data do Open Humans.</string>
<string name="your_phone_is_upload_data">Váš telefon nyní nahrává data do Open Humans.</string>
<string name="setup_failed">Nastavení selhalo</string>
<string name="there_was_an_error">Došlo k chybě. Chcete-li pokračovat, zkuste se přihlásit znovu. Lituji &amp; Děkuji!</string>
<string name="open_humans_terms">Jedná se o open source nástroj, který zkopíruje vaše data do Open Humans. Zachováváme práva ke sdílení vašich údajů s třetími stranami bez vašeho výslovného povolení. Data, která projekt a aplikace obdrží, jsou identifikována pomocí náhodného ID uživatele a budou bezpečně přenášena pouze na účet Otevřít Humans a jen s vaším svolením. Můžete kdykoli zastavit odesílání a smazat Vaše data prostřednictvím adresy www.openhumans.org.</string>
<string name="i_understand_and_agree">Rozumím a souhlasím.</string>
<string name="login">Přihlášení</string>
<string name="logout">Odhlášení</string>
<string name="oh_logout_confirmation">Opravdu se chcete odhlásit a zastavit darování dat vědě?</string>
<string name="project_member_id">ID člena projektu: %s</string>
<string name="queue_size">Velikost fronty: %d</string>
<string name="terms_of_use">Smluvní podmínky</string>
<string name="not_logged_in">Nejste přihlášen</string>
<string name="you_need_to_accept_the_of_use_first">Nejprve je třeba přijmout podmínky použití.</string>
<string name="successfully_logged_in">Přihlášení proběhlo úspěšně</string>
<string name="setup_will_continue_in_background">Nastavení bude nyní dokončeno na pozadí. Děkujeme za nahrání vašich dat.\n\nNechte prosím tento plugin a váš telefon na krátkou dobu zapnutý, aby bylo dokončeno nastavení.</string>
<string name="completing_login">Dokončení přihlášení…</string>
<string name="donate_your_data_to_science">Darujte svá data vědě</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Byl jste odhlášen z Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Chcete-li se znovu přihlásit, klepněte zde, pokud to nebylo schválně.</string>
<string name="only_upload_if_connected_to_wifi">Odeslat pouze při připojení k Wi-Fi</string>
<string name="only_upload_if_charging">Odeslat pouze při nabíjení</string>
<string name="worker_state">Stav procesu: %s</string>
<string name="uploaded_data">Odeslaná data</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">Následující data budou nahrána do vašeho účtu Open Humans: hodnoty glykémie, bolusy, sacharidy, události péče (kromě poznámek), rozložené bolusy, přepnutí profilu, celkové denní dávky, dočasné bazály, nastavení, verze aplikace, model zařízení a rozměry obrazovky. Tajné nebo soukromé informace, jako je URL nebo API heslo vašeho Nightscoutu, nahrány nebudou.</string>
<string name="setupwizard_pump_riley_link_status">Status RileyLink:</string> <string name="setupwizard_pump_riley_link_status">Status RileyLink:</string>
<string name="filter">Filtr</string> <string name="filter">Filtr</string>
<string name="copytolocalprofile_invalid">Nelze vytvořit lokální profil. Profil je neplatný.</string> <string name="copytolocalprofile_invalid">Nelze vytvořit lokální profil. Profil je neplatný.</string>
@ -921,4 +891,5 @@
<string name="ns_receive_cgm_summary">Přijmout CGM data z NS</string> <string name="ns_receive_cgm_summary">Přijmout CGM data z NS</string>
<string name="sms_timeout_while_wating">Vypršel časový limit při čekání na dokončení předchozí komunikace s pumpou</string> <string name="sms_timeout_while_wating">Vypršel časový limit při čekání na dokončení předchozí komunikace s pumpou</string>
<string name="smscommunicator_another_bolus_in_queue">Ve frontě je další bolus. Zkuste to znovu později.</string> <string name="smscommunicator_another_bolus_in_queue">Ve frontě je další bolus. Zkuste to znovu později.</string>
<string name="calculation_in_progress">Probíhá výpočet</string>
</resources> </resources>

View file

@ -132,7 +132,7 @@
<string name="wronginsulin_label">Fehler bei Insulinabgabe/Eintrag</string> <string name="wronginsulin_label">Fehler bei Insulinabgabe/Eintrag</string>
<string name="wronginsulin_whattodo">Wie solltest Du vorgehen, wenn Du weniger Insulin im Körper hast als in der Pumpenhistorie vermerkt - z.B. durch eine Verstopfung, Kanülenfehler oder eine nach dem Duschen nicht wieder angekoppelte Pumpe?</string> <string name="wronginsulin_whattodo">Wie solltest Du vorgehen, wenn Du weniger Insulin im Körper hast als in der Pumpenhistorie vermerkt - z.B. durch eine Verstopfung, Kanülenfehler oder eine nach dem Duschen nicht wieder angekoppelte Pumpe?</string>
<string name="wronginsulin_careportal">Lösche Insulindaten im Nightscout careportal, um sie aus der Pumpenhistorie zu entfernen.</string> <string name="wronginsulin_careportal">Lösche Insulindaten im Nightscout careportal, um sie aus der Pumpenhistorie zu entfernen.</string>
<string name="wronginsulin_compare">Vergleiche die Werte in AndroidAPS und der Pumpenhistorie.</string> <string name="wronginsulin_compare">Vergleiche die Werte der Historie in AAPS und Deiner Pumpe (wenn die Pumpe diese Funktion bietet).</string>
<string name="wronginsulin_prime">Gib einen Teil-Bolus des \'nicht erhaltenen\' Insulins mit Spritze / Pen oder durch Befüllen der Kanüle.</string> <string name="wronginsulin_prime">Gib einen Teil-Bolus des \'nicht erhaltenen\' Insulins mit Spritze / Pen oder durch Befüllen der Kanüle.</string>
<string name="wronginsulin_donothing">Unternimm nichts und lass AndroidAPS die entstehenden hohen Glukosewerte korrigieren.</string> <string name="wronginsulin_donothing">Unternimm nichts und lass AndroidAPS die entstehenden hohen Glukosewerte korrigieren.</string>
<string name="iob_label">Aktives Insulin (IOB)</string> <string name="iob_label">Aktives Insulin (IOB)</string>

View file

@ -133,6 +133,7 @@
<string name="configbuilder_nightscoutversion_label">Nightscout-Version:</string> <string name="configbuilder_nightscoutversion_label">Nightscout-Version:</string>
<string name="missing_carbs">%1$d g fehlen</string> <string name="missing_carbs">%1$d g fehlen</string>
<string name="exported">Einstellungen exportiert</string> <string name="exported">Einstellungen exportiert</string>
<string name="ue_exported">Benutzereinträge exportiert</string>
<string name="export_to">Einstellungen exportieren nach</string> <string name="export_to">Einstellungen exportieren nach</string>
<string name="import_from">Importiere Einstellungen von</string> <string name="import_from">Importiere Einstellungen von</string>
<string name="setting_imported">Einstellungen importiert</string> <string name="setting_imported">Einstellungen importiert</string>
@ -832,36 +833,6 @@ Unerwartetes Verhalten.</string>
<string name="formatwithweight">Alter: %1$.0f Gewicht: %2$.0f kg</string> <string name="formatwithweight">Alter: %1$.0f Gewicht: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% der Basalrate</string> <string name="basalpctfromtdd_label">% der Basalrate</string>
<string name="dpvdefaultprofile">DPV-Standard-Profil</string> <string name="dpvdefaultprofile">DPV-Standard-Profil</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Einrichtung von Open Humans abschließen…</string>
<string name="this_may_take_a_while">Das kann eine Weile dauern. Schalte Dein Telefon oder dieses Plugin nicht aus.</string>
<string name="setup_finished">Einrichtung abgeschlossen</string>
<string name="your_phone_will_upload_data">Dein Telefon wird in Kürze Daten zu Open Human hochladen.</string>
<string name="your_phone_is_upload_data">Dein Telefon lädt nun Daten zu Open Human hoch.</string>
<string name="setup_failed">Einrichtung fehlgeschlagen</string>
<string name="there_was_an_error">Es gab einen Fehler. Bitte logge Dich erneut ein, um fortzufahren. Entschuldigung &amp; Danke!</string>
<string name="open_humans_terms">Dies ist ein Open-Source-Tool, das Deine Daten zu Open Humans hochlädt. Wir behalten uns keine Rechte vor, Deine Daten ohne Deine ausdrückliche Genehmigung an Dritte weiterzugeben. Die Daten, die das Projekt und die Anwendung erhalten, werden über eine zufällige Benutzer-ID identifiziert und nur nach Deiner Zustimmung sicher auf ein Open Humans-Konto übertragen. Du kannst das Hochladen beenden und Deine hochgeladenen Daten jederzeit über www.openhumans.org löschen.</string>
<string name="i_understand_and_agree">Verstanden und akzeptiert. </string>
<string name="login">Login</string>
<string name="logout">Logout</string>
<string name="oh_logout_confirmation">Willst Du Dich wirklich abmelden und die Spende von Daten an die Wissenschaft beenden?</string>
<string name="project_member_id">Project Member ID: %s</string>
<string name="queue_size">Größe der Warteschlange: %d</string>
<string name="terms_of_use">Nutzungsbedingungen</string>
<string name="not_logged_in">Nicht angemeldet</string>
<string name="you_need_to_accept_the_of_use_first">Du musst zuerst die Nutzungsbedingungen akzeptieren.</string>
<string name="successfully_logged_in">Erfolgreich angemeldet</string>
<string name="setup_will_continue_in_background">Die Einrichtung wird jetzt im Hintergrund abgeschlossen. Vielen Dank für das Hochladen Deiner Daten.\n\nBitte halte dieses Plugin und Dein Handy für kurze Zeit eingeschaltet, damit das Setup abgeschlossen werden kann.</string>
<string name="completing_login">Login wird abgeschlossen…</string>
<string name="donate_your_data_to_science">Spende deine Daten an Wissenschaft</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Du wurdest von Open Humans abgemeldet.</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Klicke hier, um Dich erneut anzumelden, falls dies versehentlich passiert ist.</string>
<string name="only_upload_if_connected_to_wifi">Nur über WLAN hochladen</string>
<string name="only_upload_if_charging">Nur beim Laden hochladen</string>
<string name="worker_state">Worker State: %s</string>
<string name="uploaded_data">Daten hochgeladen</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">Die folgenden Daten werden auf Dein Open Humans-Konto hochgeladen: Glukosewerte, Boli, Kohlenhydrate, Careportal-Ereignisse (außer Notizen), erweiterte Boli, Profilwechsel, Gesamttagesdosen, temporäre Basalwerte, Temporäre Ziele, Einstellungen, Anwendungsversion, Gerätemodell und Bildschirmabmessungen. Vertrauliche oder private Informationen wie z.B. Deine Nightscout-URL oder Dein API-Secret werden nicht hochgeladen.</string>
<string name="setupwizard_pump_riley_link_status">RileyLink Status:</string> <string name="setupwizard_pump_riley_link_status">RileyLink Status:</string>
<string name="filter">Filter</string> <string name="filter">Filter</string>
<string name="copytolocalprofile_invalid">Lokales Profil kann nicht erstellt werden. Profil ist ungültig.</string> <string name="copytolocalprofile_invalid">Lokales Profil kann nicht erstellt werden. Profil ist ungültig.</string>
@ -904,6 +875,7 @@ Unerwartetes Verhalten.</string>
<string name="ns_upload_summary">Profile, Boli, Kohlenhydrate und temporäre Basalraten werden zu NS hochgeladen</string> <string name="ns_upload_summary">Profile, Boli, Kohlenhydrate und temporäre Basalraten werden zu NS hochgeladen</string>
<string name="ns_upload">Daten zu NS hochladen</string> <string name="ns_upload">Daten zu NS hochladen</string>
<string name="ns_receive_profile_store">Gespeicherte Profile abrufen</string> <string name="ns_receive_profile_store">Gespeicherte Profile abrufen</string>
<string name="ns_receive_profile_store_summary">Profile vom NS-Profil-Editors zu lokalen Profil synchronisieren</string>
<string name="ns_receive_temp_target">Temporäre Ziele abrufen</string> <string name="ns_receive_temp_target">Temporäre Ziele abrufen</string>
<string name="ns_receive_temp_target_summary">Temp. Ziele akzeptieren, die in NS oder NSClient eingegeben wurden</string> <string name="ns_receive_temp_target_summary">Temp. Ziele akzeptieren, die in NS oder NSClient eingegeben wurden</string>
<string name="ns_receive_profile_switch">Profilwechsel abrufen</string> <string name="ns_receive_profile_switch">Profilwechsel abrufen</string>

View file

@ -132,7 +132,6 @@
<string name="wronginsulin_label">Errores de entrega/entrada de insulina</string> <string name="wronginsulin_label">Errores de entrega/entrada de insulina</string>
<string name="wronginsulin_whattodo">¿Qué debes hacer si recibiste menos insulina de la que sugiere la historia de la bomba p.ej. debido a una oclusión, una cánula fallida o olvidarse de reponer la bomba después de una ducha?</string> <string name="wronginsulin_whattodo">¿Qué debes hacer si recibiste menos insulina de la que sugiere la historia de la bomba p.ej. debido a una oclusión, una cánula fallida o olvidarse de reponer la bomba después de una ducha?</string>
<string name="wronginsulin_careportal">Elimina los datos de insulina del portal de Nightscout Careportal para eliminarlos del historial de la bomba.</string> <string name="wronginsulin_careportal">Elimina los datos de insulina del portal de Nightscout Careportal para eliminarlos del historial de la bomba.</string>
<string name="wronginsulin_compare">Comparar valores en AndroidAPS e historial de la bomba.</string>
<string name="wronginsulin_prime">Bolo una proporción de la insulina calculada “perdida” por jeringa/pluma o usando menú de llenado.</string> <string name="wronginsulin_prime">Bolo una proporción de la insulina calculada “perdida” por jeringa/pluma o usando menú de llenado.</string>
<string name="wronginsulin_donothing">No haga nada y permite que AndroidAPS corrija cualquier nivel alto de glucosa en la sangre resultante.</string> <string name="wronginsulin_donothing">No haga nada y permite que AndroidAPS corrija cualquier nivel alto de glucosa en la sangre resultante.</string>
<string name="iob_label">Insulina a bordo (IOB)</string> <string name="iob_label">Insulina a bordo (IOB)</string>

View file

@ -826,36 +826,6 @@
<string name="formatwithweight">Edad: %1$.0f Peso: %2$.0f kg</string> <string name="formatwithweight">Edad: %1$.0f Peso: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% de basal</string> <string name="basalpctfromtdd_label">% de basal</string>
<string name="dpvdefaultprofile">Perfil DPV por defecto</string> <string name="dpvdefaultprofile">Perfil DPV por defecto</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Finalizando la configuración de Open Humans…</string>
<string name="this_may_take_a_while">Esto puede tardar un tiempo. No apague su teléfono o este plugin.</string>
<string name="setup_finished">Configuración finalizada</string>
<string name="your_phone_will_upload_data">Tu teléfono subirá los datos a Open Humans pronto.</string>
<string name="your_phone_is_upload_data">Su teléfono está subiendo datos a Open Humans ahora.</string>
<string name="setup_failed">Fallo en la configuración</string>
<string name="there_was_an_error">Se ha producido un error. Vuelva a iniciar sesión para poder continuar. Lo siento &amp; ¡Gracias!</string>
<string name="open_humans_terms">Esta es una herramienta de código abierto que copiará sus datos a Open Humans. No conservamos ningún derecho a compartir sus datos con terceros sin su autorización explícita. Los datos que el proyecto y la aplicación reciben se identifican mediante un ID de usuario aleatorio y sólo se transmitirán de forma segura a una cuenta de Open Humans con la autorización de dicho proceso. Puedes dejar de subir y borrar tus datos en cualquier momento a través de www.openhumans.org.</string>
<string name="i_understand_and_agree">Entiendo y acepto.</string>
<string name="login">Login</string>
<string name="logout">Cerrar sesión</string>
<string name="oh_logout_confirmation">¿Realmente quieres cerrar sesión y dejar de donar datos a la ciencia?</string>
<string name="project_member_id">ID de miembro del proyecto: %s</string>
<string name="queue_size">Tamaño de Cola: %d</string>
<string name="terms_of_use">Condiciones de Uso</string>
<string name="not_logged_in">No has accedido</string>
<string name="you_need_to_accept_the_of_use_first">Primero debe aceptar los términos de uso.</string>
<string name="successfully_logged_in">Sesión iniciada correctamente</string>
<string name="setup_will_continue_in_background">La configuración ahora se completará en segundo plano. Gracias por cargar sus datos.\n\nPor favor, mantenga este plugin y su teléfono encendido por un un momento mientras se completa la configuración.</string>
<string name="completing_login">Completando inicio de sesión…</string>
<string name="donate_your_data_to_science">Dona tus datos a la ciencia</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Has cerrado la sesión de Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Haga clic aquí para iniciar sesión de nuevo si no tenía esa intención.</string>
<string name="only_upload_if_connected_to_wifi">Subir datos solo si está conectado a WiFi</string>
<string name="only_upload_if_charging">Sólo subir datos si se está cargando</string>
<string name="worker_state">Worker State: %s</string>
<string name="uploaded_data">Datos subidos</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">Los siguientes datos se cargarán en su cuenta de Open Humans: valores de glucosa, bolos, carbohidratos, eventos de la bomba (excepto notas), bolos extendidos, cambios de perfil, dosis diarias totales, valores basales temporales, objetivos de temperatura, preferencias, versión de la aplicación, modelo del dispositivo y dimensiones de la pantalla. No se cargará información secreta o privada, como su URL de Nightscout o el API secreto.</string>
<string name="setupwizard_pump_riley_link_status">Estado de RileyLink:</string> <string name="setupwizard_pump_riley_link_status">Estado de RileyLink:</string>
<string name="filter">Filtro</string> <string name="filter">Filtro</string>
<string name="copytolocalprofile_invalid">No se puede crear el perfil local. El perfil no es válido.</string> <string name="copytolocalprofile_invalid">No se puede crear el perfil local. El perfil no es válido.</string>

View file

@ -132,7 +132,6 @@
<string name="wronginsulin_label">Erreurs de saisie/injection d\'insuline</string> <string name="wronginsulin_label">Erreurs de saisie/injection d\'insuline</string>
<string name="wronginsulin_whattodo">Que devriez-vous faire si vous avez reçu moins d\'insuline que l\'historique de la pompe suggère par ex. à cause d\'une occlusion, d\'une mauvaise canule ou d\'un oubli de rebranchement de la pompe après une douche ?</string> <string name="wronginsulin_whattodo">Que devriez-vous faire si vous avez reçu moins d\'insuline que l\'historique de la pompe suggère par ex. à cause d\'une occlusion, d\'une mauvaise canule ou d\'un oubli de rebranchement de la pompe après une douche ?</string>
<string name="wronginsulin_careportal">Supprimez les données d\'insuline de Nightscout Careportal pour le retirer de l\'historique de la pompe.</string> <string name="wronginsulin_careportal">Supprimez les données d\'insuline de Nightscout Careportal pour le retirer de l\'historique de la pompe.</string>
<string name="wronginsulin_compare">Comparez les valeurs dans l\'historique de la pompe et AndroidAPS.</string>
<string name="wronginsulin_prime">Faites un bolus du montant de votre insuline calculée « manquante » soit par seringue / stylo ou en utilisant un amorçage.</string> <string name="wronginsulin_prime">Faites un bolus du montant de votre insuline calculée « manquante » soit par seringue / stylo ou en utilisant un amorçage.</string>
<string name="wronginsulin_donothing">Ne faites rien et laissez AndroidAPS corriger tout taux élevé de glycémie qui en résulte.</string> <string name="wronginsulin_donothing">Ne faites rien et laissez AndroidAPS corriger tout taux élevé de glycémie qui en résulte.</string>
<string name="iob_label">Insuline Active (IA)</string> <string name="iob_label">Insuline Active (IA)</string>

View file

@ -833,36 +833,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="formatwithweight">Âge: %1$.0f Poids: %2$.0f kg</string> <string name="formatwithweight">Âge: %1$.0f Poids: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% de basal</string> <string name="basalpctfromtdd_label">% de basal</string>
<string name="dpvdefaultprofile">Profil par défaut DPV</string> <string name="dpvdefaultprofile">Profil par défaut DPV</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Fin de la configuration d\'Open Humans…</string>
<string name="this_may_take_a_while">Cela peut prendre un certain temps. N\'éteignez pas votre téléphone ni ce plugin.</string>
<string name="setup_finished">Configuration terminée</string>
<string name="your_phone_will_upload_data">Votre téléphone va bientôt télécharger les données vers Open Humans.</string>
<string name="your_phone_is_upload_data">Votre téléphone télécharge les données vers Open Humans.</string>
<string name="setup_failed">Échec de la configuration</string>
<string name="there_was_an_error">Une erreur s\'est produite. Essayez de vous reconnecter pour continuer. Désolé &amp; merci !</string>
<string name="open_humans_terms">Il s\'agit d\'un outil open source qui va copier vos données vers Open Humans. Nous ne conservons aucun droit de partage et vos données ne seront pas partagées avec des tiers sans votre autorisation explicite. Les données que le projet et l\'application reçoivent sont identifiées par un Identifiant utilisateur aléatoire et ne seront transmises à un compte Open Humans qu\'avec votre autorisation et en toute sécurité. Vous pouvez arrêter de télécharger et supprimer vos données de téléchargées à tout moment via www.openhumans.org.</string>
<string name="i_understand_and_agree">Je comprends et je suis d\'accord.</string>
<string name="login">Connexion</string>
<string name="logout">Déconnexion</string>
<string name="oh_logout_confirmation">Voulez-vous vraiment vous déconnecter et arrêter de donner vos données à la science?</string>
<string name="project_member_id">ID utilisateur : %s</string>
<string name="queue_size">Taille de la queue : %d</string>
<string name="terms_of_use">Conditions dUtilisation</string>
<string name="not_logged_in">Non connecté</string>
<string name="you_need_to_accept_the_of_use_first">Vous devez d\'abord accepter les conditions dutilisation.</string>
<string name="successfully_logged_in">Connexion réussie</string>
<string name="setup_will_continue_in_background">La configuration sera terminée en arrière-plan. Merci de télécharger vos données.\n\nVeuillez conserver ce plug-in et votre téléphone allumés pendant un petit moment pour que la configuration se termine.</string>
<string name="completing_login">Fin de la connexion…</string>
<string name="donate_your_data_to_science">Donner vos données à la science</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Vous avez été déconnecté d\'Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Cliquez ici pour vous connecter à nouveau si ce n\'était pas volontaire.</string>
<string name="only_upload_if_connected_to_wifi">Ne télécharger que si connecté au WiFi</string>
<string name="only_upload_if_charging">Ne télécharger que si en charge</string>
<string name="worker_state">État du travail : %s</string>
<string name="uploaded_data">Données transférées</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">Les données suivantes seront téléchargées sur votre compte Open Humans : glycémie, bolus, glucides, événements Careportal (sauf les notes), bolus étendus, changements de profil, doses quotidiennes totales, basales temporaires, cibles temporaires, préférences, version de l\'application, modèle de l\'appareil et dimensions de l\'écran. Les informations secrètes ou privées telles que votre URL Nightscout ou votre API secret ne seront pas téléchargés.</string>
<string name="setupwizard_pump_riley_link_status">État du RileyLink :</string> <string name="setupwizard_pump_riley_link_status">État du RileyLink :</string>
<string name="filter">Filtrer</string> <string name="filter">Filtrer</string>
<string name="copytolocalprofile_invalid">Impossible de créer le profil local. Le profil est invalide.</string> <string name="copytolocalprofile_invalid">Impossible de créer le profil local. Le profil est invalide.</string>

View file

@ -132,7 +132,7 @@
<string name="wronginsulin_label">Errori erogazione/inserimento insulina</string> <string name="wronginsulin_label">Errori erogazione/inserimento insulina</string>
<string name="wronginsulin_whattodo">Cosa dovresti fare se hai ricevuto meno insulina di quanto lo storico del micro suggerisce? Ad esempio a causa di un\'occlusione, una cannula difettosa o l\'aver dimenticato di riattaccare il micro dopo una doccia? </string> <string name="wronginsulin_whattodo">Cosa dovresti fare se hai ricevuto meno insulina di quanto lo storico del micro suggerisce? Ad esempio a causa di un\'occlusione, una cannula difettosa o l\'aver dimenticato di riattaccare il micro dopo una doccia? </string>
<string name="wronginsulin_careportal">Eliminare dal portale Nightscout i dati relativi all\'insulina per rimuoverli dallo storico del micro.</string> <string name="wronginsulin_careportal">Eliminare dal portale Nightscout i dati relativi all\'insulina per rimuoverli dallo storico del micro.</string>
<string name="wronginsulin_compare">Confrontare i valori in AndroidAPS con lo storico del micro.</string> <string name="wronginsulin_compare">Compara valori in AndroidAPS e storico micro (se supportato).</string>
<string name="wronginsulin_prime">Erogare un bolo con parte della tua insulina calcolata \"mancante\" usando una siringa/penna o la funzione caricamento.</string> <string name="wronginsulin_prime">Erogare un bolo con parte della tua insulina calcolata \"mancante\" usando una siringa/penna o la funzione caricamento.</string>
<string name="wronginsulin_donothing">Non fare nulla e permettere ad AndroidAPS di correggere eventuali glicemie alte.</string> <string name="wronginsulin_donothing">Non fare nulla e permettere ad AndroidAPS di correggere eventuali glicemie alte.</string>
<string name="iob_label">Insulina attiva (IOB)</string> <string name="iob_label">Insulina attiva (IOB)</string>

View file

@ -832,36 +832,6 @@
<string name="formatwithweight">Età: %1$.0f Peso: %2$.0f kg</string> <string name="formatwithweight">Età: %1$.0f Peso: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% di basale</string> <string name="basalpctfromtdd_label">% di basale</string>
<string name="dpvdefaultprofile">Profilo DPV predefinito</string> <string name="dpvdefaultprofile">Profilo DPV predefinito</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Completamento configurazione Open Humans…</string>
<string name="this_may_take_a_while">Potrebbe volerci un po\' di tempo. Non spegnere il tuo telefono e non disattivare questo plugin.</string>
<string name="setup_finished">Configurazione completata</string>
<string name="your_phone_will_upload_data">Il tuo telefono caricherà a breve i dati su Open Humans.</string>
<string name="your_phone_is_upload_data">Il tuo telefono sta caricando ora i dati su Open Humans.</string>
<string name="setup_failed">Configurazione fallita</string>
<string name="there_was_an_error">Si è verificato un errore. Prova ad accedere di nuovo per procedere.</string>
<string name="open_humans_terms">Questo è uno strumento open source che copierà i tuoi dati su Open Humans. Non ci riserviamo alcun diritto di condividere i tuoi dati con terze parti senza la tua esplicita autorizzazione. I dati che il progetto e l\'app ricevono vengono identificati tramite un ID utente casuale e verranno trasmessi in modo sicuro a un account Open Humans solo con la tua autorizzazione per tale processo. Puoi interrompere il caricamento ed eliminare i dati di caricamento in qualsiasi momento tramite www.openhumans.org.</string>
<string name="i_understand_and_agree">Comprendo e accetto.</string>
<string name="login">Login</string>
<string name="logout">Logout</string>
<string name="oh_logout_confirmation">Vuoi davvero fare il logout e smettere di donare dati alla scienza?</string>
<string name="project_member_id">Project Member ID: %s</string>
<string name="queue_size">Dimensione coda: %d</string>
<string name="terms_of_use">Termini d\'uso</string>
<string name="not_logged_in">Accesso non effettuato</string>
<string name="you_need_to_accept_the_of_use_first">Devi prima accettare i termini d\'uso.</string>
<string name="successfully_logged_in">Accesso riuscito</string>
<string name="setup_will_continue_in_background">La configurazione verrà ora completata in background. Grazie per il caricamento dei tuoi dati.\n\nPer completare la configurazione, mantieni questo plugin attivo e il telefono acceso per un po\' di tempo.</string>
<string name="completing_login">Completamento accesso…</string>
<string name="donate_your_data_to_science">Dona i tuoi dati alla scienza</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Sei stato disconnesso da Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Fare click qui per accedere di nuovo.</string>
<string name="only_upload_if_connected_to_wifi">Upload solo se connesso a WiFi</string>
<string name="only_upload_if_charging">Upload solo se in carica</string>
<string name="worker_state">Worker State: %s</string>
<string name="uploaded_data">Dati caricati</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">I seguenti dati verranno caricati sul tuo account Open Humans: valori glicemia, boli, carboidrati, eventi portale (eccetto note), boli estesi, cambi profilo, dosi giornaliere totali (TDD), basali temporanee, target temporanei, preferenze, versione dell\'applicazione, modello del dispositivo e dimensioni dello schermo. Informazioni segrete o private come l\'URL di Nightscout o l\'API secret non verranno caricate.</string>
<string name="setupwizard_pump_riley_link_status">Stato RileyLink:</string> <string name="setupwizard_pump_riley_link_status">Stato RileyLink:</string>
<string name="filter">Filtro</string> <string name="filter">Filtro</string>
<string name="copytolocalprofile_invalid">Impossibile creare il profilo locale. Il profilo non è valido.</string> <string name="copytolocalprofile_invalid">Impossibile creare il profilo locale. Il profilo non è valido.</string>
@ -921,4 +891,5 @@
<string name="ns_receive_cgm_summary">Accetta dati CGM da NS</string> <string name="ns_receive_cgm_summary">Accetta dati CGM da NS</string>
<string name="sms_timeout_while_wating">Timeout nell\'attesa della fine della precedente comunicazione col micro.</string> <string name="sms_timeout_while_wating">Timeout nell\'attesa della fine della precedente comunicazione col micro.</string>
<string name="smscommunicator_another_bolus_in_queue">C\'è un altro bolo in coda. Riprova più tardi.</string> <string name="smscommunicator_another_bolus_in_queue">C\'è un altro bolo in coda. Riprova più tardi.</string>
<string name="calculation_in_progress">Calcolo in corso</string>
</resources> </resources>

View file

@ -132,7 +132,7 @@
<string name="wronginsulin_label">שגיאות ברישום\\הזרקת אינסולין</string> <string name="wronginsulin_label">שגיאות ברישום\\הזרקת אינסולין</string>
<string name="wronginsulin_whattodo">מה עליכם לעשות אם מקבלים פחות אינסולין מאשר המוצע ע\"י היסטוריית המשאבה, למשל עקב חסימה, צינורית כושלת או אי חיבור מחדש של המשאבה אחרי מקלחת? </string> <string name="wronginsulin_whattodo">מה עליכם לעשות אם מקבלים פחות אינסולין מאשר המוצע ע\"י היסטוריית המשאבה, למשל עקב חסימה, צינורית כושלת או אי חיבור מחדש של המשאבה אחרי מקלחת? </string>
<string name="wronginsulin_careportal">מחקו את נתוני האינסולין מפורטל הטיפולים של נייטסקאוט כדי לסלק אותם מהיסטוריית המשאבה.</string> <string name="wronginsulin_careportal">מחקו את נתוני האינסולין מפורטל הטיפולים של נייטסקאוט כדי לסלק אותם מהיסטוריית המשאבה.</string>
<string name="wronginsulin_compare">השוו את הערכים שב-AndroidAPS לאלה שבהיסטוריית משאבה.</string> <string name="wronginsulin_compare">השוו את הרשומות שב-AndroidAPS עם היסטוריית המשאבה (אם המשאבה תומכת בכך).</string>
<string name="wronginsulin_prime">מזריקים בולוס על חלק מהאינסולין המחושב \"שחסר\" עם מזרק\\עט או באמצעות תיחול (Prime).</string> <string name="wronginsulin_prime">מזריקים בולוס על חלק מהאינסולין המחושב \"שחסר\" עם מזרק\\עט או באמצעות תיחול (Prime).</string>
<string name="wronginsulin_donothing">לא לעשות דבר ולאפשר ל-AndroidAPS לתקן כל רמת סוכר גבוהה.</string> <string name="wronginsulin_donothing">לא לעשות דבר ולאפשר ל-AndroidAPS לתקן כל רמת סוכר גבוהה.</string>
<string name="iob_label">אינסולין פעיל בגוף (IOB)</string> <string name="iob_label">אינסולין פעיל בגוף (IOB)</string>

View file

@ -289,7 +289,7 @@
<string name="openapsama_autosens_adjusttargets">וויסות ערכי מטרה ע\"י Autosens</string> <string name="openapsama_autosens_adjusttargets">וויסות ערכי מטרה ע\"י Autosens</string>
<string name="openapsama_autosens_adjusttargets_summary">ערך ברירת מחדל: התאמה מדויקת\n נועד לאפשר ל-Autosens לשנות את המטרה של ערכי הסוכר, בנוסף ליחס התיקון והבזאלים.</string> <string name="openapsama_autosens_adjusttargets_summary">ערך ברירת מחדל: התאמה מדויקת\n נועד לאפשר ל-Autosens לשנות את המטרה של ערכי הסוכר, בנוסף ליחס התיקון והבזאלים.</string>
<string name="openapsama_bolussnooze_dia_divisor_summary">ערך ברירת מחדל: 2\n מעכב בולוס מופעל אחרי שאתם מזריקים בולוס ארוחה, כך שהלולאה לא תפצה ע\"י בזאלי זמני נמוך אחרי הארוחה. הדוגמה כאן וברירת המחדל היא 2; כך שהגדרה של משך פעילות אינסולין של 3 שעות משמעה שהעיכוב יחלוף בהדרגה בתוך 1.5 שעות (3 ש\' לחלק ל-2).</string> <string name="openapsama_bolussnooze_dia_divisor_summary">ערך ברירת מחדל: 2\n מעכב בולוס מופעל אחרי שאתם מזריקים בולוס ארוחה, כך שהלולאה לא תפצה ע\"י בזאלי זמני נמוך אחרי הארוחה. הדוגמה כאן וברירת המחדל היא 2; כך שהגדרה של משך פעילות אינסולין של 3 שעות משמעה שהעיכוב יחלוף בהדרגה בתוך 1.5 שעות (3 ש\' לחלק ל-2).</string>
<string name="openapsama_min_5m_carbimpact_summary">ערך ברירת מחדל: 3.0 (AMA) או 8.0 (SMB). זוהי הגדרת ברירת מחדל לספיגת פחמימות ב-5 דקות. ברירת המחדל היא 3mg/dL/5min. פעולה זו משפיעה על קצב הדעיכה של פחמ\' פעילות, ועל הנחת קצב ספיגת הפחמ\' בחישוב רמות סוכר עתידיות כשהן בירידה מהירה מהצפוי או עליה איטית מהצפוי.</string> <string name="openapsama_min_5m_carbimpact_summary">ערך ברירת מחדל: 3.0 (AMA) או 8.0 (SMB). זוהי הגדרת ברירת מחדל להשפעת פחמימות על הסוכר בדם ב-5 דקות. ברירת המחדל היא 3mg/dL/5min. פעולה זו משפיעה על קצב הדעיכה של פחמ\' פעילות, ועל הנחת קצב ספיגת הפחמ\' בחישוב רמות סוכר עתידיות כשהן בירידה מהירה מהצפוי או עליה איטית מהצפוי.</string>
<string name="openapsama_link_to_preferncejson_doc_txt">שימו לב!\nבדרך כלל אינכם צריכים לשנות את הערכים שלהלן. נא ללחוץ כאן, לקרוא את הטקסט ולוודא שאתם מבינים אותו לפני שתשנו ערכים אלה.</string> <string name="openapsama_link_to_preferncejson_doc_txt">שימו לב!\nבדרך כלל אינכם צריכים לשנות את הערכים שלהלן. נא ללחוץ כאן, לקרוא את הטקסט ולוודא שאתם מבינים אותו לפני שתשנו ערכים אלה.</string>
<string name="smscommunicator_invalidphonennumber">מספר טלפון ל-SMS אינו תקין</string> <string name="smscommunicator_invalidphonennumber">מספר טלפון ל-SMS אינו תקין</string>
<string name="overview_calibration">כיול</string> <string name="overview_calibration">כיול</string>
@ -359,7 +359,7 @@
<string name="smscommunicator_wrongduration">משך שגוי</string> <string name="smscommunicator_wrongduration">משך שגוי</string>
<string name="smscommunicator_loopsuspended">לולאה מושהית</string> <string name="smscommunicator_loopsuspended">לולאה מושהית</string>
<string name="smscommunicator_loopresumed">לולאה חודשה</string> <string name="smscommunicator_loopresumed">לולאה חודשה</string>
<string name="treatments_wizard_bgtrend_label">מגמה 15 דקות</string> <string name="treatments_wizard_bgtrend_label">מגמת 15 דקות</string>
<string name="treatments_wizard_cob_label">פחמ\' פעילות</string> <string name="treatments_wizard_cob_label">פחמ\' פעילות</string>
<string name="superbolus">סופר בולוס</string> <string name="superbolus">סופר בולוס</string>
<string name="ns_logappstartedevent">רשום הפעלת AAPS ב-Nightscout</string> <string name="ns_logappstartedevent">רשום הפעלת AAPS ב-Nightscout</string>
@ -832,36 +832,6 @@
<string name="formatwithweight">גיל: %1$.0f יח\' משקל: %2$.0f ק\"ג</string> <string name="formatwithweight">גיל: %1$.0f יח\' משקל: %2$.0f ק\"ג</string>
<string name="basalpctfromtdd_label">% של הבזאלי</string> <string name="basalpctfromtdd_label">% של הבזאלי</string>
<string name="dpvdefaultprofile">פרופיל ברירת מחדל</string> <string name="dpvdefaultprofile">פרופיל ברירת מחדל</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">מסיים התקנת Open Humans…</string>
<string name="this_may_take_a_while">זה עלול לקחת זמן מה. נא לא לכבות את את המכשיר או את התוסף.</string>
<string name="setup_finished">ההתקנה הושלמה</string>
<string name="your_phone_will_upload_data">מכשירכם ישלח את מידע ל-Open Humans בהקדם.</string>
<string name="your_phone_is_upload_data">מכשירכם שולח כעת את המידע ל-Open Humans.</string>
<string name="setup_failed">ההתקנה נכשלה</string>
<string name="there_was_an_error">חלה שגיאה. בבקשה נסו להתחבר שוב כדי להמשיך. סליחה ותודה!</string>
<string name="open_humans_terms">זהו כלי קוד פתוח שיעתיק את הנתונים שלכם ל-Open Humans. אין לנו זכויות לחלוק את הנתונים שלך עם צדדים שלישיים ללא אישורכם המפורש. הנתונים שהפרויקט והיישום מקבלים מזוהים באמצעות מספר זיהוי משתמש אקראי ויעברו באופן מאובטח לחשבון Open Humans באישורכם. תוכלו להפסיק לשלוח ולמחוק את נתוניכם בכל עת דרך www.openhumans.org.</string>
<string name="i_understand_and_agree">אני מבינ\\ה ומסכימ\\ה.</string>
<string name="login">התחברות</string>
<string name="logout">התנתקות</string>
<string name="oh_logout_confirmation">אתם בטוחים שברצונכם להתנתק ולהפסיק לתרום מידע למדע?</string>
<string name="project_member_id">זיהוי משתתף פרויקט: %s</string>
<string name="queue_size">גודל התור: %d</string>
<string name="terms_of_use">תנאי השימוש</string>
<string name="not_logged_in">לא מחובר\\ת</string>
<string name="you_need_to_accept_the_of_use_first">עליכם להסכים לתנאי השימוש.</string>
<string name="successfully_logged_in">ההתחברות הצליחה</string>
<string name="setup_will_continue_in_background">ההתקנה תושלם כעת ברקע. תודה על שליחת הנתונים שלכם.\n\nאנא השאירו את תוסף זה ואת מכשיר הטלפון שלכם מופעל לזמן קצר כדי להשלים את ההתקנה.</string>
<string name="completing_login">משלים התחברות…</string>
<string name="donate_your_data_to_science">תרמו את נתוניכם למדע</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">התנתקתם מ-Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">לחצו כאן כדי להתחבר מחדש אם זה לא היה בכוונה.</string>
<string name="only_upload_if_connected_to_wifi">אפשר העלאה רק אם מחובר ל-WiFi</string>
<string name="only_upload_if_charging">אפשר העלאה רק בזמן טעינת הסוללה</string>
<string name="worker_state">מצב עובד: %s</string>
<string name="uploaded_data">נתונים שהועלו</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">הנתונים הבאים יועלו לחשבון Open Humans שלכם: ערכי גלוקוז, בולוסים, פחמימות, אירועים מפורטל הטיפולים (מלבד הערות), בולוסים ממושכים, החלפות פרופיל, מינונים יומיים כוללים, באזאלים זמניים, ערכי מטרה זמניים, העדפות, גרסת יישום, דגם המכשיר ומממדי המסך. מידע סודי או פרטי כגון כתובת ה-Nightscout האישית או סוד ה-API שלכם לא יועלו.</string>
<string name="setupwizard_pump_riley_link_status">מצב ריילילינק:</string> <string name="setupwizard_pump_riley_link_status">מצב ריילילינק:</string>
<string name="filter">סינון</string> <string name="filter">סינון</string>
<string name="copytolocalprofile_invalid">לא ניתן ליצור פרופיל מקומי. הפרופיל אינו חוקי.</string> <string name="copytolocalprofile_invalid">לא ניתן ליצור פרופיל מקומי. הפרופיל אינו חוקי.</string>
@ -921,4 +891,5 @@
<string name="ns_receive_cgm_summary">קבלת נתוני סנסור מנייטסקאוט</string> <string name="ns_receive_cgm_summary">קבלת נתוני סנסור מנייטסקאוט</string>
<string name="sms_timeout_while_wating">בהמתנה עד לסיום תקשורת קודמת עם המשאבה</string> <string name="sms_timeout_while_wating">בהמתנה עד לסיום תקשורת קודמת עם המשאבה</string>
<string name="smscommunicator_another_bolus_in_queue">ישנו בולוס נוסף בתור. נסו שוב מאוחר יותר.</string> <string name="smscommunicator_another_bolus_in_queue">ישנו בולוס נוסף בתור. נסו שוב מאוחר יותר.</string>
<string name="calculation_in_progress">מבצע חישוב</string>
</resources> </resources>

View file

@ -132,7 +132,6 @@
<string name="wronginsulin_label">인슐린 주입/입력 오류</string> <string name="wronginsulin_label">인슐린 주입/입력 오류</string>
<string name="wronginsulin_whattodo">만약 펌프 기록에서 보여지는 것보다 인슐린이 적게 주입되었을 때 어떻게 해야 할까요? (예를 들어, 주입 막힘, 캐뉼라 문제, 샤워 후 펌프 재부착을 잊어버렸을 때)</string> <string name="wronginsulin_whattodo">만약 펌프 기록에서 보여지는 것보다 인슐린이 적게 주입되었을 때 어떻게 해야 할까요? (예를 들어, 주입 막힘, 캐뉼라 문제, 샤워 후 펌프 재부착을 잊어버렸을 때)</string>
<string name="wronginsulin_careportal">Nightscout 케어포탈에서 인슐린 데이터를 삭제하여 펌프 기록에서 이를 제거합니다.</string> <string name="wronginsulin_careportal">Nightscout 케어포탈에서 인슐린 데이터를 삭제하여 펌프 기록에서 이를 제거합니다.</string>
<string name="wronginsulin_compare">AndroidAPS와 펌프 기록을 비교합니다.</string>
<string name="wronginsulin_prime">\"주입되지 않은\" 인슐린양을 계산하여 시린지/펜 또는 prime 기능을 사용하여 인슐린을 주입합니다.</string> <string name="wronginsulin_prime">\"주입되지 않은\" 인슐린양을 계산하여 시린지/펜 또는 prime 기능을 사용하여 인슐린을 주입합니다.</string>
<string name="wronginsulin_donothing">특별한 조치를 취하지 않고, AndroidAPS가 결과적으로 높은 혈당 정도를 조정할 수 있도록 합니다.</string> <string name="wronginsulin_donothing">특별한 조치를 취하지 않고, AndroidAPS가 결과적으로 높은 혈당 정도를 조정할 수 있도록 합니다.</string>
<string name="iob_label">활성 인슐린 (IOB)</string> <string name="iob_label">활성 인슐린 (IOB)</string>

View file

@ -132,7 +132,6 @@
<string name="wronginsulin_label">Insulino suleidimo / įrašų klaidos</string> <string name="wronginsulin_label">Insulino suleidimo / įrašų klaidos</string>
<string name="wronginsulin_whattodo">Ką turėtumėte daryti, jei buvo suleista mažiau insulino nei rodo pompos istorija, pvz. dėl užsikimšimo, neveikiančios kaniulės ar pamiršus po dušo vėl pritvirtinti pompą? </string> <string name="wronginsulin_whattodo">Ką turėtumėte daryti, jei buvo suleista mažiau insulino nei rodo pompos istorija, pvz. dėl užsikimšimo, neveikiančios kaniulės ar pamiršus po dušo vėl pritvirtinti pompą? </string>
<string name="wronginsulin_careportal">Ištrinti insulino suleidimo įrašą per Nightscout Careportal, kad pašalintumėte jį iš pompos istorijos.</string> <string name="wronginsulin_careportal">Ištrinti insulino suleidimo įrašą per Nightscout Careportal, kad pašalintumėte jį iš pompos istorijos.</string>
<string name="wronginsulin_compare">Palyginti įrašus AndroidAPS ir pompos istorijoje.</string>
<string name="wronginsulin_prime">Susileisti trūkstamą insulino kiekį švirkštu ar naudojantis infuzinės sistemos užpildymo funkcija.</string> <string name="wronginsulin_prime">Susileisti trūkstamą insulino kiekį švirkštu ar naudojantis infuzinės sistemos užpildymo funkcija.</string>
<string name="wronginsulin_donothing">Nieko nedaryti ir leisti AndroidAPS koreguoti padidėjusį gliukozės kiekį kraujyje.</string> <string name="wronginsulin_donothing">Nieko nedaryti ir leisti AndroidAPS koreguoti padidėjusį gliukozės kiekį kraujyje.</string>
<string name="iob_label">Aktyvus insulinas organizme (AIO)</string> <string name="iob_label">Aktyvus insulinas organizme (AIO)</string>

View file

@ -810,35 +810,6 @@
<string name="formatwithweight">Amžius: %1$.0f Svoris: %2$.0f kg</string> <string name="formatwithweight">Amžius: %1$.0f Svoris: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% bazės</string> <string name="basalpctfromtdd_label">% bazės</string>
<string name="dpvdefaultprofile">Numatytasis profilis</string> <string name="dpvdefaultprofile">Numatytasis profilis</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Baigiama Open Humans sąranka…</string>
<string name="this_may_take_a_while">Tai gali užtrukti. Neišjunkite telefono ar šio papildinio.</string>
<string name="setup_finished">Sąranka baigta</string>
<string name="your_phone_will_upload_data">Netrukus jūsų telefonas įkels duomenis į Open Human.</string>
<string name="your_phone_is_upload_data">Jūsų telefonas įkelia duomenis į Open Human.</string>
<string name="setup_failed">Sąranka nepavyko</string>
<string name="there_was_an_error">Įvyko klaida. Norėdami tęsti, prisijunkite dar kartą. Atsiprašome &amp; Ačiū!</string>
<string name="open_humans_terms">Tai yra atviro kodo įrankis, kuris nukopijuoja jūsų duomenis į Open Humans. Mes neturime teisės perduoti jūsų duomenų trečiosioms šalims be aiškaus jūsų sutikimo. Duomenys, kuriuos gauna projektas ir programa, identifikuojami pagal atsitiktinį vartotojo ID ir tik tada saugiai perkeliami į Open Humans paskyrą, jei sutinkate su šiuo procesu. Galite bet kada sustabdyti įkėlimą ir ištrinti savo įkeltus duomenis apsilankę www.openhumans.org.</string>
<string name="i_understand_and_agree">Aš suprantu ir sutinku.</string>
<string name="login">Prisijungti</string>
<string name="logout">Atsijungti</string>
<string name="oh_logout_confirmation">Ar tikrai norite atsisakyti prenumeratos ir nebeteikti duomenų mokslui?</string>
<string name="project_member_id">Projekto nario ID: %s</string>
<string name="queue_size">Eilės Dydis: %d</string>
<string name="terms_of_use">Naudojimosi sąlygos</string>
<string name="not_logged_in">Neprisijungęs</string>
<string name="you_need_to_accept_the_of_use_first">Jūs turite sutikti su naudojimo sąlygomis.</string>
<string name="successfully_logged_in">Sėkmingai prisijungta</string>
<string name="setup_will_continue_in_background">Sąranka bus baigta fone. Dėkojame, kad įkėlėte duomenis. \n\n Palaikykite šį papildinį ir telefoną įjungtus, kad būtų galima užbaigti sąranką.</string>
<string name="completing_login">Užbaigiamas prisijungimas…</string>
<string name="donate_your_data_to_science">Paaukokite savo duomenis mokslui</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Jūs buvote atjungtas iš Open Humans</string>
<string name="only_upload_if_connected_to_wifi">Tik įkelti, jei prijungta prie WiFi</string>
<string name="only_upload_if_charging">Įkelti tik akumuliatoriaus įkrovimo metu</string>
<string name="worker_state">Darbinė Būklė: %s</string>
<string name="uploaded_data">Įkelti duomenis</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">Į jūsų Open Humans paskyrą bus įkelti šie duomenys: glikemijos reikšmės, bolusai, angliavandeniai, priežiūros portalo įvykiai (išskyrus pastabas), ištęstiniai bolusai, profilio pakeitimai, visos paros dozės, laikinos valandinės bazės, laikini tikslai, nustatymai, programos versija, įrenginio modelis ir ekrano matmenys. Konfidenciali ar privati informacija, pvz., Jūsų Nightscout URL arba API slaptažodis, nebus įkelta.</string>
<string name="setupwizard_pump_riley_link_status">RileyLink statusas:</string> <string name="setupwizard_pump_riley_link_status">RileyLink statusas:</string>
<string name="filter">Filtruoti</string> <string name="filter">Filtruoti</string>
<string name="copytolocalprofile_invalid">Nepavyksta sukurti vietinio profilio. Profilis neteisingas.</string> <string name="copytolocalprofile_invalid">Nepavyksta sukurti vietinio profilio. Profilis neteisingas.</string>

View file

@ -132,7 +132,6 @@
<string name="wronginsulin_label">Insulinetoediening/-invoerfouten</string> <string name="wronginsulin_label">Insulinetoediening/-invoerfouten</string>
<string name="wronginsulin_whattodo">Wat moet je doen wanneer je minder insuline toegediend hebt gekregen dan de geschiedenis van de pomp suggereert, bijvoorbeeld vanwege een verstopping, een lekkende canule of door het vergeten de pomp opnieuw aan te koppelen na een douche? </string> <string name="wronginsulin_whattodo">Wat moet je doen wanneer je minder insuline toegediend hebt gekregen dan de geschiedenis van de pomp suggereert, bijvoorbeeld vanwege een verstopping, een lekkende canule of door het vergeten de pomp opnieuw aan te koppelen na een douche? </string>
<string name="wronginsulin_careportal">Verwijder de insulinegegevens uit het Nightscout Careportal om deze uit de pompgeschiedenis te verwijderen.</string> <string name="wronginsulin_careportal">Verwijder de insulinegegevens uit het Nightscout Careportal om deze uit de pompgeschiedenis te verwijderen.</string>
<string name="wronginsulin_compare">Vergelijk de waarden in AndroidAPS met de pompgeschiedenis.</string>
<string name="wronginsulin_prime">Bolus een deel van je berekende \'gemiste\' insuline door een injectiespuit/pen of door de uitvulfunctie te gebruiken.</string> <string name="wronginsulin_prime">Bolus een deel van je berekende \'gemiste\' insuline door een injectiespuit/pen of door de uitvulfunctie te gebruiken.</string>
<string name="wronginsulin_donothing">Doe niets en laat AndroidAPS de resulterende hoge bloedglucosespiegel corrigeren.</string> <string name="wronginsulin_donothing">Doe niets en laat AndroidAPS de resulterende hoge bloedglucosespiegel corrigeren.</string>
<string name="iob_label">Insuline aan boord (IOB)</string> <string name="iob_label">Insuline aan boord (IOB)</string>

View file

@ -832,36 +832,6 @@
<string name="formatwithweight">Leeftijd: %1$.0f gewicht: %2$.0f kg</string> <string name="formatwithweight">Leeftijd: %1$.0f gewicht: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% van basaal</string> <string name="basalpctfromtdd_label">% van basaal</string>
<string name="dpvdefaultprofile">DPV Basis profiel</string> <string name="dpvdefaultprofile">DPV Basis profiel</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Setup van Open Humans voltooien…</string>
<string name="this_may_take_a_while">Dit kan even duren. Zet de telefoon of plugin niet uit.</string>
<string name="setup_finished">Setup voltooid</string>
<string name="your_phone_will_upload_data">Je telefoon zal binnenkort data gaan uploaden naar Open Humans.</string>
<string name="your_phone_is_upload_data">Je telefoon is data aan het uploaden naar Open Humans.</string>
<string name="setup_failed">Setup mislukt</string>
<string name="there_was_an_error">Er is een fout opgetreden. Probeer opnieuw in te loggen. Sorry &amp; bedankt!</string>
<string name="open_humans_terms">Dit is een open source tool die je data uploadt naar Open Humans. Wij behouden geen rechten om je gegevens te delen met derden zonder jouw uitdrukkelijke toestemming. De gegevens die het project en de app ontvangen, worden geïdentificeerd aan de hand van een willekeurig gebruikers-ID en worden uitsluitend veilig verzonden naar een Open Humans account met jouw toestemming voor dat proces. Je kunt op elk gewenst moment stoppen met uploaden en je data verwijderen via www.openhumans.org.</string>
<string name="i_understand_and_agree">Ik begrijp het en ga akkoord.</string>
<string name="login">Inloggen</string>
<string name="logout">Uitloggen</string>
<string name="oh_logout_confirmation">Weet je zeker dat je uit wilt loggen en wilt stoppen met het doneren van gegevens aan de wetenschap?</string>
<string name="project_member_id">Projectlid-ID: %s</string>
<string name="queue_size">Grootte wachtrij: %d</string>
<string name="terms_of_use">Gebruiksvoorwaarden</string>
<string name="not_logged_in">Niet ingelogd</string>
<string name="you_need_to_accept_the_of_use_first">Je moet eerst instemmen met de voorwaarden.</string>
<string name="successfully_logged_in">Succesvol ingelogd</string>
<string name="setup_will_continue_in_background">De setup wordt nu op de achtergrond voltooid. Bedankt voor het uploaden van je gegevens.\n\nHoud deze plugin en je telefoon even ingeschakeld om de setup te voltooien.</string>
<string name="completing_login">Login voltooien…</string>
<string name="donate_your_data_to_science">Doneer je gegevens aan de wetenschap</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Je bent uitgelogd van Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Klik hier om opnieuw in te loggen als dit niet opzettelijk was.</string>
<string name="only_upload_if_connected_to_wifi">Alleen uploaden indien verbonden met WiFi</string>
<string name="only_upload_if_charging">Alleen uploaden tijdens opladen</string>
<string name="worker_state">Werkstatus: %s</string>
<string name="uploaded_data">Geüploade gegevens</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">De volgende gegevens worden geüpload naar je Open Humans account: glucosewaarden, bolussen, koolhydraten, careportal-events (met uitzondering van notities), verlengde bolussen, profielwissels, totale dagelijkse doses, tijdelijke basaalstanden, tijdelijke doelen, voorkeuren, app-versie, apparaatmodel en schermafmetingen. Geheime of persoonlijke gegevens zoals je Nightscout-URL of API-secret worden niet geüpload.</string>
<string name="setupwizard_pump_riley_link_status">RileyLink Status:</string> <string name="setupwizard_pump_riley_link_status">RileyLink Status:</string>
<string name="filter">Filter</string> <string name="filter">Filter</string>
<string name="copytolocalprofile_invalid">Lokaal profiel kan niet worden gemaakt. Profiel is ongeldig.</string> <string name="copytolocalprofile_invalid">Lokaal profiel kan niet worden gemaakt. Profiel is ongeldig.</string>

View file

@ -132,7 +132,7 @@
<string name="wronginsulin_label">Feil i insulin levering/registrering</string> <string name="wronginsulin_label">Feil i insulin levering/registrering</string>
<string name="wronginsulin_whattodo">Hva ska du gjøre hvis du har fått mindre insulin enn hva pumpens historikk viser, f.eks. på grunn av okklusjon, feil med kanyle eller om du har glemt å koble på pumpen etter en dusj</string> <string name="wronginsulin_whattodo">Hva ska du gjøre hvis du har fått mindre insulin enn hva pumpens historikk viser, f.eks. på grunn av okklusjon, feil med kanyle eller om du har glemt å koble på pumpen etter en dusj</string>
<string name="wronginsulin_careportal">Fjern insulindata fra Nightscout slik at det slettes fra pumpens historikk.</string> <string name="wronginsulin_careportal">Fjern insulindata fra Nightscout slik at det slettes fra pumpens historikk.</string>
<string name="wronginsulin_compare">Sammenligne verdier i AndroidAPS og pumpehistorikk.</string> <string name="wronginsulin_compare">Sammenlign verdiene i AndroidAPS og pumpehistorikken (hvis pumpen støtter dette).</string>
<string name="wronginsulin_prime">Gi en bolus med en del av det insulinet du mangler enten med penn eller ved å bruke prime funksjonen.</string> <string name="wronginsulin_prime">Gi en bolus med en del av det insulinet du mangler enten med penn eller ved å bruke prime funksjonen.</string>
<string name="wronginsulin_donothing">Ikke gjør noe og la AndroidAPS korrigere eventuelle høye blodsukkerverdier.</string> <string name="wronginsulin_donothing">Ikke gjør noe og la AndroidAPS korrigere eventuelle høye blodsukkerverdier.</string>
<string name="iob_label">Aktivt insulin (IOB)</string> <string name="iob_label">Aktivt insulin (IOB)</string>

View file

@ -832,36 +832,6 @@
<string name="formatwithweight">Alder: %1$.0f Vekt: %2$.0f kg</string> <string name="formatwithweight">Alder: %1$.0f Vekt: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% av basal</string> <string name="basalpctfromtdd_label">% av basal</string>
<string name="dpvdefaultprofile">DPV standardprofil</string> <string name="dpvdefaultprofile">DPV standardprofil</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Avslutter oppsett av Open Humans…</string>
<string name="this_may_take_a_while">Dette kan ta litt tid. Ikke slå av telefonen eller avbryt prosessen.</string>
<string name="setup_finished">Oppsett ferdig</string>
<string name="your_phone_will_upload_data">Telefonen vil laste opp data til Open Humans snart.</string>
<string name="your_phone_is_upload_data">Telefonen laster opp data til Open Humans nå.</string>
<string name="setup_failed">Installasjonen mislyktes</string>
<string name="there_was_an_error">Det oppstod en feil. Prøv å logge inn igjen for å fortsette. Beklager &amp; Takk!</string>
<string name="open_humans_terms">Dette er et verktøy med åpen kildekode som vil kopiere data til Open Humans. Vi har ingen rettigheter til å dele dine data med tredjeparter uten din eksplisitte godkjenning. Alle data som app og prosjektet mottar vil ha en vilkårlig ID som bare vil bli oversendt Open Humans kontoen med din godkjennelse. Du kan avslutte opplasting og slette opplastede data når som helst via www.openhumans.org.</string>
<string name="i_understand_and_agree">Jeg forstår og godkjenner.</string>
<string name="login">Innlogging</string>
<string name="logout">Utlogging</string>
<string name="oh_logout_confirmation">Vil du virkelig logge ut og slutte å donere dine data til vitenskapen?</string>
<string name="project_member_id">Prosjektmedlems ID: %s</string>
<string name="queue_size">Kø størrelse: %d</string>
<string name="terms_of_use">Vilkår for bruk</string>
<string name="not_logged_in">Ikke logget inn</string>
<string name="you_need_to_accept_the_of_use_first">Du må først godta vilkårene for bruk.</string>
<string name="successfully_logged_in">Innlogging vellykket</string>
<string name="setup_will_continue_in_background">Oppsettet vil bli fullført i bakgrunnen nå. Takk for at du laster opp dine data.\n\nSørg for at AndroidAPS og telefonen er slått på i en kort periode for å fullføre oppsettet.</string>
<string name="completing_login">Fullfører innlogging…</string>
<string name="donate_your_data_to_science">Doner dine data til vitenskapen</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Du har blitt logget ut fra Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Klikk her for å logge inn igjen hvis dette ikke var hensikten.</string>
<string name="only_upload_if_connected_to_wifi">Last opp kun dersom du er koblet til WiFi</string>
<string name="only_upload_if_charging">Last opp kun ved mobillading</string>
<string name="worker_state">Fremdrift: %s</string>
<string name="uploaded_data">Opplastede data</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">Følgende data vil bli lastet opp til din Open Humans konto: glukoseverdier, boluser, karbohydrater, careportalhendelser (bortsett fra merknader), forlengede boluser, profilbytter, totale daglige doser, temp basaler, endringer i BS mål, innstillinger, app versjon, mobilmerke og skjermstørrelser. Hemmelig eller privat informasjon som din Nightscout URL eller API secret vil ikke bli lastet opp.</string>
<string name="setupwizard_pump_riley_link_status">RileyLink status:</string> <string name="setupwizard_pump_riley_link_status">RileyLink status:</string>
<string name="filter">Filter</string> <string name="filter">Filter</string>
<string name="copytolocalprofile_invalid">Klarte ikke å opprette lokal profil. Profilen er ikke gyldig.</string> <string name="copytolocalprofile_invalid">Klarte ikke å opprette lokal profil. Profilen er ikke gyldig.</string>
@ -921,4 +891,5 @@
<string name="ns_receive_cgm_summary">Aksepter CGM data fra NS</string> <string name="ns_receive_cgm_summary">Aksepter CGM data fra NS</string>
<string name="sms_timeout_while_wating">Tidsavbrudd fordi vi ventet på avslutning av forrige pumpekommunikasjon</string> <string name="sms_timeout_while_wating">Tidsavbrudd fordi vi ventet på avslutning av forrige pumpekommunikasjon</string>
<string name="smscommunicator_another_bolus_in_queue">Det ligger en annen bolus i køen. Prøv igjen senere.</string> <string name="smscommunicator_another_bolus_in_queue">Det ligger en annen bolus i køen. Prøv igjen senere.</string>
<string name="calculation_in_progress">Beregning pågår</string>
</resources> </resources>

View file

@ -129,7 +129,6 @@
<string name="wronginsulin_label">Błędy w dostarczaniu/wpisywaniu insuliny</string> <string name="wronginsulin_label">Błędy w dostarczaniu/wpisywaniu insuliny</string>
<string name="wronginsulin_whattodo">Co należy zrobić, jeśli otrzymano mniej insuliny niż sugeruje historia pompy, np. z powodu niedrożności, uszkodzonej kaniuli lub zapomnienia o ponownym podłączeniu pompy po prysznicu? </string> <string name="wronginsulin_whattodo">Co należy zrobić, jeśli otrzymano mniej insuliny niż sugeruje historia pompy, np. z powodu niedrożności, uszkodzonej kaniuli lub zapomnienia o ponownym podłączeniu pompy po prysznicu? </string>
<string name="wronginsulin_careportal">Usuń dane insuliny z portalu Nightscout aby usunąć je z historii pompy.</string> <string name="wronginsulin_careportal">Usuń dane insuliny z portalu Nightscout aby usunąć je z historii pompy.</string>
<string name="wronginsulin_compare">Porównaj wartości w AndroidAPS i historii pompy.</string>
<string name="wronginsulin_prime">Podaj obliczoną dawkę „pominiętej” insuliny za pomocą strzykawki / wstrzykiwacza lub za pomocą pompy funkcji wypełnienia.</string> <string name="wronginsulin_prime">Podaj obliczoną dawkę „pominiętej” insuliny za pomocą strzykawki / wstrzykiwacza lub za pomocą pompy funkcji wypełnienia.</string>
<string name="wronginsulin_donothing">Nie rób nic i pozwól AndroidAPS na skorygowanie każdego uzyskanego wysokiego stężenia glukozy we krwi.</string> <string name="wronginsulin_donothing">Nie rób nic i pozwól AndroidAPS na skorygowanie każdego uzyskanego wysokiego stężenia glukozy we krwi.</string>
<string name="iob_label">Aktywna insulina (IOB)</string> <string name="iob_label">Aktywna insulina (IOB)</string>

View file

@ -825,36 +825,6 @@
<string name="formatwithweight">Wiek: %1$.0f Waga: %2$.0f kg</string> <string name="formatwithweight">Wiek: %1$.0f Waga: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% bazy</string> <string name="basalpctfromtdd_label">% bazy</string>
<string name="dpvdefaultprofile">Domyślny profil DPV</string> <string name="dpvdefaultprofile">Domyślny profil DPV</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Kończenie konfiguracji Open Humans…</string>
<string name="this_may_take_a_while">To może chwilę potrwać. Nie wyłączaj telefonu ani tej wtyczki.</string>
<string name="setup_finished">Konfiguracja zakończona</string>
<string name="your_phone_will_upload_data">Twój telefon wkrótce prześle dane do Open Humans.</string>
<string name="your_phone_is_upload_data">Twój telefon przesyła teraz dane do Open Humans.</string>
<string name="setup_failed">Konfiguracja nie powiodła się</string>
<string name="there_was_an_error">Wystąpił błąd. Spróbuj zalogować się ponownie, aby kontynuować. Przepraszamy &amp; dziękujemy!</string>
<string name="open_humans_terms">To jest narzędzie open source, które skopiuje Twoje dane do projektu Open Humans. Nie zachowujemy żadnych praw do dzielenia się Twoimi danymi z osobami trzecimi bez Twojej wyraźnej zgody. Dane, które otrzymują projekt i aplikacja są identyfikowane za pomocą losowego identyfikatora użytkownika i będą bezpiecznie przesyłane na konto Open Humans za Twoją zgodą dla tego procesu. Możesz zatrzymać przesyłanie i usunąć swoje już przesłane dane w dowolnym momencie za pośrednictwem strony www.openhumans.org.</string>
<string name="i_understand_and_agree">Rozumiem i zgadzam się.</string>
<string name="login">Zaloguj się</string>
<string name="logout">Wyloguj się</string>
<string name="oh_logout_confirmation">Czy na pewno chcesz się wylogować i zaprzestać przekazywania danych na rzecz nauki?</string>
<string name="project_member_id">Identyfikator członka projektu: %s</string>
<string name="queue_size">Rozmiar kolejki: %d</string>
<string name="terms_of_use">Warunki użytkowania</string>
<string name="not_logged_in">Nie zalogowano</string>
<string name="you_need_to_accept_the_of_use_first">Najpierw musisz zaakceptować warunki użytkowania.</string>
<string name="successfully_logged_in">Pomyślnie zalogowano</string>
<string name="setup_will_continue_in_background">Konfiguracja zostanie teraz zakończona w tle. Dziękujemy za przesłanie swoich danych.\n\nProszę nie wyłączaj telefonu ani tej wtyczki jeszcze przez chwilę, aby umożliwić dokończenie się konfiguracji.</string>
<string name="completing_login">Kończenie logowania…</string>
<string name="donate_your_data_to_science">Przekaż swoje dane na rzecz nauki</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Zostałeś wylogowany z Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Kliknij tutaj, aby zalogować się ponownie, jeśli wylogowanie nie było celowe.</string>
<string name="only_upload_if_connected_to_wifi">Prześlij tylko jeśli połączono poprzez WiFi</string>
<string name="only_upload_if_charging">Prześlij tylko gdy telefon jest ładowany</string>
<string name="worker_state">Stan procesu: %s</string>
<string name="uploaded_data">Przesłane dane</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">Następujące dane zostaną przesłane na konto Open Humans: wartości Glikemii, bolusy, węglowodany, zdarzenia z portalu opieki (z wyjątkiem notatek), rozszerzone bolusy, przełączenia profilu, całkowite dawki dobowe, bazy tymczasowe, cele tymczasowe, preferencje, wersja aplikacji, model urządzenia i wymiary ekranu. Dane niejawne lub prywatne, takie jak adres URL strony Nightscout lub klucz autoryzacji API, nie zostaną przesłane.</string>
<string name="setupwizard_pump_riley_link_status">Stan RileyLink:</string> <string name="setupwizard_pump_riley_link_status">Stan RileyLink:</string>
<string name="filter">Filtr</string> <string name="filter">Filtr</string>
<string name="copytolocalprofile_invalid">Nie można utworzyć profilu lokalnego. Profil jest niepoprawny.</string> <string name="copytolocalprofile_invalid">Nie można utworzyć profilu lokalnego. Profil jest niepoprawny.</string>

View file

@ -132,7 +132,6 @@
<string name="wronginsulin_label">Erros de entrada/administração de insulina</string> <string name="wronginsulin_label">Erros de entrada/administração de insulina</string>
<string name="wronginsulin_whattodo">O que deve fazer se receber menos insulina do que o histórico da bomba sugere por exemplo devido a uma oclusão, uma cânula danificada ou esquecer-se de reanexar a bomba após um banho? </string> <string name="wronginsulin_whattodo">O que deve fazer se receber menos insulina do que o histórico da bomba sugere por exemplo devido a uma oclusão, uma cânula danificada ou esquecer-se de reanexar a bomba após um banho? </string>
<string name="wronginsulin_careportal">Elimine dados de insulina do Nightscout Careportal para removê-lo do histórico da bomba.</string> <string name="wronginsulin_careportal">Elimine dados de insulina do Nightscout Careportal para removê-lo do histórico da bomba.</string>
<string name="wronginsulin_compare">Compare valores no AndroidAPS e no histórico da bomba.</string>
<string name="wronginsulin_prime">Bólus uma proporção de insulina calculada \'não administrada\' ou com seringa/caneta ou purgando.</string> <string name="wronginsulin_prime">Bólus uma proporção de insulina calculada \'não administrada\' ou com seringa/caneta ou purgando.</string>
<string name="wronginsulin_donothing">Faça nada e permita que o AndroidAPS corrija qualquer nível de glicose elevado que daí resulte.</string> <string name="wronginsulin_donothing">Faça nada e permita que o AndroidAPS corrija qualquer nível de glicose elevado que daí resulte.</string>
<string name="iob_label">Insulina ativa (IA )</string> <string name="iob_label">Insulina ativa (IA )</string>

View file

@ -831,36 +831,6 @@
<string name="formatwithweight">Idade: %1$.0f Peso: %2$.0f kg</string> <string name="formatwithweight">Idade: %1$.0f Peso: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% de basal</string> <string name="basalpctfromtdd_label">% de basal</string>
<string name="dpvdefaultprofile">Perfil Padrão DPV</string> <string name="dpvdefaultprofile">Perfil Padrão DPV</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">A terminar configuração Open Humans...</string>
<string name="this_may_take_a_while">Pode demorar um pouco. Não desligue o telefone ou este plugin.</string>
<string name="setup_finished">Configuração terminada</string>
<string name="your_phone_will_upload_data">Seu telefone fará o envio de dados para Open Humans em breve.</string>
<string name="your_phone_is_upload_data">Seu telefone está enviar dados para Open Humans agora.</string>
<string name="setup_failed">Falha na configuração</string>
<string name="there_was_an_error">Houve um erro. Tente efetuar o login novamente a fim de prosseguir. Desculpe &amp; Obrigado!</string>
<string name="open_humans_terms">Esta é uma ferramenta de código aberto que vai copiar seus dados para Open Humans. Nós não retemos direitos de compartilhar seus dados com terceiros sem a sua autorização explícita. Os dados que o projecto e a app recebem são identificados através de um ID de usuário aleatório e só serão transmitidos de forma segura para uma conta Open Humans com a sua autorização desse processo. Pode parar de fazer o envio e excluir seus dados enviados a qualquer momento via www.openhumans.org.</string>
<string name="i_understand_and_agree">Compreendo e concordo.</string>
<string name="login">Login</string>
<string name="logout">Terminar Sessão</string>
<string name="oh_logout_confirmation">Deseja realmente encerrar sessão e parar de doar dados para a ciência?</string>
<string name="project_member_id">ID Membro do Projecto: %s</string>
<string name="queue_size">Tamanho da Fila: %d</string>
<string name="terms_of_use">Termos de Utilização</string>
<string name="not_logged_in">Não tem sessão iniciada</string>
<string name="you_need_to_accept_the_of_use_first">Tem de aceitar os Termos de Utilização.</string>
<string name="successfully_logged_in">Login bem sucedido</string>
<string name="setup_will_continue_in_background">A configuração será concluída em segundo plano agora. Obrigado por fazer o envio dos seus dados.\n\nPor favor, mantenha este plugin e o telefone ligado por um curto tempo para que a configuração seja concluída.</string>
<string name="completing_login">A completar o login…</string>
<string name="donate_your_data_to_science">Doar seus dados para a ciência</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Sessão do Open Humans foi encerrada</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Clique aqui para entrar novamente, se não era de propósito.</string>
<string name="only_upload_if_connected_to_wifi">Apenas enviar se ligado ao Wi-Fi</string>
<string name="only_upload_if_charging">Apenas enviar se estiver a carregar</string>
<string name="worker_state">Estado Trabalhador: %s</string>
<string name="uploaded_data">Dados Enviados</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">Os seguintes dados serão enviados para sua conta Open Humans: valores de Glicose, bólus, hidratos, eventos do careportal (excepto notas), bólus estendidos, mudanças de perfil, doses diárias totais, basais temporárias, alvos temp, preferências, versão da aplicação, modelo de dispositivo e dimensões da tela. Informações secretas ou privadas como sua URL de Nightscout ou senha de API não serão enviadas.</string>
<string name="setupwizard_pump_riley_link_status">Estado RileyLink:</string> <string name="setupwizard_pump_riley_link_status">Estado RileyLink:</string>
<string name="filter">Filtro</string> <string name="filter">Filtro</string>
<string name="copytolocalprofile_invalid">Não é possível criar perfil local. Perfil é inválido.</string> <string name="copytolocalprofile_invalid">Não é possível criar perfil local. Perfil é inválido.</string>

View file

@ -132,7 +132,6 @@
<string name="wronginsulin_label">Erori de livrare/introducere insulină</string> <string name="wronginsulin_label">Erori de livrare/introducere insulină</string>
<string name="wronginsulin_whattodo">Ce trebuie să faci dacă ai primit mai putină insulină decât sugerează istoricul pompei, de exemplu datorită unei ocluzii, a unei canule defecte sau pentru ca ai uitat sa reatașezi pompa după un dus? </string> <string name="wronginsulin_whattodo">Ce trebuie să faci dacă ai primit mai putină insulină decât sugerează istoricul pompei, de exemplu datorită unei ocluzii, a unei canule defecte sau pentru ca ai uitat sa reatașezi pompa după un dus? </string>
<string name="wronginsulin_careportal">Șterge datele despre insulină din Nightscout Careportal pentru a le înlătura din istoricul pompei.</string> <string name="wronginsulin_careportal">Șterge datele despre insulină din Nightscout Careportal pentru a le înlătura din istoricul pompei.</string>
<string name="wronginsulin_compare">Compară valorile din AndroidAPS cu cele din istoricul pompei.</string>
<string name="wronginsulin_prime">Bolusati o cantitate parțiala de insulina din insulina calculata ca fiind lipsa utilizând seringa/penul sau amorsarea.</string> <string name="wronginsulin_prime">Bolusati o cantitate parțiala de insulina din insulina calculata ca fiind lipsa utilizând seringa/penul sau amorsarea.</string>
<string name="wronginsulin_donothing">Nu faceți nimic și permiteți AndroidAPS să corecteze valorile mari ale glicemiei.</string> <string name="wronginsulin_donothing">Nu faceți nimic și permiteți AndroidAPS să corecteze valorile mari ale glicemiei.</string>
<string name="iob_label">Insulină activă (IOB)</string> <string name="iob_label">Insulină activă (IOB)</string>

View file

@ -828,36 +828,6 @@
<string name="formatwithweight">Vârstă: %1$.0f Greutate: %2$.0f kg</string> <string name="formatwithweight">Vârstă: %1$.0f Greutate: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% din bazală</string> <string name="basalpctfromtdd_label">% din bazală</string>
<string name="dpvdefaultprofile">Profil implicit DPV</string> <string name="dpvdefaultprofile">Profil implicit DPV</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Finalizare configurare Open Humans…</string>
<string name="this_may_take_a_while">Acest lucru poate dura un timp. Nu opriți telefonul și nici acest plugin.</string>
<string name="setup_finished">Configurare terminată</string>
<string name="your_phone_will_upload_data">Telefonul tău va încărca date către Open Humans în curând.</string>
<string name="your_phone_is_upload_data">Telefonul tău încarcă date în Open Humans acum.</string>
<string name="setup_failed">Configurare eșuată</string>
<string name="there_was_an_error">A apărut o eroare. Te rugăm să încerci să te autentifici din nou pentru a continua. Ne pare rău. Mulțumim!</string>
<string name="open_humans_terms">Aceasta este un instrument open source care va copia datele tale în Open Humans. Nu avem dreptul sa împărtășim datele tale cu terțe părți fără autorizație explicită. Datele pe care le primesc proiectul și aplicația sunt identificate printr-un ID de utilizator aleatoriu și vor fi transmise în siguranță într-un cont Open Humans numai cu autorizarea acestui proces. Poți înceta încărcarea și șterge datele oricând folosind www.openhumans.org.</string>
<string name="i_understand_and_agree">Înţeleg şi sunt de acord.</string>
<string name="login">Autentificare</string>
<string name="logout">Deconectare</string>
<string name="oh_logout_confirmation">Sigur doriți să vă deconectați și să încetați să donați date in scopuri științifice?</string>
<string name="project_member_id">ID Membru proiect: %s</string>
<string name="queue_size">Dimensiunea cozii: %d</string>
<string name="terms_of_use">Condiții de utilizare</string>
<string name="not_logged_in">Nu ești autentificat(ă)</string>
<string name="you_need_to_accept_the_of_use_first">Trebuie mai întâi să acceptați condițiile de utilizare.</string>
<string name="successfully_logged_in">Conectare reușită</string>
<string name="setup_will_continue_in_background">Setarea va fi finalizată în fundal acum. Vă mulțumim pentru încărcarea datelor.\n\nVă rugăm să păstrați acest plugin și telefonul pornit pentru o scurtă perioadă de timp astfel încât setarea să se finalizeze.</string>
<string name="completing_login">Finalizare autentificare…</string>
<string name="donate_your_data_to_science">Donează datele în scopuri științifice</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Ai fost deconectat de la Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Dați click aici pentru a vă conecta din nou, dacă a fost din greșeală.</string>
<string name="only_upload_if_connected_to_wifi">Încarcă numai pe conexiune WiFi</string>
<string name="only_upload_if_charging">Încărca numai dacă telefonul este la încărcat</string>
<string name="worker_state">Stare prelucrare: %s</string>
<string name="uploaded_data">Date încărcate</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">Următoarele date vor fi încărcate în contul Open Humans: glicemii, evenimente careportal (cu excepția notelor), bolusuri extinse, schimbări de profil, doze zilnice totale, bazale temporare, ținte temporare, preferințe, versiunea aplicației, model dispozitiv și dimensiunile ecranului. Informațiile secrete sau private, cum ar fi URL-ul Nightscout sau secretul API, nu vor fi încărcate.</string>
<string name="setupwizard_pump_riley_link_status">Stare RileyLink:</string> <string name="setupwizard_pump_riley_link_status">Stare RileyLink:</string>
<string name="filter">Filtru</string> <string name="filter">Filtru</string>
<string name="copytolocalprofile_invalid">Nu se poate crea profilul local. Profilul este invalid.</string> <string name="copytolocalprofile_invalid">Nu se poate crea profilul local. Profilul este invalid.</string>

View file

@ -134,7 +134,7 @@ Context | Edit Context</string>
<string name="wronginsulin_label">Ошибки подачи/поступления инсулина</string> <string name="wronginsulin_label">Ошибки подачи/поступления инсулина</string>
<string name="wronginsulin_whattodo">Что делать, если вы получили меньше инсулина, чем указано в истории помпы, например, из-за окклюзии, проблем с канюлей или из-за того, что вы забыли подключить помпу обратно после душа?</string> <string name="wronginsulin_whattodo">Что делать, если вы получили меньше инсулина, чем указано в истории помпы, например, из-за окклюзии, проблем с канюлей или из-за того, что вы забыли подключить помпу обратно после душа?</string>
<string name="wronginsulin_careportal">Удалить данные об инсулине в Портале терапии Nightscout, чтобы удалить их из истории помпы.</string> <string name="wronginsulin_careportal">Удалить данные об инсулине в Портале терапии Nightscout, чтобы удалить их из истории помпы.</string>
<string name="wronginsulin_compare">Сравнить значения в AndroidAPS и истории помпы.</string> <string name="wronginsulin_compare">Сравните значения в истории AndroidAPS и помпы (если помпа это поддерживает).</string>
<string name="wronginsulin_prime">Рассчитать и ввести «пропущенный» вами инсулин шприцем/ручкой или через кнопку заполнения канюли.</string> <string name="wronginsulin_prime">Рассчитать и ввести «пропущенный» вами инсулин шприцем/ручкой или через кнопку заполнения канюли.</string>
<string name="wronginsulin_donothing">Ничего не делать и позволить AndroidAPS исправить возможный высокий уровень ГК.</string> <string name="wronginsulin_donothing">Ничего не делать и позволить AndroidAPS исправить возможный высокий уровень ГК.</string>
<string name="iob_label">Активный инсулин (IOB)</string> <string name="iob_label">Активный инсулин (IOB)</string>

View file

@ -834,36 +834,6 @@ Context | Edit Context</string>
<string name="formatwithweight">Возраст: %1$.0f Вес: %2$.0f кг</string> <string name="formatwithweight">Возраст: %1$.0f Вес: %2$.0f кг</string>
<string name="basalpctfromtdd_label">% базального</string> <string name="basalpctfromtdd_label">% базального</string>
<string name="dpvdefaultprofile">Значение для профиля по умолчанию</string> <string name="dpvdefaultprofile">Значение для профиля по умолчанию</string>
<string name="open_humans">Проект Open Humans</string>
<string name="finishing_open_humans_setup">Завершение установки Open Humans…</string>
<string name="this_may_take_a_while">Это может занять некоторое время. Не выключайте телефон или этот плагин.</string>
<string name="setup_finished">Установка завершена</string>
<string name="your_phone_will_upload_data">Ваш телефон скоро загрузит данные на Open Humans.</string>
<string name="your_phone_is_upload_data">Ваш телефон сейчас загружает данные на Open Humans.</string>
<string name="setup_failed">Установка не выполнена</string>
<string name="there_was_an_error">Произошла ошибка. &amp; для продолжения попробуйте заново войти в систему!</string>
<string name="open_humans_terms">Это проект с открытым исходным кодом, который будет копировать ваши данные на Open Humans. Мы не будем обмениваться вашими данными с третьими лицами без вашего явного разрешения. Данные, отправляемые на проект и приложение, идентифицируются с помощью случайного идентификатора и будут безопасно передаваться на учетную запись Open Humans при вашем одобрении этого процесса. Вы можете остановить загрузку и удалить загруженные данные в любое время здесь: www.openhumans.org.</string>
<string name="i_understand_and_agree">Я понимаю и соглашаюсь.</string>
<string name="login">Вход</string>
<string name="logout">Выход</string>
<string name="oh_logout_confirmation">Вы действительно хотите выйти из системы и перестать отправлять данные исследователям?</string>
<string name="project_member_id">Идентификатор участника проекта: %s</string>
<string name="queue_size">Объем данных в очереди на отправку %d</string>
<string name="terms_of_use">Условия пользования</string>
<string name="not_logged_in">Не выполнен вход</string>
<string name="you_need_to_accept_the_of_use_first">Сначала нужно принять условия использования.</string>
<string name="successfully_logged_in">Вход выполнен успешно</string>
<string name="setup_will_continue_in_background">Настройка будет завершена в фоновом режиме. Спасибо, что загрузила ваши данные.\n\nНе выключайте этот плагин и телефон до завершения установки.</string>
<string name="completing_login">Завершение входа в систему…</string>
<string name="donate_your_data_to_science">Передайте свои данные исследователям</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Вы вышли из Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Нажмите здесь, чтобы снова войти в систему, если выход произошел случайно.</string>
<string name="only_upload_if_connected_to_wifi">Загружать только при подключении к WiFi</string>
<string name="only_upload_if_charging">Загружать только при зарядке</string>
<string name="worker_state">Рабочее состояние: %s</string>
<string name="uploaded_data">Загруженные данные</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">На ваш аккаунт Open Humans будут загружены следующие данные: значения ГК, события careportal (за исключением примечаний), пролонгированные болюсы, переключения профиля, суммарные суточные дозы, временные базалы, временные цели, настройки, версии приложения, модель устройства и размеры экрана. Секретная или конфиденциальная информация, такая как адрес вашего сайта Nightscout или API secret, не будет загружена.</string>
<string name="setupwizard_pump_riley_link_status">Статус RileyLink:</string> <string name="setupwizard_pump_riley_link_status">Статус RileyLink:</string>
<string name="filter">Фильтр</string> <string name="filter">Фильтр</string>
<string name="copytolocalprofile_invalid">Не удается создать локальный профиль. Настройки профиля неправильны.</string> <string name="copytolocalprofile_invalid">Не удается создать локальный профиль. Настройки профиля неправильны.</string>
@ -923,4 +893,5 @@ Context | Edit Context</string>
<string name="ns_receive_cgm_summary">Принимать данные мониторинга CGM из NS</string> <string name="ns_receive_cgm_summary">Принимать данные мониторинга CGM из NS</string>
<string name="sms_timeout_while_wating">Таймаут во время ожидания окончания предыдущего соединения с помпой</string> <string name="sms_timeout_while_wating">Таймаут во время ожидания окончания предыдущего соединения с помпой</string>
<string name="smscommunicator_another_bolus_in_queue">В очереди есть еще один болюс. Повторите попытку позже.</string> <string name="smscommunicator_another_bolus_in_queue">В очереди есть еще один болюс. Повторите попытку позже.</string>
<string name="calculation_in_progress">Идет подсчет</string>
</resources> </resources>

View file

@ -132,7 +132,7 @@
<string name="wronginsulin_label">Chyby pri podávaní inzulínu</string> <string name="wronginsulin_label">Chyby pri podávaní inzulínu</string>
<string name="wronginsulin_whattodo">Čo by ste mali urobiť, pokiaľ ste dostali menej inzulínu, než ukazuje história pumpy, napr. v dôsledku oklúzie, vadnej kanyly, alebo zabudnutia na opätovné pripojenie pumpy po sprche?</string> <string name="wronginsulin_whattodo">Čo by ste mali urobiť, pokiaľ ste dostali menej inzulínu, než ukazuje história pumpy, napr. v dôsledku oklúzie, vadnej kanyly, alebo zabudnutia na opätovné pripojenie pumpy po sprche?</string>
<string name="wronginsulin_careportal">Odstráňte dáta z Nightscoutu pre odstránenie z histórie pumpy.</string> <string name="wronginsulin_careportal">Odstráňte dáta z Nightscoutu pre odstránenie z histórie pumpy.</string>
<string name="wronginsulin_compare">Porovnajte hodnoty v AndroidAPS a histórii pumpy.</string> <string name="wronginsulin_compare">Porovnaj hodnoty v AndroidAPS z históriou v tvojej pumpe (ak pumpa má túto funkciu).</string>
<string name="wronginsulin_prime">Pošlite bolus na vypočítaný „chýbajúci“ inzulín buď injekčnou striekačkou, alebo perom, alebo pomocou plnenia na pumpe.</string> <string name="wronginsulin_prime">Pošlite bolus na vypočítaný „chýbajúci“ inzulín buď injekčnou striekačkou, alebo perom, alebo pomocou plnenia na pumpe.</string>
<string name="wronginsulin_donothing">Nerobte nič a dovoľte AndroidAPS upraviť akúkoľvek výslednú vysokú hladinu glukózy v krvi.</string> <string name="wronginsulin_donothing">Nerobte nič a dovoľte AndroidAPS upraviť akúkoľvek výslednú vysokú hladinu glukózy v krvi.</string>
<string name="iob_label">Aktívny inzulín (IOB)</string> <string name="iob_label">Aktívny inzulín (IOB)</string>

View file

@ -832,36 +832,6 @@
<string name="formatwithweight">Vek: %1$.0f Hmotnosť: %2$.0f kg</string> <string name="formatwithweight">Vek: %1$.0f Hmotnosť: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% bazálu</string> <string name="basalpctfromtdd_label">% bazálu</string>
<string name="dpvdefaultprofile">Predvolený DPV profil</string> <string name="dpvdefaultprofile">Predvolený DPV profil</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Dokončovanie nastavenia Open Humans...</string>
<string name="this_may_take_a_while">Môže to chvíľu trvať. Nevypínajte Váš telefón ani tento modul.</string>
<string name="setup_finished">Nastavenie dokončené</string>
<string name="your_phone_will_upload_data">Váš telefón čoskoro nahrá dáta na Open Humans.</string>
<string name="your_phone_is_upload_data">Váš telefón práve nahráva dáta na Open Humans.</string>
<string name="setup_failed">Nastavenie zlyhalo</string>
<string name="there_was_an_error">Vyskytla sa chyba. Prosím, skúste sa znova prihlásiť, aby ste mohli pokračovať. Prepáčte &amp; Ďakujem!</string>
<string name="open_humans_terms">Jedná sa o open source nástroj, ktorý skopíruje vaše dáta do Open Humans. Zachovávame práva na zdieľanie vašich údajov s tretími stranami bez vašeho výslovného povolenia. Dáta, ktoré projekt a aplikácia obdržia, sú identifikované pomocou náhodného ID užívateľa a budú bezpečne prenášané iba na účet Open Humans a len s vaším povolením. Môžete kedykoľvek zastaviť odosielanie a zmazať Vaše dáta prostredníctvom adresy www.openhumans.org.</string>
<string name="i_understand_and_agree">Rozumiem a potvrdzujem.</string>
<string name="login">Prihlásenie</string>
<string name="logout">Odhlásiť</string>
<string name="oh_logout_confirmation">Naozaj sa chceš odhlásiť a prestať tak prispievať údajmi vede?</string>
<string name="project_member_id">ID člena projektu: %s</string>
<string name="queue_size">Veľkosť fronty: %d</string>
<string name="terms_of_use">Podmienky používania</string>
<string name="not_logged_in">Neprihlásený</string>
<string name="you_need_to_accept_the_of_use_first">Musíte najskôr akceptovať podmienky používania.</string>
<string name="successfully_logged_in">Prihlásenie úspešné</string>
<string name="setup_will_continue_in_background">Nastavenie bude teraz dokončené na pozadí. Vďaka za odoslanie vašich údajov.\n\nProsím, ponechajte tento modul a Váš telefón na chvíľu zapnutý, kým sa dokončí nastavenie.</string>
<string name="completing_login">Dokončuje sa prihlasovanie…</string>
<string name="donate_your_data_to_science">Darujte svoje údaje vede</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Boli ste odhlásený z Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Kliknite sem, ak sa chcete prihlásiť znova, v prípade, že sa to stalo nedopatrením.</string>
<string name="only_upload_if_connected_to_wifi">Odoslať iba ak ste pripojený k Wi-Fi</string>
<string name="only_upload_if_charging">Odoslať iba pri nabíjaní</string>
<string name="worker_state">Stav procesu: %s</string>
<string name="uploaded_data">Odoslané údaje</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">Následujúce dáta budú nahraté do vašeho účtu Open Humans: hodnoty glykémie, bolusy, sacharidy, udalosti starostlivosti (okrem poznámok), rozložené bolusy, prepnutia profilov, celkové denné dávky, dočasné bazály, nastavenia, verzia aplikácie, model zariadenia a rozmery obrazovky. Tajné, alebo súkromné informácie, ako je URL, alebo API heslo vašeho Nightscoutu, nahraté nebudú.</string>
<string name="setupwizard_pump_riley_link_status">Stav RileyLinku:</string> <string name="setupwizard_pump_riley_link_status">Stav RileyLinku:</string>
<string name="filter">Filter</string> <string name="filter">Filter</string>
<string name="copytolocalprofile_invalid">Nie je možné vytvoriť lokálny profil. Profil je neplatný.</string> <string name="copytolocalprofile_invalid">Nie je možné vytvoriť lokálny profil. Profil je neplatný.</string>
@ -921,4 +891,5 @@
<string name="ns_receive_cgm_summary">Prijať CGM dáta z NS</string> <string name="ns_receive_cgm_summary">Prijať CGM dáta z NS</string>
<string name="sms_timeout_while_wating">Vypršal časový limit pri čakaní na dokončenie predchádzajúcej komunikácie s pumpou</string> <string name="sms_timeout_while_wating">Vypršal časový limit pri čakaní na dokončenie predchádzajúcej komunikácie s pumpou</string>
<string name="smscommunicator_another_bolus_in_queue">Vo fronte je ďalší bolus. Skúste to znovu neskôr.</string> <string name="smscommunicator_another_bolus_in_queue">Vo fronte je ďalší bolus. Skúste to znovu neskôr.</string>
<string name="calculation_in_progress">Prebieha výpočet</string>
</resources> </resources>

View file

@ -132,7 +132,6 @@
<string name="wronginsulin_label">Fel i bolusinmatning</string> <string name="wronginsulin_label">Fel i bolusinmatning</string>
<string name="wronginsulin_whattodo">Vad ska du göra om du fått mindre insulin än vad pumpens historik visar, t.ex. på grund av en ocklusion, en felaktig kanyl eller om du glömt att sätta fast pumpen efter en dusch? </string> <string name="wronginsulin_whattodo">Vad ska du göra om du fått mindre insulin än vad pumpens historik visar, t.ex. på grund av en ocklusion, en felaktig kanyl eller om du glömt att sätta fast pumpen efter en dusch? </string>
<string name="wronginsulin_careportal">Ta bort insulindata från Nightscout för att ta bort den från pumpens historik.</string> <string name="wronginsulin_careportal">Ta bort insulindata från Nightscout för att ta bort den från pumpens historik.</string>
<string name="wronginsulin_compare">Jämför värden i AndroidAPS och pumphistoriken.</string>
<string name="wronginsulin_prime">Ge en bolus med en del av det insulin du saknar antingen med penna eller genom att använda förfyllningsfunktionen.</string> <string name="wronginsulin_prime">Ge en bolus med en del av det insulin du saknar antingen med penna eller genom att använda förfyllningsfunktionen.</string>
<string name="wronginsulin_donothing">Gör ingenting och låt AndroidAPS korrigera eventuella höga blodglukosnivåer.</string> <string name="wronginsulin_donothing">Gör ingenting och låt AndroidAPS korrigera eventuella höga blodglukosnivåer.</string>
<string name="iob_label">Aktivt Insulin (IOB)</string> <string name="iob_label">Aktivt Insulin (IOB)</string>

View file

@ -777,6 +777,7 @@ Eversense-appen.</string>
<string name="randombg_short">BG</string> <string name="randombg_short">BG</string>
<string name="tools">Verktyg</string> <string name="tools">Verktyg</string>
<string name="show_calculation">Visa beräkning</string> <string name="show_calculation">Visa beräkning</string>
<string name="show_removed">Visa borttagna</string>
<string name="clearqueueconfirm">Allt data som inte synkats kommer att kastas bort. Är du säker på att du vill tömma kön?</string> <string name="clearqueueconfirm">Allt data som inte synkats kommer att kastas bort. Är du säker på att du vill tömma kön?</string>
<string name="ebstopsloop">OBS! Om du använder förlängd bolus, kommer du inte längre vara i Closed Loop under den tiden som den förlängda bolusen är igång. Vill du fortsätta?</string> <string name="ebstopsloop">OBS! Om du använder förlängd bolus, kommer du inte längre vara i Closed Loop under den tiden som den förlängda bolusen är igång. Vill du fortsätta?</string>
<string name="closed_loop_disabled_with_eb">Closed Loop-läget inaktiverat pga att en förlängd bolus är aktiv</string> <string name="closed_loop_disabled_with_eb">Closed Loop-läget inaktiverat pga att en förlängd bolus är aktiv</string>
@ -832,36 +833,6 @@ Eversense-appen.</string>
<string name="formatwithweight">Ålder: %1$.0f Vikt: %2$.0f kg</string> <string name="formatwithweight">Ålder: %1$.0f Vikt: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% av basal</string> <string name="basalpctfromtdd_label">% av basal</string>
<string name="dpvdefaultprofile">DPV-standardprofil</string> <string name="dpvdefaultprofile">DPV-standardprofil</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Slutför Open Humans-konfiguration…</string>
<string name="this_may_take_a_while">Det här kan ta ett tag. Avbryt inte den här processen.</string>
<string name="setup_finished">Konfigurationen slutförd</string>
<string name="your_phone_will_upload_data">Din telefon kommer att ladda upp data till Open Humans snart.</string>
<string name="your_phone_is_upload_data">Din telefon laddar upp data till Open Humans nu.</string>
<string name="setup_failed">Konfiguration misslyckades</string>
<string name="there_was_an_error">Ett fel uppstod. Försök att logga in igen för att fortsätta. Tack!</string>
<string name="open_humans_terms">Detta är ett open source-verktyg som kommer att ladda upp dina data till Open Humans. Vi förbehåller oss inga rättigheter att dela dina uppgifter med tredje part utan ditt uttryckliga tillstånd. De data som projektet och appen tar emot identifieras via ett slumpmässigt användar-ID och kommer endast att överföras på ett säkert sätt till ett Open Humans-konto om du tillåter det. Du kan när som helst sluta ladda upp och radera dina uppladdningsdata via www.openhumans.org.</string>
<string name="i_understand_and_agree">Jag förstår och instämmer.</string>
<string name="login">Logga in</string>
<string name="logout">Logga ut</string>
<string name="oh_logout_confirmation">Vill du verkligen logga ut och sluta donera data till vetenskapen?</string>
<string name="project_member_id">Projektmedlems-ID: %s</string>
<string name="queue_size">Köstorlek: %d</string>
<string name="terms_of_use">Användarvillkor</string>
<string name="not_logged_in">Inte inloggad</string>
<string name="you_need_to_accept_the_of_use_first">Du måste acceptera användarvillkoren först.</string>
<string name="successfully_logged_in">Inloggning lyckades</string>
<string name="setup_will_continue_in_background">Konfigurationen kommer att slutföras i bakgrunden nu. Tack för att du laddade upp dina data.\n\nBehåll det här appen och din telefon påslagen en stund till för installationen ska slutföras helt.</string>
<string name="completing_login">Slutför inloggning…</string>
<string name="donate_your_data_to_science">Donera dina data till vetenskapen</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Du har loggats ut från Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Klicka här om du vill logga in igen.</string>
<string name="only_upload_if_connected_to_wifi">Ladda bara upp om ansluten till WiFi</string>
<string name="only_upload_if_charging">Ladda bara upp vid laddning</string>
<string name="worker_state">Jobbstatus: %s</string>
<string name="uploaded_data">Uppladdad data</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">Följande data kommer att överföras till ditt Open Humans-konto: Glukosvärden, careportalhändelser (utom anteckningar), utökade bolusar, profilbyten, totala dagliga doser, temp basaler, temp mål, inställningar, appversion, enhetsmodell och skärmstorlek. Hemlig eller privat information, t. ex. din Nightscout-adress eller API-hemlighet, kommer inte att överföras.</string>
<string name="setupwizard_pump_riley_link_status">Riley Link-status:</string> <string name="setupwizard_pump_riley_link_status">Riley Link-status:</string>
<string name="filter">Filter</string> <string name="filter">Filter</string>
<string name="copytolocalprofile_invalid">Kan inte att skapa den lokala profilen. Profilen är ogiltig.</string> <string name="copytolocalprofile_invalid">Kan inte att skapa den lokala profilen. Profilen är ogiltig.</string>
@ -898,4 +869,28 @@ Eversense-appen.</string>
<string name="profile_max_daily_basal_value">Maximal basaldos för profil</string> <string name="profile_max_daily_basal_value">Maximal basaldos för profil</string>
<string name="current_basal_value">Nuvarande basaldos</string> <string name="current_basal_value">Nuvarande basaldos</string>
<string name="profile_carbs_ratio_value">Profilens KH-kvot</string> <string name="profile_carbs_ratio_value">Profilens KH-kvot</string>
<string name="full_sync">Full synkronisering</string>
<string name="prime">Förfyllning</string>
<string name="ns_sync_options">Synkronisering</string>
<string name="ns_upload_summary">Profiler, bolus, kolhydrater och temp basaler laddas upp till NS</string>
<string name="ns_upload">Ladda upp data till NS</string>
<string name="ns_receive_profile_store">Ladda ner profiler</string>
<string name="ns_receive_profile_store_summary">Skapa/synka lokala profiler från NS</string>
<string name="ns_receive_temp_target">Ladda ner temporära mål</string>
<string name="ns_receive_temp_target_summary">Godkänn temp mål som anges genom NS eller NSClient</string>
<string name="ns_receive_profile_switch">Ladda ner profilbyten</string>
<string name="ns_receive_profile_switch_summary">Acceptera profilbyten som matats in via NS eller NSClient</string>
<string name="ns_receive_offline_event">Ladda ner APS offline händelser</string>
<string name="ns_receive_offline_event_summary">Acceptera APS Offline-händelser som matas in via NS eller NSClient</string>
<string name="ns_receive_insulin">Ladda ner loggade insulindoser</string>
<string name="ns_receive_insulin_summary">Acceptera loggat insulin som matats in via NS eller NSClient (den levereras inte, endast beräknad mot IOB)</string>
<string name="ns_receive_carbs">Ladda ner loggade kolhydrater</string>
<string name="ns_receive_carbs_summary">Acceptera kolhydrater som matats in via NS eller NSClient</string>
<string name="ns_receive_therapy_events">Ladda ner loggade behandlingar</string>
<string name="ns_receive_therapy_events_summary">Acceptera händelser (kanyl-, insulin-, batteribyte etc) som angetts via NS eller NSClient</string>
<string name="ns_receive_cgm">Ladda ner CGM-data</string>
<string name="ns_receive_cgm_summary">Acceptera CGM-data från NS</string>
<string name="sms_timeout_while_wating">Föregående pumpkommunikation har inte bekräftats/avslutats i tid</string>
<string name="smscommunicator_another_bolus_in_queue">Det finns en annan bolus i kö. Försök igen senare.</string>
<string name="calculation_in_progress">Beräkning pågår</string>
</resources> </resources>

View file

@ -132,7 +132,7 @@
<string name="wronginsulin_label">Insulin delivery/entry errors</string> <string name="wronginsulin_label">Insulin delivery/entry errors</string>
<string name="wronginsulin_whattodo">What should you do if you received less insulin than the pump history suggests e.g. due to an occlusion, a failed cannula or forgetting to reattach the pump after a shower? </string> <string name="wronginsulin_whattodo">What should you do if you received less insulin than the pump history suggests e.g. due to an occlusion, a failed cannula or forgetting to reattach the pump after a shower? </string>
<string name="wronginsulin_careportal">Delete insulin data from Nightscout Careportal to remove it from the pump history.</string> <string name="wronginsulin_careportal">Delete insulin data from Nightscout Careportal to remove it from the pump history.</string>
<string name="wronginsulin_compare">Compare values in AndroidAPS and pump history.</string> <string name="wronginsulin_compare">Compare values in AndroidAPS and pump history (if pump supports this).</string>
<string name="wronginsulin_prime">Bolus a proportion of your calculated missed insulin by either syringe/pen or using a prime.</string> <string name="wronginsulin_prime">Bolus a proportion of your calculated missed insulin by either syringe/pen or using a prime.</string>
<string name="wronginsulin_donothing">Do nothing and allow AndroidAPS to correct any resulting high blood glucose level.</string> <string name="wronginsulin_donothing">Do nothing and allow AndroidAPS to correct any resulting high blood glucose level.</string>
<string name="iob_label">Insulin on Board (IOB)</string> <string name="iob_label">Insulin on Board (IOB)</string>

View file

@ -29,7 +29,6 @@
<string name="key_email_for_crash_report" translatable="false">email_for_crash_report</string> <string name="key_email_for_crash_report" translatable="false">email_for_crash_report</string>
<string name="key_smscommunicator_settings" translatable="false">smscommunicator</string> <string name="key_smscommunicator_settings" translatable="false">smscommunicator</string>
<string name="key_open_humans_settings" translatable="false">open_humans</string>
<string name="key_protection_settings" translatable="false">protection</string> <string name="key_protection_settings" translatable="false">protection</string>
<string name="key_absorption_category_settings" translatable="false">absorption_category_settings</string> <string name="key_absorption_category_settings" translatable="false">absorption_category_settings</string>
<string name="key_insulin_oref_peak_settings" translatable="false">insulin_oref_peak_settings</string> <string name="key_insulin_oref_peak_settings" translatable="false">insulin_oref_peak_settings</string>
@ -251,8 +250,6 @@
<string name="smscommunicator_loophasbeendisabled">Loop has been disabled</string> <string name="smscommunicator_loophasbeendisabled">Loop has been disabled</string>
<string name="smscommunicator_loophasbeenenabled">Loop has been enabled</string> <string name="smscommunicator_loophasbeenenabled">Loop has been enabled</string>
<string name="smscommunicator_loopisenabled">Loop is enabled</string> <string name="smscommunicator_loopisenabled">Loop is enabled</string>
<string name="valuelimitedto">%1$.2f limited to %2$.2f</string>
<string name="valueoutofrange">»%1$s« is out of hard limits</string>
<string name="smscommunicator_pumpconnectwithcode">To connect pump reply with code %1$s</string> <string name="smscommunicator_pumpconnectwithcode">To connect pump reply with code %1$s</string>
<string name="smscommunicator_pumpconnectfail">Connection to pump failed</string> <string name="smscommunicator_pumpconnectfail">Connection to pump failed</string>
<string name="smscommunicator_pumpdisconnectwithcode">To disconnect pump for %1$d minutes reply with code %2$s</string> <string name="smscommunicator_pumpdisconnectwithcode">To disconnect pump for %1$d minutes reply with code %2$s</string>
@ -401,12 +398,6 @@
<string name="adult">Adult</string> <string name="adult">Adult</string>
<string name="resistantadult">Insulin resistant adult</string> <string name="resistantadult">Insulin resistant adult</string>
<string name="pregnant">Pregnancy</string> <string name="pregnant">Pregnancy</string>
<string name="key_age" translatable="false">age</string>
<string name="key_child" translatable="false">child</string>
<string name="key_teenage" translatable="false">teenage</string>
<string name="key_adult" translatable="false">adult</string>
<string name="key_resistantadult" translatable="false">resistantadult</string>
<string name="key_pregnant" translatable="false">pregnant</string>
<string name="patientage_summary">Please select patient type to setup safety limits</string> <string name="patientage_summary">Please select patient type to setup safety limits</string>
<string name="patient_name">Patient name</string> <string name="patient_name">Patient name</string>
<string name="patient_name_summary">Please provide patient name or nickname to differentiate among multiple setups</string> <string name="patient_name_summary">Please provide patient name or nickname to differentiate among multiple setups</string>
@ -1055,36 +1046,6 @@
<string name="basalpctfromtdd_label">% of basal</string> <string name="basalpctfromtdd_label">% of basal</string>
<string name="dpvdefaultprofile">DPV Default profile</string> <string name="dpvdefaultprofile">DPV Default profile</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Finishing Open Humans setup…</string>
<string name="this_may_take_a_while">This may take a while. Do not turn your phone or this plugin off.</string>
<string name="setup_finished">Setup finished</string>
<string name="your_phone_will_upload_data">Your phone will upload data to Open Humans soon.</string>
<string name="your_phone_is_upload_data">Your phone is uploading data to Open Humans now.</string>
<string name="setup_failed">Setup failed</string>
<string name="there_was_an_error">There was an error. Please try to log in again in order to proceed. Sorry &amp; Thank you!</string>
<string name="open_humans_terms">This is an open source tool that will copy your data to Open Humans. We retain no rights to share your data with third parties without your explicit authorization. The data the project and app receive are identified via a random user ID and will only be securely transmitted to an Open Humans account with your authorization of that process. You can stop uploading and delete your upload data at any time via www.openhumans.org.</string>
<string name="i_understand_and_agree">I understand and agree.</string>
<string name="login">Login</string>
<string name="logout">Logout</string>
<string name="oh_logout_confirmation">Do you really want to log out and stop donating data to science?</string>
<string name="project_member_id">Project Member ID: %s</string>
<string name="queue_size">Queue Size: %d</string>
<string name="terms_of_use">Terms of Use</string>
<string name="not_logged_in">Not logged in</string>
<string name="you_need_to_accept_the_of_use_first">You need to accept the terms of use first.</string>
<string name="successfully_logged_in">Successfully logged in</string>
<string name="setup_will_continue_in_background">The setup will be completed in background now. Thanks for uploading your data.\n\nPlease keep this plugin and your phone turned on for a short while for the setup to complete.</string>
<string name="completing_login">Completing login…</string>
<string name="donate_your_data_to_science">Donate your data to science</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">You have been signed out of Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Click here to sign in again if this wasn\'t on purpose.</string>
<string name="only_upload_if_connected_to_wifi">Only upload if connected to WiFi</string>
<string name="only_upload_if_charging">Only upload if charging</string>
<string name="worker_state">Worker State: %s</string>
<string name="uploaded_data">Uploaded Data</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">The following data will be uploaded to your Open Humans account: Glucose values, boluses, carbs, careportal events (except notes), extended boluses, profile switches, total daily doses, temporary basals, temp targets, preferences, application version, device model and screen dimensions. Secret or private information such as your Nightscout URL or API secret will not be uploaded.</string>
<string name="setupwizard_pump_riley_link_status">RileyLink status:</string> <string name="setupwizard_pump_riley_link_status">RileyLink status:</string>
<string name="filter">Filter</string> <string name="filter">Filter</string>
<string name="copytolocalprofile_invalid">Unable to create local profile. Profile is invalid.</string> <string name="copytolocalprofile_invalid">Unable to create local profile. Profile is invalid.</string>
@ -1113,16 +1074,6 @@
<string name="email_address">Email address</string> <string name="email_address">Email address</string>
<string name="privacy_settings">Privacy setting</string> <string name="privacy_settings">Privacy setting</string>
<string name="privacy_summary">You can provide optional email address if you want to be notified about app crashes. This is not an automated service. You will be contacted by developers in dangerous situations.</string> <string name="privacy_summary">You can provide optional email address if you want to be notified about app crashes. This is not an automated service. You will be contacted by developers in dangerous situations.</string>
<string name="profile_low_target">Profile low target</string>
<string name="profile_high_target">Profile high target</string>
<string name="temp_target_low_target">Temporary target bottom value</string>
<string name="temp_target_high_target">Temporary target top value</string>
<string name="temp_target_value">Temporary target value</string>
<string name="profile_dia">Profile DIA value</string>
<string name="profile_sensitivity_value">Profile sensitivity value</string>
<string name="profile_max_daily_basal_value">Maximal profile basal value</string>
<string name="current_basal_value">Current basal value</string>
<string name="profile_carbs_ratio_value">Profile carbs ratio value</string>
<string name="full_sync">Full sync</string> <string name="full_sync">Full sync</string>
<string name="prime">Prime</string> <string name="prime">Prime</string>
<string name="ns_sync_options">Synchronization</string> <string name="ns_sync_options">Synchronization</string>

View file

@ -43,7 +43,7 @@
android:title="@string/ns_receive_cgm" /> android:title="@string/ns_receive_cgm" />
<SwitchPreference <SwitchPreference
android:defaultValue="false" android:defaultValue="true"
android:key="@string/key_ns_receive_profile_store" android:key="@string/key_ns_receive_profile_store"
android:summary="@string/ns_receive_profile_store_summary" android:summary="@string/ns_receive_profile_store_summary"
android:title="@string/ns_receive_profile_store" /> android:title="@string/ns_receive_profile_store" />

View file

@ -19,7 +19,6 @@ import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin
import info.nightscout.androidaps.plugins.constraints.objectives.objectives.Objective import info.nightscout.androidaps.plugins.constraints.objectives.objectives.Objective
import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin
import info.nightscout.androidaps.plugins.general.maintenance.LoggerUtils
import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin

View file

@ -11,7 +11,6 @@ import org.junit.Assert
import org.junit.Test import org.junit.Test
import org.mockito.Mock import org.mockito.Mock
@kotlin.ExperimentalStdlibApi
class SignatureVerifierPluginTest : TestBase() { class SignatureVerifierPluginTest : TestBase() {
@Mock lateinit var resourceHelper: ResourceHelper @Mock lateinit var resourceHelper: ResourceHelper

View file

@ -58,7 +58,6 @@ import java.util.*
SmsManager::class, CommandQueue::class, LocalProfilePlugin::class, DateUtil::class, SmsManager::class, CommandQueue::class, LocalProfilePlugin::class, DateUtil::class,
OneTimePassword::class, UserEntryLogger::class, LoopPlugin::class, OneTimePassword::class, UserEntryLogger::class, LoopPlugin::class,
AppRepository::class, DateUtil::class, AutosensDataStore::class) AppRepository::class, DateUtil::class, AutosensDataStore::class)
@kotlin.ExperimentalStdlibApi
class SmsCommunicatorPluginTest : TestBaseWithProfile() { class SmsCommunicatorPluginTest : TestBaseWithProfile() {
@Mock lateinit var sp: SP @Mock lateinit var sp: SP

View file

@ -9,7 +9,6 @@ import info.nightscout.androidaps.queue.Callback
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
import javax.inject.Inject import javax.inject.Inject
import kotlin.reflect.full.primaryConstructor
abstract class Action(val injector: HasAndroidInjector) { abstract class Action(val injector: HasAndroidInjector) {
@ -34,7 +33,7 @@ abstract class Action(val injector: HasAndroidInjector) {
open fun hasDialog(): Boolean = false open fun hasDialog(): Boolean = false
open fun toJSON(): String = open fun toJSON(): String =
JSONObject().put("type", this.javaClass.name).toString() JSONObject().put("type", this.javaClass.simpleName).toString()
open fun fromJSON(data: String): Action = this open fun fromJSON(data: String): Action = this
@ -48,10 +47,37 @@ abstract class Action(val injector: HasAndroidInjector) {
fun instantiate(obj: JSONObject): Action? { fun instantiate(obj: JSONObject): Action? {
try { try {
val type = obj.getString("type") val type = obj.getString("type")
val data = obj.optJSONObject("data") val data = if (obj.has("data")) obj.getJSONObject("data") else JSONObject()
val clazz = Class.forName(type).kotlin return when (type) {
return (clazz.primaryConstructor?.call(injector) as Action).fromJSON(data?.toString() ActionAlarm::class.java.name, // backward compatibility
?: "") ActionAlarm::class.java.simpleName -> ActionAlarm(injector).fromJSON(data.toString())
ActionDummy::class.java.name,
ActionDummy::class.java.simpleName -> ActionDummy(injector).fromJSON(data.toString())
ActionLoopDisable::class.java.name,
ActionLoopDisable::class.java.simpleName -> ActionLoopDisable(injector).fromJSON(data.toString())
ActionLoopEnable::class.java.name,
ActionLoopEnable::class.java.simpleName -> ActionLoopEnable(injector).fromJSON(data.toString())
ActionLoopResume::class.java.name,
ActionLoopResume::class.java.simpleName -> ActionLoopResume(injector).fromJSON(data.toString())
ActionLoopSuspend::class.java.name,
ActionLoopSuspend::class.java.simpleName -> ActionLoopSuspend(injector).fromJSON(data.toString())
ActionNotification::class.java.name,
ActionNotification::class.java.simpleName -> ActionNotification(injector).fromJSON(data.toString())
ActionProfileSwitch::class.java.name,
ActionProfileSwitch::class.java.simpleName -> ActionProfileSwitch(injector).fromJSON(data.toString())
ActionProfileSwitchPercent::class.java.name,
ActionProfileSwitchPercent::class.java.simpleName -> ActionProfileSwitchPercent(injector).fromJSON(data.toString())
ActionSendSMS::class.java.name,
ActionSendSMS::class.java.simpleName -> ActionSendSMS(injector).fromJSON(data.toString())
ActionStartTempTarget::class.java.name,
ActionStartTempTarget::class.java.simpleName -> ActionStartTempTarget(injector).fromJSON(data.toString())
ActionStopTempTarget::class.java.name,
ActionStopTempTarget::class.java.simpleName -> ActionStopTempTarget(injector).fromJSON(data.toString())
else -> throw ClassNotFoundException(type)
}
//val clazz = Class.forName(type).kotlin
//return (clazz.primaryConstructor?.call(injector) as Action).fromJSON(data?.toString()
// ?: "")
//return (clazz.newInstance() as Action).fromJSON(data?.toString() ?: "") //return (clazz.newInstance() as Action).fromJSON(data?.toString() ?: "")
} catch (e: ClassNotFoundException) { } catch (e: ClassNotFoundException) {
aapsLogger.error("Unhandled exception", e) aapsLogger.error("Unhandled exception", e)

View file

@ -41,12 +41,12 @@ class SimpleItemTouchHelperCallback(private val mAdapter: ItemTouchHelperAdapter
return false return false
} }
// Notify the adapter of the move // Notify the adapter of the move
mAdapter.onItemMove(source.adapterPosition, target.adapterPosition) mAdapter.onItemMove(source.absoluteAdapterPosition, target.absoluteAdapterPosition)
return true return true
} }
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, i: Int) { // Notify the adapter of the dismissal override fun onSwiped(viewHolder: RecyclerView.ViewHolder, i: Int) { // Notify the adapter of the dismissal
mAdapter.onItemDismiss(viewHolder.adapterPosition) mAdapter.onItemDismiss(viewHolder.absoluteAdapterPosition)
} }
override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) { override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) {

View file

@ -6,6 +6,7 @@ import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.interfaces.ConfigBuilder import info.nightscout.androidaps.interfaces.ConfigBuilder
import info.nightscout.androidaps.interfaces.Loop import info.nightscout.androidaps.interfaces.Loop
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.automation.actions.Action
import info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopEnable import info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopEnable
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnectorTest import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnectorTest
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerDummy import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerDummy
@ -29,6 +30,9 @@ class AutomationEventTest : TestBase() {
if (it is AutomationEvent) { if (it is AutomationEvent) {
it.aapsLogger = aapsLogger it.aapsLogger = aapsLogger
} }
if (it is Action) {
it.aapsLogger = aapsLogger
}
if (it is ActionLoopEnable) { if (it is ActionLoopEnable) {
it.loopPlugin = loopPlugin it.loopPlugin = loopPlugin
it.resourceHelper = resourceHelper it.resourceHelper = resourceHelper
@ -48,7 +52,7 @@ class AutomationEventTest : TestBase() {
event.addAction(ActionLoopEnable(injector)) event.addAction(ActionLoopEnable(injector))
// export to json // export to json
val eventJsonExpected = "{\"autoRemove\":false,\"readOnly\":false,\"trigger\":\"{\\\"data\\\":{\\\"connectorType\\\":\\\"AND\\\",\\\"triggerList\\\":[\\\"{\\\\\\\"data\\\\\\\":{\\\\\\\"connectorType\\\\\\\":\\\\\\\"AND\\\\\\\",\\\\\\\"triggerList\\\\\\\":[]},\\\\\\\"type\\\\\\\":\\\\\\\"TriggerConnector\\\\\\\"}\\\"]},\\\"type\\\":\\\"TriggerConnector\\\"}\",\"title\":\"Test\",\"systemAction\":false,\"actions\":[\"{\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopEnable\\\"}\"],\"enabled\":true}" val eventJsonExpected = "{\"autoRemove\":false,\"readOnly\":false,\"trigger\":\"{\\\"data\\\":{\\\"connectorType\\\":\\\"AND\\\",\\\"triggerList\\\":[\\\"{\\\\\\\"data\\\\\\\":{\\\\\\\"connectorType\\\\\\\":\\\\\\\"AND\\\\\\\",\\\\\\\"triggerList\\\\\\\":[]},\\\\\\\"type\\\\\\\":\\\\\\\"TriggerConnector\\\\\\\"}\\\"]},\\\"type\\\":\\\"TriggerConnector\\\"}\",\"title\":\"Test\",\"systemAction\":false,\"actions\":[\"{\\\"type\\\":\\\"ActionLoopEnable\\\"}\"],\"enabled\":true}"
Assert.assertEquals(eventJsonExpected, event.toJSON()) Assert.assertEquals(eventJsonExpected, event.toJSON())
// clone // clone
@ -64,7 +68,7 @@ class AutomationEventTest : TestBase() {
Assert.assertEquals(event.trigger.toJSON(), clone.trigger.toJSON()) Assert.assertEquals(event.trigger.toJSON(), clone.trigger.toJSON())
// check action // check action
Assert.assertEquals(1, clone.actions.size.toLong()) Assert.assertEquals(1, clone.actions.size)
Assert.assertFalse(event.actions === clone.actions) // not the same object reference Assert.assertFalse(event.actions === clone.actions) // not the same object reference
Assert.assertEquals(clone.toJSON(), clone.toJSON()) Assert.assertEquals(clone.toJSON(), clone.toJSON())
} }

View file

@ -66,7 +66,7 @@ class ActionStopTempTargetTest : ActionsTestBase() {
} }
@Test fun toJSONTest() { @Test fun toJSONTest() {
Assert.assertEquals("{\"type\":\"info.nightscout.androidaps.plugins.general.automation.actions.ActionStopTempTarget\"}", sut.toJSON()) Assert.assertEquals("{\"type\":\"ActionStopTempTarget\"}", sut.toJSON())
} }
@Test fun fromJSONTest() { @Test fun fromJSONTest() {

View file

@ -90,21 +90,25 @@ open class ActionsTestBase : TestBaseWithProfile() {
it.dateUtil = dateUtil it.dateUtil = dateUtil
} }
if (it is ActionProfileSwitchPercent) { if (it is ActionProfileSwitchPercent) {
it.aapsLogger = aapsLogger
it.resourceHelper = resourceHelper it.resourceHelper = resourceHelper
it.profileFunction = profileFunction it.profileFunction = profileFunction
it.uel = uel it.uel = uel
} }
if (it is ActionNotification) { if (it is ActionNotification) {
it.aapsLogger = aapsLogger
it.resourceHelper = resourceHelper it.resourceHelper = resourceHelper
it.rxBus = rxBus it.rxBus = rxBus
} }
if (it is ActionLoopSuspend) { if (it is ActionLoopSuspend) {
it.aapsLogger = aapsLogger
it.loopPlugin = loopPlugin it.loopPlugin = loopPlugin
it.resourceHelper = resourceHelper it.resourceHelper = resourceHelper
it.rxBus = rxBus it.rxBus = rxBus
it.uel = uel it.uel = uel
} }
if (it is ActionLoopResume) { if (it is ActionLoopResume) {
it.aapsLogger = aapsLogger
it.loopPlugin = loopPlugin it.loopPlugin = loopPlugin
it.resourceHelper = resourceHelper it.resourceHelper = resourceHelper
it.configBuilder = configBuilder it.configBuilder = configBuilder
@ -114,6 +118,7 @@ open class ActionsTestBase : TestBaseWithProfile() {
it.uel = uel it.uel = uel
} }
if (it is ActionLoopEnable) { if (it is ActionLoopEnable) {
it.aapsLogger = aapsLogger
it.loopPlugin = loopPlugin it.loopPlugin = loopPlugin
it.resourceHelper = resourceHelper it.resourceHelper = resourceHelper
it.configBuilder = configBuilder it.configBuilder = configBuilder
@ -121,6 +126,7 @@ open class ActionsTestBase : TestBaseWithProfile() {
it.uel = uel it.uel = uel
} }
if (it is ActionLoopDisable) { if (it is ActionLoopDisable) {
it.aapsLogger = aapsLogger
it.loopPlugin = loopPlugin it.loopPlugin = loopPlugin
it.resourceHelper = resourceHelper it.resourceHelper = resourceHelper
it.configBuilder = configBuilder it.configBuilder = configBuilder

View file

@ -2,7 +2,7 @@
buildscript { buildscript {
ext { ext {
kotlin_version = '1.5.21' kotlin_version = '1.5.30'
coreVersion = '1.6.0' coreVersion = '1.6.0'
rxjava_version = '2.2.21' rxjava_version = '2.2.21'
rxandroid_version = '2.1.1' rxandroid_version = '2.1.1'
@ -25,12 +25,12 @@ buildscript {
work_version = '2.5.0' work_version = '2.5.0'
junit_version = '4.13.2' junit_version = '4.13.2'
mockitoVersion = '3.11.2' mockitoVersion = '3.12.4'
powermockVersion = '2.0.9' powermockVersion = '2.0.9'
dexmakerVersion = "1.2" dexmakerVersion = "1.2"
retrofit2Version = '2.9.0' retrofit2Version = '2.9.0'
okhttp3Version = '4.9.0' okhttp3Version = '4.9.0'
byteBuddyVersion = '1.11.12' byteBuddyVersion = '1.11.13'
androidx_junit = '1.1.2' androidx_junit = '1.1.2'
androidx_rules = '1.4.0-alpha04' androidx_rules = '1.4.0-alpha04'
@ -41,7 +41,7 @@ buildscript {
maven { url "https://plugins.gradle.org/m2/" } // jacoco 0.2 maven { url "https://plugins.gradle.org/m2/" } // jacoco 0.2
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.0.0' classpath 'com.android.tools.build:gradle:7.0.2'
classpath 'com.google.gms:google-services:4.3.10' classpath 'com.google.gms:google-services:4.3.10'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.7.1' classpath 'com.google.firebase:firebase-crashlytics-gradle:2.7.1'

View file

@ -19,6 +19,8 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.Round
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import org.json.JSONArray import org.json.JSONArray
@ -94,34 +96,93 @@ sealed class ProfileSealed(
value.timeZone.rawOffset.toLong() value.timeZone.rawOffset.toLong()
) )
override fun isValid(from: String, pump: Pump, config: Config, resourceHelper: ResourceHelper, rxBus: RxBusWrapper): Boolean { override fun isValid(from: String, pump: Pump, config: Config, resourceHelper: ResourceHelper, rxBus: RxBusWrapper, hardLimits: HardLimits): Profile.ValidityCheck {
val notify = true val notify = true
var valid = true val validityCheck = Profile.ValidityCheck()
val description = pump.pumpDescription val description = pump.pumpDescription
if (!description.is30minBasalRatesCapable) { for (basal in basalBlocks) {
for (basal in basalBlocks) { val basalAmount = basal.amount * percentage / 100.0
if (!description.is30minBasalRatesCapable) {
// Check for hours alignment // Check for hours alignment
val duration: Long = basal.duration val duration: Long = basal.duration
if (duration % 3600000 != 0L) { if (duration % 3600000 != 0L) {
if (notify && config.APS) { if (notify && config.APS) {
val notification = Notification(Notification.BASAL_PROFILE_NOT_ALIGNED_TO_HOURS, resourceHelper.gs(R.string.basalprofilenotaligned, from), Notification.NORMAL) val notification = Notification(
Notification.BASAL_PROFILE_NOT_ALIGNED_TO_HOURS,
resourceHelper.gs(R.string.basalprofilenotaligned, from),
Notification.NORMAL
)
rxBus.send(EventNewNotification(notification)) rxBus.send(EventNewNotification(notification))
} }
valid = false validityCheck.isValid = false
} validityCheck.reasons.add(
// Check for minimal basal value resourceHelper.gs(
if (basal.amount < description.basalMinimumRate) { R.string.basalprofilenotaligned,
basal.amount = description.basalMinimumRate from
if (notify) sendBelowMinimumNotification(from, rxBus, resourceHelper) )
valid = false )
} else if (basal.amount > description.basalMaximumRate) { break
basal.amount = description.basalMaximumRate
if (notify) sendAboveMaximumNotification(from, rxBus, resourceHelper)
valid = false
} }
} }
// Check for minimal basal value
if (basalAmount < description.basalMinimumRate) {
basal.amount = description.basalMinimumRate
if (notify) sendBelowMinimumNotification(from, rxBus, resourceHelper)
validityCheck.isValid = false
validityCheck.reasons.add(resourceHelper.gs(R.string.minimalbasalvaluereplaced, from))
break
} else if (basalAmount > description.basalMaximumRate) {
basal.amount = description.basalMaximumRate
if (notify) sendAboveMaximumNotification(from, rxBus, resourceHelper)
validityCheck.isValid = false
validityCheck.reasons.add(resourceHelper.gs(R.string.maximumbasalvaluereplaced, from))
break
}
if (!hardLimits.isInRange(basalAmount, 0.01, hardLimits.maxBasal())) {
validityCheck.isValid = false
validityCheck.reasons.add(resourceHelper.gs(R.string.value_out_of_hard_limits, resourceHelper.gs(R.string.basal_value), basalAmount))
break
}
} }
return valid if (!hardLimits.isInRange(dia, hardLimits.minDia(), hardLimits.maxDia())) {
validityCheck.isValid = false
validityCheck.reasons.add(resourceHelper.gs(R.string.value_out_of_hard_limits, resourceHelper.gs(R.string.profile_dia), dia))
}
for (ic in icBlocks)
if (!hardLimits.isInRange(ic.amount * 100.0 / percentage, hardLimits.minIC(), hardLimits.maxIC())) {
validityCheck.isValid = false
validityCheck.reasons.add(resourceHelper.gs(R.string.value_out_of_hard_limits, resourceHelper.gs(R.string.profile_carbs_ratio_value), ic.amount * 100.0 / percentage))
break
}
for (isf in isfBlocks)
if (!hardLimits.isInRange(toMgdl(isf.amount * 100.0 / percentage, units), HardLimits.MIN_ISF, HardLimits.MAX_ISF)) {
validityCheck.isValid = false
validityCheck.reasons.add(resourceHelper.gs(R.string.value_out_of_hard_limits, resourceHelper.gs(R.string.profile_sensitivity_value), isf.amount * 100.0 / percentage))
break
}
for (target in targetBlocks) {
if (!hardLimits.isInRange(
Profile.toMgdl(target.lowTarget, units),
HardLimits.VERY_HARD_LIMIT_MIN_BG[0].toDouble(),
HardLimits.VERY_HARD_LIMIT_MIN_BG[1].toDouble()
)
) {
validityCheck.isValid = false
validityCheck.reasons.add(resourceHelper.gs(R.string.value_out_of_hard_limits, resourceHelper.gs(R.string.profile_low_target), target.lowTarget))
break
}
if (!hardLimits.isInRange(
Profile.toMgdl(target.highTarget, units),
HardLimits.VERY_HARD_LIMIT_MAX_BG[0].toDouble(),
HardLimits.VERY_HARD_LIMIT_MAX_BG[1].toDouble()
)
) {
validityCheck.isValid = false
validityCheck.reasons.add(resourceHelper.gs(R.string.value_out_of_hard_limits, resourceHelper.gs(R.string.profile_high_target), target.highTarget))
break
}
}
return validityCheck
} }
protected open fun sendBelowMinimumNotification(from: String, rxBus: RxBusWrapper, resourceHelper: ResourceHelper) { protected open fun sendBelowMinimumNotification(from: String, rxBus: RxBusWrapper, resourceHelper: ResourceHelper) {

View file

@ -17,15 +17,18 @@ import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.extensions.getCustomizedName import info.nightscout.androidaps.extensions.getCustomizedName
import info.nightscout.androidaps.extensions.pureProfileFromJson import info.nightscout.androidaps.extensions.pureProfileFromJson
import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.HtmlHelper import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import org.json.JSONObject import org.json.JSONObject
import java.io.File.separator
import java.text.DecimalFormat import java.text.DecimalFormat
import javax.inject.Inject import javax.inject.Inject
@ -39,6 +42,7 @@ class ProfileViewerDialog : DaggerDialogFragment() {
@Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var config: Config @Inject lateinit var config: Config
@Inject lateinit var rxBus: RxBusWrapper @Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var hardLimits: HardLimits
private var time: Long = 0 private var time: Long = 0
@ -149,7 +153,9 @@ class ProfileViewerDialog : DaggerDialogFragment() {
} }
binding.noprofile.visibility = View.GONE binding.noprofile.visibility = View.GONE
binding.invalidprofile.visibility = if (profile1.isValid("ProfileViewDialog", activePlugin.activePump, config, resourceHelper, rxBus)) View.GONE else View.VISIBLE val validity = profile1.isValid("ProfileViewDialog", activePlugin.activePump, config, resourceHelper, rxBus, hardLimits)
binding.invalidprofile.text = resourceHelper.gs(R.string.invalidprofile) + "\n" + validity.reasons.joinToString(separator = "\n")
binding.invalidprofile.visibility = validity.isValid.not().toVisibility()
} }
else else
profile?.let { profile?.let {
@ -164,7 +170,9 @@ class ProfileViewerDialog : DaggerDialogFragment() {
binding.basalGraph.show(it) binding.basalGraph.show(it)
binding.noprofile.visibility = View.GONE binding.noprofile.visibility = View.GONE
binding.invalidprofile.visibility = if (it.isValid("ProfileViewDialog", activePlugin.activePump, config, resourceHelper, rxBus)) View.GONE else View.VISIBLE val validity = it.isValid("ProfileViewDialog", activePlugin.activePump, config, resourceHelper, rxBus, hardLimits)
binding.invalidprofile.text = resourceHelper.gs(R.string.invalidprofile) + "\n" + validity.reasons.joinToString(separator = "\n")
binding.invalidprofile.visibility = validity.isValid.not().toVisibility()
} }
} }

View file

@ -15,7 +15,7 @@ private fun getShiftedTimeSecs(originalSeconds: Int, timeShiftHours: Int): Int {
fun List<Block>.shiftBlock(multiplier: Double, timeShiftHours: Int): List<Block> { fun List<Block>.shiftBlock(multiplier: Double, timeShiftHours: Int): List<Block> {
val newList = arrayListOf<Block>() val newList = arrayListOf<Block>()
for (hour in 0..23) newList.add(Block(1000 * 60 * 60, blockValueBySeconds(hour * 3600, multiplier, timeShiftHours))) for (hour in 0..23) newList.add(Block(1000L * 60 * 60, blockValueBySeconds(hour * 3600, multiplier, timeShiftHours)))
for (i in newList.indices.reversed()) { for (i in newList.indices.reversed()) {
if (i > 0) if (i > 0)
if (newList[i].amount == newList[i - 1].amount) { if (newList[i].amount == newList[i - 1].amount) {
@ -29,7 +29,7 @@ fun List<Block>.shiftBlock(multiplier: Double, timeShiftHours: Int): List<Block>
fun List<TargetBlock>.shiftTargetBlock(timeShiftHours: Int): List<TargetBlock> { fun List<TargetBlock>.shiftTargetBlock(timeShiftHours: Int): List<TargetBlock> {
val newList = arrayListOf<TargetBlock>() val newList = arrayListOf<TargetBlock>()
for (hour in 0..23) for (hour in 0..23)
newList.add(TargetBlock(1000 * 60 * 60, lowTargetBlockValueBySeconds(hour * 3600, timeShiftHours), highTargetBlockValueBySeconds(hour * 3600, timeShiftHours))) newList.add(TargetBlock(1000L * 60 * 60, lowTargetBlockValueBySeconds(hour * 3600, timeShiftHours), highTargetBlockValueBySeconds(hour * 3600, timeShiftHours)))
for (i in newList.indices.reversed()) { for (i in newList.indices.reversed()) {
if (i > 0) if (i > 0)
if (newList[i].lowTarget == newList[i - 1].lowTarget && newList[i].highTarget == newList[i - 1].highTarget) { if (newList[i].lowTarget == newList[i - 1].lowTarget && newList[i].highTarget == newList[i - 1].highTarget) {

View file

@ -18,7 +18,6 @@ fun ByteArray.toHex() : String{
return result.toString() return result.toString()
} }
@kotlin.ExperimentalStdlibApi
fun String.hexStringToByteArray(): ByteArray { fun String.hexStringToByteArray(): ByteArray {
val result = ByteArray(length / 2) val result = ByteArray(length / 2)
@ -29,7 +28,7 @@ fun String.hexStringToByteArray(): ByteArray {
val secondIndex = HEX_CHARS.indexOf(lowerCased[i + 1]) val secondIndex = HEX_CHARS.indexOf(lowerCased[i + 1])
val octet = firstIndex.shl(4).or(secondIndex) val octet = firstIndex.shl(4).or(secondIndex)
result.set(i.shr(1), octet.toByte()) result[i.shr(1)] = octet.toByte()
} }
return result return result

View file

@ -6,6 +6,7 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DecimalFormatter.to0Decimal import info.nightscout.androidaps.utils.DecimalFormatter.to0Decimal
import info.nightscout.androidaps.utils.DecimalFormatter.to1Decimal import info.nightscout.androidaps.utils.DecimalFormatter.to1Decimal
import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.Round import info.nightscout.androidaps.utils.Round
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import org.joda.time.DateTime import org.joda.time.DateTime
@ -13,7 +14,9 @@ import org.json.JSONObject
interface Profile { interface Profile {
fun isValid(from: String, pump: Pump, config: Config, resourceHelper: ResourceHelper, rxBus: RxBusWrapper): Boolean class ValidityCheck(var isValid: Boolean = true, val reasons: ArrayList<String> = arrayListOf())
fun isValid(from: String, pump: Pump, config: Config, resourceHelper: ResourceHelper, rxBus: RxBusWrapper, hardLimits: HardLimits): ValidityCheck
/** /**
* Units used for ISF & target * Units used for ISF & target

View file

@ -46,6 +46,18 @@ interface ProfileFunction {
*/ */
fun getRequestedProfile(): ProfileSwitch? fun getRequestedProfile(): ProfileSwitch?
/**
* Build a new circadian profile switch request based on provided profile
*
* @param profileStore ProfileStore to use
* @param profileName this profile from profile store
* @param durationInMinutes
* @param percentage 100 = no modification
* @param timeShiftInHours 0 = no modification
* @param timestamp expected time
*/
fun buildProfileSwitch(profileStore: ProfileStore, profileName: String, durationInMinutes: Int, percentage: Int, timeShiftInHours: Int, timestamp: Long): ProfileSwitch
/** /**
* Create a new circadian profile switch request based on provided profile * Create a new circadian profile switch request based on provided profile
* *

View file

@ -63,7 +63,7 @@ class PumpDescription() {
is30minBasalRatesCapable = false is30minBasalRatesCapable = false
isRefillingCapable = true isRefillingCapable = true
isBatteryReplaceable = true isBatteryReplaceable = true
storesCarbInfo = true storesCarbInfo = false
supportsTDDs = false supportsTDDs = false
needsManualTDDLoad = true needsManualTDDLoad = true
hasCustomUnreachableAlertCheck = false hasCustomUnreachableAlertCheck = false

View file

@ -26,8 +26,7 @@ class PrefFileListProvider @Inject constructor(
private val classicPrefsFormat: ClassicPrefsFormat, private val classicPrefsFormat: ClassicPrefsFormat,
private val encryptedPrefsFormat: EncryptedPrefsFormat, private val encryptedPrefsFormat: EncryptedPrefsFormat,
private val storage: Storage, private val storage: Storage,
private val versionCheckerUtils: VersionCheckerUtils, private val versionCheckerUtils: VersionCheckerUtils
context: Context
) { ) {
private val path = File(Environment.getExternalStorageDirectory().toString()) private val path = File(Environment.getExternalStorageDirectory().toString())

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