Merge branch 'dev' of github.com:MilosKozak/AndroidAPS into update-oref

This commit is contained in:
Tim Gunn 2020-03-25 13:30:12 +13:00
commit e1d8691af2
No known key found for this signature in database
GPG key ID: C9BC1E9D0D0AED8C
152 changed files with 2563 additions and 706 deletions

View file

@ -1,9 +1,6 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<option name="AUTODETECT_INDENTS" value="false" />
<AndroidXmlCodeStyleSettings>
<option name="ARRANGEMENT_SETTINGS_MIGRATED_TO_191" value="true" />
</AndroidXmlCodeStyleSettings>
<JetCodeStyleSettings>
<option name="ALIGN_IN_COLUMNS_CASE_BRANCH" value="true" />
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="6" />

View file

@ -109,7 +109,7 @@ android {
targetSdkVersion 28
multiDexEnabled true
versionCode 1500
version "2.6-dev"
version "2.6.1-dev"
buildConfigField "String", "VERSION", '"' + version + '"'
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"'
@ -315,6 +315,7 @@ dependencies {
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test:rules:1.3.0-alpha03'
androidTestImplementation 'com.google.code.findbugs:jsr305:3.0.2'
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
}
@ -341,7 +342,37 @@ task copyLibs(dependsOn: downloadAndUnzipFile, type: Copy) {
task full_clean(type: Delete) {
delete file("src/main/jniLibs")
}
/*
// Run 'adb' shell command to clear application data of main app for 'debug' variant
task clearMainAppData(type: Exec) {
// we have to iterate to find the 'debug' variant to obtain a variant reference
android.applicationVariants.all { variant ->
if (variant.name == "fullDebug") {
def applicationId = [variant.mergedFlavor.applicationId, variant.buildType.applicationIdSuffix].findAll().join()
def clearDataCommand = ['adb', 'shell', 'pm', 'clear', applicationId]
println "Clearing application data of ${variant.name} variant: [${clearDataCommand}]"
def stdout = new ByteArrayOutputStream()
exec {
commandLine clearDataCommand
standardOutput = stdout
}
String result = stdout.toString().trim()
if (!result.startsWith("Success")) {
println result
throw new GradleException(clearDataCommand.join(" "))
}
}
}
}
// Clear Application Data (once) before running instrumentation test
tasks.whenTaskAdded { task ->
// Both of these targets are equivalent today, although in future connectedCheck
// will also include connectedUiAutomatorTest (not implemented yet)
if(task.name == "connectedAndroidTest" || task.name == "connectedCheck"){
task.dependsOn(clearMainAppData)
}
}
*/
clean.dependsOn full_clean
preBuild.dependsOn copyLibs

Binary file not shown.

View file

@ -4,6 +4,9 @@ import androidx.test.espresso.ViewAction
import androidx.test.espresso.ViewInteraction
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.UiSelector
fun ViewInteraction.isDisplayed(): Boolean {
try {
@ -25,3 +28,8 @@ fun ViewInteraction.waitAndPerform(viewActions: ViewAction): ViewInteraction? {
return perform(viewActions)
}
fun clickOkInDialog() {
val uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
val button = uiDevice.findObject(UiSelector().clickable(true).checkable(false).index(1))
if (button.exists() && button.isEnabled) button.click()
}

View file

@ -0,0 +1,116 @@
package info.nightscout.androidaps
import android.os.SystemClock
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.rule.ActivityTestRule
import androidx.test.rule.GrantPermissionRule
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.PumpInterface
import info.nightscout.androidaps.logging.L
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin
import info.nightscout.androidaps.plugins.general.actions.ActionsPlugin
import info.nightscout.androidaps.plugins.insulin.InsulinOrefUltraRapidActingPlugin
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
import info.nightscout.androidaps.plugins.pump.danaRv2.DanaRv2Plugin
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
import info.nightscout.androidaps.plugins.source.RandomBgPlugin
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.SP
import info.nightscout.androidaps.utils.isRunningTest
import org.json.JSONObject
import org.junit.Assert
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.slf4j.LoggerFactory
@LargeTest
@RunWith(AndroidJUnit4::class)
class RealPumpTest {
private val log = LoggerFactory.getLogger(L.CORE)
companion object {
val pump: PumpInterface = DanaRv2Plugin.getPlugin()
const val R_PASSWORD = 1234
const val R_SERIAL = "PBB00013LR_P"
}
private val validProfile = "{\"dia\":\"6\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"10\"},{\"time\":\"2:00\",\"value\":\"11\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}"
@Rule
@JvmField
var mActivityTestRule = ActivityTestRule(MainActivity::class.java)
@Rule
@JvmField
var mGrantPermissionRule: GrantPermissionRule =
GrantPermissionRule.grant(
android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
)
@Before
fun clear() {
SP.clear()
SP.putBoolean(R.string.key_setupwizard_processed, true)
SP.putString(R.string.key_aps_mode, "closed")
MainApp.getDbHelper().resetDatabases()
MainApp.devBranch = false
}
private fun preparePlugins() {
// Source
RandomBgPlugin.performPluginSwitch(true, PluginType.BGSOURCE)
// Profile
LocalProfilePlugin.performPluginSwitch(true, PluginType.PROFILE)
val profile = Profile(JSONObject(validProfile), Constants.MGDL)
Assert.assertTrue(profile.isValid("Test"))
LocalProfilePlugin.profiles.clear()
LocalProfilePlugin.numOfProfiles = 0
val singleProfile = LocalProfilePlugin.SingleProfile().copyFrom(profile, "TestProfile")
LocalProfilePlugin.addProfile(singleProfile)
ProfileFunctions.doProfileSwitch(LocalProfilePlugin.createProfileStore(), "TestProfile", 0, 100, 0, DateUtil.now())
// Insulin
InsulinOrefUltraRapidActingPlugin.getPlugin().performPluginSwitch(true, PluginType.INSULIN)
// Pump
SP.putInt(R.string.key_danar_password, R_PASSWORD)
SP.putString(R.string.key_danar_bt_name, R_SERIAL)
(pump as PluginBase).performPluginSwitch(true, PluginType.PUMP)
// Sensitivity
SensitivityOref1Plugin.getPlugin().performPluginSwitch(true, PluginType.SENSITIVITY)
// APS
OpenAPSSMBPlugin.getPlugin().performPluginSwitch(true, PluginType.APS)
LoopPlugin.getPlugin().performPluginSwitch(true, PluginType.LOOP)
// Enable common
ActionsPlugin.performPluginSwitch(true, PluginType.GENERAL)
// Disable unneeded
MainApp.getPluginsList().remove(ObjectivesPlugin)
}
@Test
fun doTest() {
Assert.assertTrue(isRunningTest())
preparePlugins()
while (!pump.isInitialized) {
log.debug("Waiting for initialization")
SystemClock.sleep(1000)
}
while (true) {
log.debug("Tick")
SystemClock.sleep(1000)
}
}
}

View file

@ -1,6 +1,5 @@
package info.nightscout.androidaps
import android.os.SystemClock
import android.view.View
import android.view.ViewGroup
@ -9,12 +8,15 @@ 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.*
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.filters.LargeTest
import androidx.test.rule.ActivityTestRule
import androidx.test.rule.GrantPermissionRule
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
@ -39,7 +41,6 @@ import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@LargeTest
@RunWith(AndroidJUnit4::class)
class SetupWizardActivityTest {
@ -50,12 +51,12 @@ class SetupWizardActivityTest {
@Rule
@JvmField
var mGrantPermissionRule =
GrantPermissionRule.grant(
android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
)
var mGrantPermissionRule: GrantPermissionRule =
GrantPermissionRule.grant(
android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
)
@Before
fun clear() {
@ -74,9 +75,9 @@ adb shell settings put global transition_animation_scale 0 &
adb shell settings put global animator_duration_scale 0 &
*/
@Test
fun setupWizardActivityTest() {
SP.clear()
Assert.assertTrue(isRunningTest())
// Welcome page
onView(withId(R.id.next_button)).perform(click())
@ -86,7 +87,7 @@ adb shell settings put global animator_duration_scale 0 &
// Agreement page
onView(withText("I UNDERSTAND AND AGREE")).perform(scrollTo(), click())
onView(withId(R.id.next_button)).waitAndPerform(click())
// Loction permission
// Location permission
var askButton = onView(withText("Ask for permission"))
if (askButton.isDisplayed()) {
askButton.perform(scrollTo(), click())
@ -99,6 +100,11 @@ adb shell settings put global animator_duration_scale 0 &
onView(withText("OK")).perform(click())
onView(withId(R.id.next_button)).waitAndPerform(click())
}
// Import settings : skip of found
askButton = onView(withText("IMPORT SETTINGS"))
if (askButton.isDisplayed()) {
onView(withId(R.id.next_button)).waitAndPerform(click())
}
// Units selection
onView(withText("mmol/L")).perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click())
@ -125,41 +131,44 @@ adb shell settings put global animator_duration_scale 0 &
// Local profile - IC
onView(withId(R.id.ic_tab)).perform(scrollTo(), click())
onView(Matchers.allOf(withTagValue(Matchers.`is`("IC-1-0")), isDisplayed()))
.perform(ViewActions.replaceText("2"), ViewActions.closeSoftKeyboard())
.perform(ViewActions.replaceText("2"), ViewActions.closeSoftKeyboard())
// Local profile - ISF
onView(withId(R.id.isf_tab)).perform(scrollTo(), click())
onView(Matchers.allOf(withTagValue(Matchers.`is`("ISF-1-0")), isDisplayed()))
.perform(ViewActions.replaceText("3"), ViewActions.closeSoftKeyboard())
.perform(ViewActions.replaceText("3"), ViewActions.closeSoftKeyboard())
// Local profile - BAS
onView(withId(R.id.basal_tab)).perform(scrollTo(), click())
onView(childAtPosition(Matchers.allOf(withId(R.id.localprofile_basal), childAtPosition(withClassName(Matchers.`is`("android.widget.LinearLayout")), 6)), 2))
.perform(scrollTo(), click())
.perform(scrollTo(), click())
onView(Matchers.allOf(withTagValue(Matchers.`is`("BASAL-1-0")), isDisplayed()))
.perform(ViewActions.replaceText("1.1"), ViewActions.closeSoftKeyboard())
.perform(ViewActions.replaceText("1.1"), ViewActions.closeSoftKeyboard())
onView(Matchers.allOf(withTagValue(Matchers.`is`("BASAL-1-1")), isDisplayed()))
.perform(ViewActions.replaceText("1.2"), ViewActions.closeSoftKeyboard())
.perform(ViewActions.replaceText("1.2"), ViewActions.closeSoftKeyboard())
onView(Matchers.allOf(withId(R.id.timelistedit_time), childAtPosition(childAtPosition(withId(R.id.localprofile_basal), 2), 0)))
.perform(scrollTo(), click())
.perform(scrollTo(), click())
onData(Matchers.anything()).inAdapterView(childAtPosition(withClassName(Matchers.`is`("android.widget.PopupWindow\$PopupBackgroundView")), 0)).atPosition(13)
.perform(click())
.perform(click())
// Local profile - TARGET
onView(withId(R.id.target_tab)).perform(scrollTo(), click())
onView(Matchers.allOf(withTagValue(Matchers.`is`("TARGET-1-0")), isDisplayed()))
.perform(ViewActions.replaceText("6"), ViewActions.closeSoftKeyboard())
.perform(ViewActions.replaceText("6"), ViewActions.closeSoftKeyboard())
onView(Matchers.allOf(withTagValue(Matchers.`is`("TARGET-2-0")), isDisplayed()))
.perform(ViewActions.replaceText("6.5"), ViewActions.closeSoftKeyboard())
.perform(ViewActions.replaceText("6.5"), ViewActions.closeSoftKeyboard())
onView(withText("Save")).perform(scrollTo(), click())
onView(Matchers.allOf(withId(R.id.localprofile_profileswitch), isDisplayed()))
.perform(scrollTo(), click())
.perform(scrollTo(), click())
onView(allOf(withId(R.id.ok), isDisplayed())).perform(click())
onView(Matchers.allOf(withText("OK"), isDisplayed())).perform(click())
// confirm dialog
//onView(Matchers.allOf(withText("OK"), isDisplayed())).perform(click()) not working on real phone
clickOkInDialog()
onView(withId(R.id.next_button)).waitAndPerform(click())
// Profile switch
askButton = onView(withText("Do Profile Switch"))
if (askButton.isDisplayed()) {
askButton.perform(scrollTo(), click())
onView(allOf(withId(R.id.ok), isDisplayed())).perform(click())
onView(Matchers.allOf(withText("OK"), isDisplayed())).perform(click())
// onView(Matchers.allOf(withText("OK"), isDisplayed())).perform(click()) not working on real phone
clickOkInDialog()
while (ProfileFunctions.getInstance().profile == null) SystemClock.sleep(100)
onView(withId(R.id.next_button)).waitAndPerform(click())
}
@ -204,7 +213,7 @@ adb shell settings put global animator_duration_scale 0 &
}
private fun childAtPosition(
parentMatcher: Matcher<View>, position: Int): Matcher<View> {
parentMatcher: Matcher<View>, position: Int): Matcher<View> {
return object : TypeSafeMatcher<View>() {
override fun describeTo(description: Description) {
@ -215,7 +224,7 @@ adb shell settings put global animator_duration_scale 0 &
public override fun matchesSafely(view: View): Boolean {
val parent = view.parent
return parent is ViewGroup && parentMatcher.matches(parent)
&& view == parent.getChildAt(position)
&& view == parent.getChildAt(position)
}
}
}

View file

@ -23,6 +23,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="com.dexcom.cgm.EXTERNAL_PERMISSION" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
@ -123,14 +124,6 @@
</intent-filter>
</receiver>
<!-- Network change local receiver -->
<receiver android:name=".receivers.NetworkChangeReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
</receiver>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
@ -264,6 +257,8 @@
<activity
android:name=".plugins.pump.insight.activities.InsightAlertActivity"
android:label="@string/pump_alert"
android:excludeFromRecents="true"
android:launchMode="singleInstance"
android:theme="@style/InsightAlertDialog" />
<activity
android:name=".plugins.pump.insight.activities.InsightPairingInformationActivity"

View file

@ -1,2 +1,4 @@
#Demo certificate
51:6D:12:67:4C:27:F4:9B:9F:E5:42:9B:01:B3:98:E4:66:2B:85:B7:A8:DD:70:32:B7:6A:D7:97:9A:0D:97:10
51:6D:12:67:4C:27:F4:9B:9F:E5:42:9B:01:B3:98:E4:66:2B:85:B7:A8:DD:70:32:B7:6A:D7:97:9A:0D:97:10
#Leaked
55:5D:70:C9:BE:10:41:7E:4B:01:A9:C4:C6:44:4A:F8:69:71:35:25:ED:95:23:16:C7:15:E8:EB:C6:08:FC:B1

View file

@ -63,6 +63,8 @@ import info.nightscout.androidaps.utils.SP;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import static info.nightscout.androidaps.utils.EspressoTestHelperKt.isRunningRealPumpTest;
public class MainActivity extends NoSplashAppCompatActivity {
private static Logger log = LoggerFactory.getLogger(L.CORE);
private CompositeDisposable disposable = new CompositeDisposable();
@ -137,7 +139,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
.subscribe(this::processPreferenceChange, FabricPrivacy::logException)
);
if (!SP.getBoolean(R.string.key_setupwizard_processed, false)) {
if (!SP.getBoolean(R.string.key_setupwizard_processed, false) && !isRunningRealPumpTest()) {
Intent intent = new Intent(this, SetupWizardActivity.class);
startActivity(intent);
}
@ -147,6 +149,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
if (Config.PUMPDRIVERS) {
AndroidPermission.notifyForLocationPermissions(this);
AndroidPermission.notifyForSMSPermissions(this);
AndroidPermission.notifyForSystemWindowPermissions(this);
}
}
@ -245,6 +248,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
case AndroidPermission.CASE_SMS:
case AndroidPermission.CASE_BATTERY:
case AndroidPermission.CASE_PHONE_STATE:
case AndroidPermission.CASE_SYSTEM_WINDOW:
break;
}
}

View file

@ -1,8 +1,11 @@
package info.nightscout.androidaps;
import android.app.Application;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
import android.os.SystemClock;
import androidx.annotation.ColorRes;
@ -85,9 +88,11 @@ import info.nightscout.androidaps.plugins.source.SourcePoctechPlugin;
import info.nightscout.androidaps.plugins.source.SourceTomatoPlugin;
import info.nightscout.androidaps.plugins.source.SourceXdripPlugin;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.receivers.ChargingStateReceiver;
import info.nightscout.androidaps.receivers.DataReceiver;
import info.nightscout.androidaps.receivers.KeepAliveReceiver;
import info.nightscout.androidaps.receivers.NSAlarmReceiver;
import info.nightscout.androidaps.receivers.NetworkChangeReceiver;
import info.nightscout.androidaps.receivers.TimeDateOrTZChangeReceiver;
import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.utils.ActivityMonitor;
@ -294,6 +299,12 @@ public class MainApp extends Application {
this.timeDateOrTZChangeReceiver = new TimeDateOrTZChangeReceiver();
this.timeDateOrTZChangeReceiver.registerBroadcasts(this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION );
registerReceiver(new NetworkChangeReceiver(), intentFilter);
registerReceiver(new ChargingStateReceiver(), new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
public static String gs(@StringRes int id) {

View file

@ -68,6 +68,12 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this);
}
@Override
public void attachBaseContext(Context newBase) {
super.attachBaseContext(LocaleHelper.INSTANCE.wrap(newBase));

View file

@ -84,7 +84,7 @@ class SurveyActivity : NoSplashAppCompatActivity() {
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
log.debug("signInAnonymously:success")
val user = auth.currentUser // TODO: do we need this, seems unused?
// val user = auth.currentUser // TODO: do we need this, seems unused?
val database = FirebaseDatabase.getInstance().reference
database.child("survey").child(r.id).setValue(r)

View file

@ -41,79 +41,55 @@ public class DbRequest {
}
// dbAdd
public DbRequest(String action, String collection, JSONObject data) {
public DbRequest(String action, String collection, JSONObject json) {
this.action = action;
this.collection = collection;
this.nsClientID = "" + DateUtil.now();
try {
data.put("NSCLIENT_ID", nsClientID);
json.put("NSCLIENT_ID", nsClientID);
} catch (JSONException e) {
e.printStackTrace();
}
this.data = data.toString();
this.data = json.toString();
this._id = "";
}
// dbUpdate, dbUpdateUnset
public DbRequest(String action, String collection, String _id, JSONObject data) {
public DbRequest(String action, String collection, String _id, JSONObject json) {
this.action = action;
this.collection = collection;
this.nsClientID = "" + DateUtil.now();
try {
data.put("NSCLIENT_ID", nsClientID);
json.put("NSCLIENT_ID", nsClientID);
} catch (JSONException e) {
e.printStackTrace();
}
this.data = data.toString();
this.data = json.toString();
this._id = _id;
}
// dbRemove
public DbRequest(String action, String collection,
String _id) {
JSONObject data = new JSONObject();
JSONObject json = new JSONObject();
this.action = action;
this.collection = collection;
this.nsClientID = "" + DateUtil.now();
try {
data.put("NSCLIENT_ID", nsClientID);
json.put("NSCLIENT_ID", nsClientID);
} catch (JSONException e) {
e.printStackTrace();
}
this.data = data.toString();
this.data = json.toString();
this._id = _id;
}
public JSONObject toJSON() {
JSONObject object = new JSONObject();
try {
object.put("action", action);
object.put("collection", collection);
object.put("data", new JSONObject(data));
if (_id != null) object.put("_id", _id);
if (nsClientID != null) object.put("nsClientID", nsClientID);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return object;
}
public static DbRequest fromJSON(JSONObject jsonObject) {
DbRequest result = new DbRequest();
try {
if (jsonObject.has("action"))
result.action = jsonObject.getString("action");
if (jsonObject.has("collection"))
result.collection = jsonObject.getString("collection");
if (jsonObject.has("data"))
result.data = jsonObject.getJSONObject("data").toString();
if (jsonObject.has("_id"))
result._id = jsonObject.getString("_id");
if (jsonObject.has("nsClientID"))
result.nsClientID = jsonObject.getString("nsClientID");
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return result;
public String log() {
return
"\nnsClientID:" + nsClientID +
"\naction:" + action +
"\ncollection:" + collection +
"\ndata:" + data +
"\n_id:" + _id;
}
}

View file

@ -30,8 +30,10 @@ class BolusProgressDialog : DialogFragment() {
companion object {
private val DEFAULT_STATE = MainApp.gs(R.string.waitingforpump)
@JvmField
var bolusEnded = false
@JvmField
var stopPressed = false
}
@ -62,6 +64,9 @@ class BolusProgressDialog : DialogFragment() {
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
savedInstanceState?.let {
amount = it.getDouble("amount")
}
overview_bolusprogress_title.text = String.format(MainApp.gs(R.string.overview_bolusprogress_goingtodeliver), amount)
overview_bolusprogress_stop.setOnClickListener {
if (L.isEnabled(L.UI)) log.debug("Stop bolus delivery button pressed")
@ -136,6 +141,7 @@ class BolusProgressDialog : DialogFragment() {
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString("state", state)
outState.putDouble("amount", amount)
}
private fun scheduleDismiss() {

View file

@ -56,7 +56,8 @@ class CalibrationDialog : DialogFragmentWithDate() {
if (bg > 0) {
activity?.let { activity ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.overview_calibration), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
XdripCalibrations.confirmAndSendCalibration(bg, context)
log.debug("USER ENTRY: CALIBRATION $bg")
XdripCalibrations.sendIntent(bg)
})
}
} else
@ -65,4 +66,4 @@ class CalibrationDialog : DialogFragmentWithDate() {
}
return true
}
}
}

View file

@ -177,6 +177,7 @@ class CarbsDialog : DialogFragmentWithDate() {
activity?.let { activity ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.carbs), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
if (activitySelected) {
log.debug("USER ENTRY: TEMPTARGET ACTIVITY $activityTT duration: $activityTTDuration")
val tempTarget = TempTarget()
.date(eventTime)
.duration(activityTTDuration)
@ -186,6 +187,7 @@ class CarbsDialog : DialogFragmentWithDate() {
.high(Profile.toMgdl(activityTT, ProfileFunctions.getSystemUnits()))
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
} else if (eatingSoonSelected) {
log.debug("USER ENTRY: TEMPTARGET EATING SOON $eatingSoonTT duration: $eatingSoonTTDuration")
val tempTarget = TempTarget()
.date(eventTime)
.duration(eatingSoonTTDuration)
@ -195,6 +197,7 @@ class CarbsDialog : DialogFragmentWithDate() {
.high(Profile.toMgdl(eatingSoonTT, ProfileFunctions.getSystemUnits()))
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
} else if (hypoSelected) {
log.debug("USER ENTRY: TEMPTARGET HYPO $hypoTT duration: $hypoTTDuration")
val tempTarget = TempTarget()
.date(eventTime)
.duration(hypoTTDuration)
@ -206,8 +209,10 @@ class CarbsDialog : DialogFragmentWithDate() {
}
if (carbsAfterConstraints > 0) {
if (duration == 0) {
log.debug("USER ENTRY: CARBS $carbsAfterConstraints time: $time")
CarbsGenerator.createCarb(carbsAfterConstraints, time, CareportalEvent.CARBCORRECTION, notes)
} else {
log.debug("USER ENTRY: CARBS $carbsAfterConstraints time: $time duration: $duration")
CarbsGenerator.generateCarbs(carbsAfterConstraints, time, duration, notes)
NSUpload.uploadEvent(CareportalEvent.NOTE, time - 2000, MainApp.gs(R.string.generated_ecarbs_note, carbsAfterConstraints, duration, timeOffset))
}

View file

@ -54,6 +54,8 @@ class CareDialog : DialogFragmentWithDate() {
super.onSaveInstanceState(savedInstanceState)
savedInstanceState.putDouble("actions_care_bg", actions_care_bg.value)
savedInstanceState.putDouble("actions_care_duration", actions_care_duration.value)
savedInstanceState.putInt("event", event)
savedInstanceState.putInt("options", options.ordinal)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
@ -65,6 +67,11 @@ class CareDialog : DialogFragmentWithDate() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
savedInstanceState?.let {
event = savedInstanceState.getInt("event", R.string.error)
options = EventType.values()[savedInstanceState.getInt("options", 0)]
}
actions_care_icon.setImageResource(when (options) {
EventType.BGCHECK -> R.drawable.icon_cp_bgcheck
EventType.SENSOR_INSERT -> R.drawable.icon_cp_cgm_insert
@ -180,6 +187,7 @@ class CareDialog : DialogFragmentWithDate() {
EventType.EXERCISE -> CareportalEvent.EXERCISE
}
careportalEvent.json = json.toString()
log.debug("USER ENTRY: CAREPORTAL ${careportalEvent.eventType} json: ${careportalEvent.json}")
MainApp.getDbHelper().createOrUpdate(careportalEvent)
NSUpload.uploadCareportalEntryToNS(json)
}, null)

View file

@ -20,7 +20,7 @@ import org.slf4j.LoggerFactory
import java.util.*
abstract class DialogFragmentWithDate : DialogFragment() {
private val log = LoggerFactory.getLogger(DialogFragmentWithDate::class.java)
val log = LoggerFactory.getLogger(DialogFragmentWithDate::class.java)
var eventTime = DateUtil.now()
var eventTimeChanged = false

View file

@ -36,6 +36,7 @@ class ErrorDialog : DialogFragment() {
bundle.getString("title")?.let { title = it }
sound = bundle.getInt("sound", R.raw.error)
}
log.debug("Error dialog displayed")
return inflater.inflate(R.layout.dialog_error, container, false)
}
@ -44,11 +45,11 @@ class ErrorDialog : DialogFragment() {
error_title.text = title
overview_error_ok.setOnClickListener {
log.debug("Error dialog ok button pressed")
log.debug("USER ENTRY: Error dialog ok button pressed")
dismiss()
}
overview_error_mute.setOnClickListener {
log.debug("Error dialog mute button pressed")
log.debug("USER ENTRY: Error dialog mute button pressed")
stopAlarm()
}
startAlarm()

View file

@ -63,6 +63,7 @@ class ExtendedBolusDialog : DialogFragmentWithDate() {
activity?.let { activity ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.extended_bolus), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
log.debug("USER ENTRY: EXTENDED BOLUS $insulinAfterConstraint duration: $durationInMinutes")
ConfigBuilderPlugin.getPlugin().commandQueue.extendedBolus(insulinAfterConstraint, durationInMinutes, object : Callback() {
override fun run() {
if (!result.success) {

View file

@ -102,13 +102,16 @@ class FillDialog : DialogFragmentWithDate() {
activity?.let { activity ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.primefill), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
if (insulinAfterConstraints > 0) {
log.debug("USER ENTRY: PRIME BOLUS $insulinAfterConstraints")
requestPrimeBolus(insulinAfterConstraints, notes)
}
if (siteChange) {
log.debug("USER ENTRY: SITE CHANGE")
generateCareportalEvent(CareportalEvent.SITECHANGE, eventTime, notes)
}
if (insulinChange) {
// add a second for case of both checked
log.debug("USER ENTRY: INSULIN CHANGE")
generateCareportalEvent(CareportalEvent.INSULINCHANGE, eventTime + 1000, notes)
}
}, null)

View file

@ -147,6 +147,7 @@ class InsulinDialog : DialogFragmentWithDate() {
activity?.let { activity ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.bolus), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
if (eatingSoonChecked) {
log.debug("USER ENTRY: TEMPTARGET EATING SOON $eatingSoonTT duration: $eatingSoonTTDuration")
val tempTarget = TempTarget()
.date(System.currentTimeMillis())
.duration(eatingSoonTTDuration)
@ -164,9 +165,11 @@ class InsulinDialog : DialogFragmentWithDate() {
detailedBolusInfo.source = Source.USER
detailedBolusInfo.notes = notes
if (recordOnlyChecked) {
log.debug("USER ENTRY: BOLUS RECORD ONLY $insulinAfterConstraints")
detailedBolusInfo.date = time
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false)
} else {
log.debug("USER ENTRY: BOLUS $insulinAfterConstraints")
detailedBolusInfo.date = DateUtil.now()
ConfigBuilderPlugin.getPlugin().commandQueue.bolus(detailedBolusInfo, object : Callback() {
override fun run() {

View file

@ -78,9 +78,9 @@ class ProfileSwitchDialog : DialogFragmentWithDate() {
?: return false
val actions: LinkedList<String> = LinkedList()
val duration = overview_profileswitch_duration.value
val duration = overview_profileswitch_duration.value.toInt()
if (duration > 0)
actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_hours, duration))
actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_mins, duration))
val profile = overview_profileswitch_profile.selectedItem.toString()
actions.add(MainApp.gs(R.string.profile) + ": " + profile)
val percent = overview_profileswitch_percentage.value.toInt()
@ -97,7 +97,8 @@ class ProfileSwitchDialog : DialogFragmentWithDate() {
activity?.let { activity ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.careportal_profileswitch), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
ProfileFunctions.doProfileSwitch(profileStore, profile, duration.toInt(), percent, timeShift, eventTime)
log.debug("USER ENTRY: PROFILE SWITCH $profile percent: $percent timeshift: $timeShift duration: $duration")
ProfileFunctions.doProfileSwitch(profileStore, profile, duration, percent, timeShift, eventTime)
})
}
return true

View file

@ -104,8 +104,10 @@ class TempBasalDialog : DialogFragmentWithDate() {
}
}
if (isPercentPump) {
log.debug("USER ENTRY: TEMP BASAL $percent% duration: $durationInMinutes")
ConfigBuilderPlugin.getPlugin().commandQueue.tempBasalPercent(percent, durationInMinutes, true, profile, callback)
} else {
log.debug("USER ENTRY: TEMP BASAL $absolute duration: $durationInMinutes")
ConfigBuilderPlugin.getPlugin().commandQueue.tempBasalAbsolute(absolute, durationInMinutes, true, profile, callback)
}
})

View file

@ -114,11 +114,11 @@ class TempTargetDialog : DialogFragmentWithDate() {
val reason = overview_temptarget_reason.selectedItem.toString()
val unitResId = if (ProfileFunctions.getSystemUnits() == Constants.MGDL) R.string.mgdl else R.string.mmol
val target = overview_temptarget_temptarget.value
val duration = overview_temptarget_duration.value
if (target != 0.0 && duration != 0.0) {
val duration = overview_temptarget_duration.value.toInt()
if (target != 0.0 && duration != 0) {
actions.add(MainApp.gs(R.string.reason) + ": " + reason)
actions.add(MainApp.gs(R.string.nsprofileview_target_label) + ": " + Profile.toCurrentUnitsString(target) + " " + MainApp.gs(unitResId))
actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_hours, duration))
actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_mins, duration))
} else {
actions.add(MainApp.gs(R.string.stoptemptarget))
}
@ -127,7 +127,8 @@ class TempTargetDialog : DialogFragmentWithDate() {
activity?.let { activity ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.careportal_temporarytarget), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
if (target == 0.0 || duration == 0.0) {
log.debug("USER ENTRY: TEMP TARGET $target duration: $duration")
if (target == 0.0 || duration == 0) {
val tempTarget = TempTarget()
.date(eventTime)
.duration(0)
@ -144,7 +145,7 @@ class TempTargetDialog : DialogFragmentWithDate() {
.high(Profile.toMgdl(target, ProfileFunctions.getSystemUnits()))
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
}
if (duration == 10.0) SP.putBoolean(R.string.key_objectiveusetemptarget, true)
if (duration == 10) SP.putBoolean(R.string.key_objectiveusetemptarget, true)
})
}
return true

View file

@ -99,6 +99,7 @@ class TreatmentDialog : DialogFragmentWithDate() {
if (insulinAfterConstraints > 0 || carbsAfterConstraints > 0) {
activity?.let { activity ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.overview_treatment_label), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
log.debug("USER ENTRY: BOLUS insulin $insulin carbs: $carbs")
val detailedBolusInfo = DetailedBolusInfo()
if (insulinAfterConstraints == 0.0) detailedBolusInfo.eventType = CareportalEvent.CARBCORRECTION
if (carbsAfterConstraints == 0) detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS

View file

@ -74,7 +74,7 @@ public abstract class PluginBase {
}
}
private void performPluginSwitch(boolean enabled, PluginType type) {
public void performPluginSwitch(boolean enabled, PluginType type) {
setPluginEnabled(type, enabled);
setFragmentVisible(type, enabled);
ConfigBuilderPlugin.getPlugin().processOnEnabledCategoryChanged(this, getType());

View file

@ -77,8 +77,11 @@ class LoopFragment : Fragment() {
loop_source?.text = it.source ?: ""
loop_lastrun?.text = it.lastAPSRun?.let { lastRun -> DateUtil.dateAndTimeString(lastRun.time) }
?: ""
loop_lastenact?.text = it.lastAPSRun?.let { lastEnact -> DateUtil.dateAndTimeString(lastEnact.time) }
?: ""
loop_smbrequest_time?.text = DateUtil.dateAndTimeAndSecondsString(it.lastSMBRequest)
loop_smbexecution_time?.text = DateUtil.dateAndTimeAndSecondsString(it.lastSMBEnact)
loop_tbrrequest_time?.text = DateUtil.dateAndTimeAndSecondsString(it.lastTBRRequest)
loop_tbrexecution_time?.text = DateUtil.dateAndTimeAndSecondsString(it.lastTBREnact)
loop_tbrsetbypump?.text = it.tbrSetByPump?.let { tbrSetByPump -> HtmlHelper.fromHtml(tbrSetByPump.toHtml()) }
?: ""
loop_smbsetbypump?.text = it.smbSetByPump?.let { smbSetByPump -> HtmlHelper.fromHtml(smbSetByPump.toHtml()) }
@ -102,7 +105,10 @@ class LoopFragment : Fragment() {
loop_constraintsprocessed?.text = ""
loop_source?.text = ""
loop_lastrun?.text = ""
loop_lastenact?.text = ""
loop_smbrequest_time?.text = ""
loop_smbexecution_time?.text = ""
loop_tbrrequest_time?.text = ""
loop_tbrexecution_time?.text = ""
loop_tbrsetbypump?.text = ""
loop_smbsetbypump?.text = ""
}

View file

@ -14,6 +14,8 @@ import android.os.SystemClock;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -57,6 +59,7 @@ import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.queue.commands.Command;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.T;
@ -84,9 +87,9 @@ public class LoopPlugin extends PluginBase {
return loopPlugin;
}
private long loopSuspendedTill = 0L; // end of manual loop suspend
private boolean isSuperBolus = false;
private boolean isDisconnected = false;
private long loopSuspendedTill; // end of manual loop suspend
private boolean isSuperBolus;
private boolean isDisconnected;
public class LastRun {
public APSResult request = null;
@ -95,8 +98,11 @@ public class LoopPlugin extends PluginBase {
public PumpEnactResult smbSetByPump = null;
public String source = null;
public Date lastAPSRun = null;
public Date lastEnact = null;
public Date lastOpenModeAccept;
public long lastTBREnact = 0;
public long lastSMBEnact = 0;
public long lastTBRRequest = 0;
public long lastSMBRequest = 0;
public long lastOpenModeAccept;
}
static public LastRun lastRun = null;
@ -342,6 +348,10 @@ public class LoopPlugin extends PluginBase {
lastRun.source = ((PluginBase) usedAPS).getName();
lastRun.tbrSetByPump = null;
lastRun.smbSetByPump = null;
lastRun.lastTBREnact = 0;
lastRun.lastTBRRequest = 0;
lastRun.lastSMBEnact = 0;
lastRun.lastSMBRequest = 0;
NSUpload.uploadDeviceStatus();
@ -378,14 +388,17 @@ public class LoopPlugin extends PluginBase {
public void run() {
if (result.enacted || result.success) {
lastRun.tbrSetByPump = result;
lastRun.lastEnact = lastRun.lastAPSRun;
lastRun.lastTBRRequest = lastRun.lastAPSRun.getTime();
lastRun.lastTBREnact = DateUtil.now();
RxBus.INSTANCE.send(new EventLoopUpdateGui());
applySMBRequest(resultAfterConstraints, new Callback() {
@Override
public void run() {
//Callback is only called if a bolus was acutally requested
if (result.enacted || result.success) {
lastRun.smbSetByPump = result;
lastRun.lastEnact = lastRun.lastAPSRun;
lastRun.lastSMBRequest = lastRun.lastAPSRun.getTime();
lastRun.lastSMBEnact = DateUtil.now();
} else {
new Thread(() -> {
SystemClock.sleep(1000);
@ -465,8 +478,9 @@ public class LoopPlugin extends PluginBase {
public void run() {
if (result.enacted) {
lastRun.tbrSetByPump = result;
lastRun.lastEnact = new Date();
lastRun.lastOpenModeAccept = new Date();
lastRun.lastTBRRequest = lastRun.lastAPSRun.getTime();
lastRun.lastTBREnact = DateUtil.now();
lastRun.lastOpenModeAccept = DateUtil.now();
NSUpload.uploadDeviceStatus();
SP.incInt(R.string.key_ObjectivesmanualEnacts);
}
@ -685,7 +699,7 @@ public class LoopPlugin extends PluginBase {
}
});
}
NSUpload.uploadOpenAPSOffline(durationInMinutes);
createOfflineEvent(durationInMinutes);
}
public void suspendLoop(int durationInMinutes) {
@ -703,7 +717,23 @@ public class LoopPlugin extends PluginBase {
}
}
});
NSUpload.uploadOpenAPSOffline(durationInMinutes);
createOfflineEvent(durationInMinutes);
}
public void createOfflineEvent(int durationInMinutes) {
JSONObject data = new JSONObject();
try {
data.put("eventType", CareportalEvent.OPENAPSOFFLINE);
data.put("duration", durationInMinutes);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
CareportalEvent event = new CareportalEvent();
event.date = DateUtil.now();
event.source = Source.USER;
event.eventType = CareportalEvent.OPENAPSOFFLINE;
event.json = data.toString();
MainApp.getDbHelper().createOrUpdate(event);
NSUpload.uploadOpenAPSOffline(event);
}
}

View file

@ -27,6 +27,7 @@ import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment
import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.dialogs.ProfileSwitchDialog
import info.nightscout.androidaps.dialogs.TempTargetDialog
import info.nightscout.androidaps.logging.L
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.*
@ -34,9 +35,11 @@ import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.actions_fragment.*
import kotlinx.android.synthetic.main.careportal_stats_fragment.*
import org.slf4j.LoggerFactory
import java.util.*
class ActionsFragment : Fragment() {
private val log = LoggerFactory.getLogger(L.CORE)
private var disposable: CompositeDisposable = CompositeDisposable()
@ -67,6 +70,7 @@ class ActionsFragment : Fragment() {
}
actions_extendedbolus_cancel.setOnClickListener {
if (TreatmentsPlugin.getPlugin().isInHistoryExtendedBoluslInProgress) {
log.debug("USER ENTRY: CANCEL EXTENDED BOLUS")
ConfigBuilderPlugin.getPlugin().commandQueue.cancelExtended(object : Callback() {
override fun run() {
if (!result.success) {
@ -86,6 +90,7 @@ class ActionsFragment : Fragment() {
}
actions_canceltempbasal.setOnClickListener {
if (TreatmentsPlugin.getPlugin().isTempBasalInProgress) {
log.debug("USER ENTRY: CANCEL TEMP BASAL")
ConfigBuilderPlugin.getPlugin().commandQueue.cancelTempBasal(true, object : Callback() {
override fun run() {
if (!result.success) {

View file

@ -28,7 +28,7 @@ public class ActionLoopResume extends Action {
if (LoopPlugin.getPlugin().isSuspended()) {
LoopPlugin.getPlugin().suspendTo(0);
ConfigBuilderPlugin.getPlugin().storeSettings("ActionLoopResume");
NSUpload.uploadOpenAPSOffline(0);
LoopPlugin.getPlugin().createOfflineEvent(0);
RxBus.INSTANCE.send(new EventRefreshOverview("ActionLoopResume"));
if (callback != null)
callback.result(new PumpEnactResult().success(true).comment(R.string.ok)).run();

View file

@ -44,11 +44,11 @@ class EditActionDialog : DialogFragmentWithDate() {
return true
}
override fun onSaveInstanceState(bundle: Bundle) {
super.onSaveInstanceState(bundle)
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
action?.let {
bundle.putInt("actionPosition", actionPosition)
bundle.putString("action", it.toJSON())
savedInstanceState.putInt("actionPosition", actionPosition)
savedInstanceState.putString("action", it.toJSON())
}
}
}

View file

@ -323,7 +323,9 @@ public class NSUpload {
prebolus.put("created_at", DateUtil.toISOString(preBolusDate));
uploadCareportalEntryToNS(prebolus);
}
UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
DbRequest dbr = new DbRequest("dbAdd", "treatments", data);
log.debug("Prepared: " + dbr.log());
UploadQueue.add(dbr);
} catch (Exception e) {
log.error("Unhandled exception", e);
}
@ -334,12 +336,10 @@ public class NSUpload {
UploadQueue.add(new DbRequest("dbRemove", "treatments", _id));
}
public static void uploadOpenAPSOffline(double durationInMinutes) {
public static void uploadOpenAPSOffline(CareportalEvent event) {
try {
JSONObject data = new JSONObject();
data.put("eventType", "OpenAPS Offline");
data.put("duration", durationInMinutes);
data.put("created_at", DateUtil.toISOString(new Date()));
JSONObject data = new JSONObject(event.json);
data.put("created_at", DateUtil.toISOString(event.date));
data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name));
UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
} catch (JSONException e) {
@ -396,7 +396,7 @@ public class NSUpload {
public static void uploadProfileStore(JSONObject profileStore) {
if (SP.getBoolean(R.string.key_ns_uploadlocalprofile, false)) {
UploadQueue.add(new DbRequest("dbAdd", "profile", String.valueOf(profileStore)));
UploadQueue.add(new DbRequest("dbAdd", "profile", profileStore));
}
}

View file

@ -14,10 +14,12 @@ import org.slf4j.LoggerFactory;
import java.sql.SQLException;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.db.DbRequest;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.general.nsclient.services.NSClientService;
import info.nightscout.androidaps.utils.SP;
/**
* Created by mike on 21.02.2016.
@ -42,31 +44,22 @@ public class UploadQueue {
}
public static void add(final DbRequest dbr) {
if (SP.getBoolean(R.string.key_ns_noupload, false)) return;
startService();
if (NSClientService.handler != null) {
NSClientService.handler.post(() -> {
if (L.isEnabled(L.NSCLIENT))
log.debug("Adding to queue: " + dbr.data);
try {
MainApp.getDbHelper().create(dbr);
} catch (Exception e) {
log.error("Unhandled exception", e);
dbr.nsClientID += "1";
try {
MainApp.getDbHelper().create(dbr);
} catch (Exception e1) {
log.error("Unhandled exception", e1);
}
}
NSClientPlugin plugin = NSClientPlugin.getPlugin();
if (plugin != null) {
plugin.resend("newdata");
}
});
if (L.isEnabled(L.NSCLIENT))
log.debug("Adding to queue: " + dbr.log());
try {
MainApp.getDbHelper().create(dbr);
} catch (Exception e) {
log.error("Unhandled exception", e);
}
NSClientPlugin plugin = NSClientPlugin.getPlugin();
if (plugin != null) {
plugin.resend("newdata");
}
}
public static void clearQueue() {
static void clearQueue() {
startService();
if (NSClientService.handler != null) {
NSClientService.handler.post(() -> {
@ -114,7 +107,7 @@ public class UploadQueue {
}
}
public String textList() {
String textList() {
String result = "";
CloseableIterator<DbRequest> iterator;
try {

View file

@ -274,7 +274,7 @@ public class NSClientService extends Service {
} else if (!nsEnabled) {
RxBus.INSTANCE.send(new EventNSClientNewLog("NSCLIENT", "disabled"));
RxBus.INSTANCE.send(new EventNSClientStatus("Disabled"));
} else if (!nsURL.equals("")) {
} else if (!nsURL.equals("") && (MainApp.engineeringMode || nsURL.toLowerCase().startsWith("https://"))) {
try {
RxBus.INSTANCE.send(new EventNSClientStatus("Connecting ..."));
IO.Options opt = new IO.Options();
@ -283,6 +283,9 @@ public class NSClientService extends Service {
mSocket = IO.socket(nsURL, opt);
mSocket.on(Socket.EVENT_CONNECT, onConnect);
mSocket.on(Socket.EVENT_DISCONNECT, onDisconnect);
mSocket.on(Socket.EVENT_ERROR, onError);
mSocket.on(Socket.EVENT_CONNECT_ERROR, onError);
mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, onError);
mSocket.on(Socket.EVENT_PING, onPing);
RxBus.INSTANCE.send(new EventNSClientNewLog("NSCLIENT", "do connect"));
mSocket.connect();
@ -295,6 +298,9 @@ public class NSClientService extends Service {
RxBus.INSTANCE.send(new EventNSClientNewLog("NSCLIENT", "Wrong URL syntax"));
RxBus.INSTANCE.send(new EventNSClientStatus("Wrong URL syntax"));
}
} else if (nsURL.toLowerCase().startsWith("http://")) {
RxBus.INSTANCE.send(new EventNSClientNewLog("NSCLIENT", "NS URL not encrypted"));
RxBus.INSTANCE.send(new EventNSClientStatus("Not encrypted"));
} else {
RxBus.INSTANCE.send(new EventNSClientNewLog("NSCLIENT", "No NS URL specified"));
RxBus.INSTANCE.send(new EventNSClientStatus("Not configured"));
@ -392,6 +398,17 @@ public class NSClientService extends Service {
nsDevice = SP.getString("careportal_enteredby", "");
}
private Emitter.Listener onError = new Emitter.Listener() {
@Override
public void call(final Object... args) {
String msg = "Unknown Error";
if (args.length > 0 && args[0] != null) {
msg = args[0].toString();
}
RxBus.INSTANCE.send(new EventNSClientNewLog("ERROR", msg));
}
};
private Emitter.Listener onPing = new Emitter.Listener() {
@Override
public void call(final Object... args) {

View file

@ -221,8 +221,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
} else if (Config.NSCLIENT) {
view = inflater.inflate(R.layout.overview_fragment_nsclient, container, false);
shorttextmode = true;
} else if (smallHeight || landscape) { // now testing the same layout for small displays as well
view = inflater.inflate(R.layout.overview_fragment, container, false);
} else if (smallHeight || landscape) {
view = inflater.inflate(R.layout.overview_fragment_landscape, container, false);
} else {
view = inflater.inflate(R.layout.overview_fragment, container, false);
}
@ -667,6 +667,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
return true;
final LoopPlugin loopPlugin = LoopPlugin.getPlugin();
if (item.getTitle().equals(MainApp.gs(R.string.disableloop))) {
log.debug("USER ENTRY: LOOP DISABLED");
loopPlugin.setPluginEnabled(PluginType.LOOP, false);
loopPlugin.setFragmentVisible(PluginType.LOOP, false);
ConfigBuilderPlugin.getPlugin().storeSettings("DisablingLoop");
@ -679,17 +680,19 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
}
}
});
NSUpload.uploadOpenAPSOffline(24 * 60); // upload 24h, we don't know real duration
LoopPlugin.getPlugin().createOfflineEvent(24 * 60); // upload 24h, we don't know real duration
return true;
} else if (item.getTitle().equals(MainApp.gs(R.string.enableloop))) {
log.debug("USER ENTRY: LOOP ENABLED");
loopPlugin.setPluginEnabled(PluginType.LOOP, true);
loopPlugin.setFragmentVisible(PluginType.LOOP, true);
ConfigBuilderPlugin.getPlugin().storeSettings("EnablingLoop");
updateGUI("suspendmenu");
NSUpload.uploadOpenAPSOffline(0);
LoopPlugin.getPlugin().createOfflineEvent(0);
return true;
} else if (item.getTitle().equals(MainApp.gs(R.string.resume)) ||
item.getTitle().equals(MainApp.gs(R.string.reconnect))) {
log.debug("USER ENTRY: RESUME");
loopPlugin.suspendTo(0L);
updateGUI("suspendmenu");
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() {
@ -701,42 +704,51 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
}
});
SP.putBoolean(R.string.key_objectiveusereconnect, true);
NSUpload.uploadOpenAPSOffline(0);
LoopPlugin.getPlugin().createOfflineEvent(0);
return true;
} else if (item.getTitle().equals(MainApp.gs(R.string.suspendloopfor1h))) {
log.debug("USER ENTRY: SUSPEND 1h");
LoopPlugin.getPlugin().suspendLoop(60);
updateGUI("suspendmenu");
return true;
} else if (item.getTitle().equals(MainApp.gs(R.string.suspendloopfor2h))) {
log.debug("USER ENTRY: SUSPEND 2h");
LoopPlugin.getPlugin().suspendLoop(120);
updateGUI("suspendmenu");
return true;
} else if (item.getTitle().equals(MainApp.gs(R.string.suspendloopfor3h))) {
log.debug("USER ENTRY: SUSPEND 3h");
LoopPlugin.getPlugin().suspendLoop(180);
updateGUI("suspendmenu");
return true;
} else if (item.getTitle().equals(MainApp.gs(R.string.suspendloopfor10h))) {
log.debug("USER ENTRY: SUSPEND 10h");
LoopPlugin.getPlugin().suspendLoop(600);
updateGUI("suspendmenu");
return true;
} else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor15m))) {
log.debug("USER ENTRY: DISCONNECT 15m");
LoopPlugin.getPlugin().disconnectPump(15, profile);
updateGUI("suspendmenu");
return true;
} else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor30m))) {
log.debug("USER ENTRY: DISCONNECT 30m");
LoopPlugin.getPlugin().disconnectPump(30, profile);
updateGUI("suspendmenu");
return true;
} else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor1h))) {
log.debug("USER ENTRY: DISCONNECT 1h");
LoopPlugin.getPlugin().disconnectPump(60, profile);
SP.putBoolean(R.string.key_objectiveusedisconnect, true);
updateGUI("suspendmenu");
return true;
} else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor2h))) {
log.debug("USER ENTRY: DISCONNECT 2h");
LoopPlugin.getPlugin().disconnectPump(120, profile);
updateGUI("suspendmenu");
return true;
} else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor3h))) {
log.debug("USER ENTRY: DISCONNECT 3h");
LoopPlugin.getPlugin().disconnectPump(180, profile);
updateGUI("suspendmenu");
return true;
@ -754,6 +766,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
if (manager != null)
pvd.show(manager, "ProfileViewDialog");
} else if (item.getTitle().equals(MainApp.gs(R.string.eatingsoon))) {
log.debug("USER ENTRY: TEMP TARGET EATING SOON");
double target = Profile.toMgdl(DefaultValueHelper.determineEatingSoonTT(), ProfileFunctions.getSystemUnits());
TempTarget tempTarget = new TempTarget()
.date(System.currentTimeMillis())
@ -764,6 +777,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
.high(target);
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
} else if (item.getTitle().equals(MainApp.gs(R.string.activity))) {
log.debug("USER ENTRY: TEMP TARGET ACTIVITY");
double target = Profile.toMgdl(DefaultValueHelper.determineActivityTT(), ProfileFunctions.getSystemUnits());
TempTarget tempTarget = new TempTarget()
.date(now())
@ -774,6 +788,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
.high(target);
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
} else if (item.getTitle().equals(MainApp.gs(R.string.hypo))) {
log.debug("USER ENTRY: TEMP TARGET HYPO");
double target = Profile.toMgdl(DefaultValueHelper.determineHypoTT(), ProfileFunctions.getSystemUnits());
TempTarget tempTarget = new TempTarget()
.date(now())
@ -788,6 +803,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
if (manager != null)
new TempTargetDialog().show(manager, "Overview");
} else if (item.getTitle().equals(MainApp.gs(R.string.cancel))) {
log.debug("USER ENTRY: TEMP TARGET CANCEL");
TempTarget tempTarget = new TempTarget()
.source(Source.USER)
.date(now())
@ -907,6 +923,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
if (finalLastRun != null && finalLastRun.lastAPSRun != null && finalLastRun.constraintsProcessed.isChangeRequested()) {
OKDialog.showConfirmation(context, MainApp.gs(R.string.pump_tempbasal_label), finalLastRun.constraintsProcessed.toSpanned(), () -> {
log.debug("USER ENTRY: ACCEPT TEMP BASAL");
hideTempRecommendation();
clearNotification();
LoopPlugin.getPlugin().acceptChangeRequest();
@ -1113,7 +1130,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
if (acceptTempButton != null) {
boolean showAcceptButton = !closedLoopEnabled.value(); // Open mode needed
showAcceptButton = showAcceptButton && finalLastRun != null && finalLastRun.lastAPSRun != null; // aps result must exist
showAcceptButton = showAcceptButton && (finalLastRun.lastOpenModeAccept == null || finalLastRun.lastOpenModeAccept.getTime() < finalLastRun.lastAPSRun.getTime()); // never accepted or before last result
showAcceptButton = showAcceptButton && (finalLastRun.lastOpenModeAccept == 0 || finalLastRun.lastOpenModeAccept < finalLastRun.lastAPSRun.getTime()); // never accepted or before last result
showAcceptButton = showAcceptButton && finalLastRun.constraintsProcessed.isChangeRequested(); // change is requested
if (showAcceptButton && pump.isInitialized() && !pump.isSuspended() && LoopPlugin.getPlugin().isEnabled(PluginType.LOOP)) {

View file

@ -78,6 +78,7 @@ public class Notification {
public static final int USERMESSAGE = 53;
public static final int OVER_24H_TIME_CHANGE_REQUESTED = 54;
public static final int INVALID_VERSION = 55;
public static final int PERMISSION_SYSTEM_WINDOW = 56;
public int id;

View file

@ -330,7 +330,7 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
"RESUME" -> {
LoopPlugin.getPlugin().suspendTo(0)
send(EventRefreshOverview("SMS_LOOP_RESUME"))
NSUpload.uploadOpenAPSOffline(0.0)
LoopPlugin.getPlugin().createOfflineEvent(0)
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, R.string.smscommunicator_loopresumed))
}
"SUSPEND" -> {
@ -352,7 +352,7 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
override fun run() {
if (result.success) {
LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + anInteger() * 60L * 1000)
NSUpload.uploadOpenAPSOffline(anInteger() * 60.toDouble())
LoopPlugin.getPlugin().createOfflineEvent(anInteger() * 60)
send(EventRefreshOverview("SMS_LOOP_SUSPENDED"))
val replyText = MainApp.gs(R.string.smscommunicator_loopsuspended) + " " +
MainApp.gs(if (result.success) R.string.smscommunicator_tempbasalcanceled else R.string.smscommunicator_tempbasalcancelfailed)

View file

@ -502,8 +502,8 @@ public class ActionStringHandler {
if (LoopPlugin.lastRun.lastAPSRun != null)
ret += "\nLast Run: " + DateUtil.timeString(LoopPlugin.lastRun.lastAPSRun);
if (LoopPlugin.lastRun.lastEnact != null)
ret += "\nLast Enact: " + DateUtil.timeString(LoopPlugin.lastRun.lastEnact);
if (LoopPlugin.lastRun.lastTBREnact != 0)
ret += "\nLast Enact: " + DateUtil.timeString(LoopPlugin.lastRun.lastTBREnact);
}

View file

@ -735,7 +735,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
//OpenAPS status
if (Config.APS) {
//we are AndroidAPS
openApsStatus = LoopPlugin.lastRun != null && LoopPlugin.lastRun.lastEnact != null && LoopPlugin.lastRun.lastEnact.getTime() != 0 ? LoopPlugin.lastRun.lastEnact.getTime() : -1;
openApsStatus = LoopPlugin.lastRun != null && LoopPlugin.lastRun.lastTBREnact != 0 ? LoopPlugin.lastRun.lastTBREnact : -1;
} else {
//NSClient or remote
openApsStatus = NSDeviceStatus.getOpenApsTimestamp();

View file

@ -202,13 +202,13 @@ public class StatuslinePlugin extends PluginBase {
+ DecimalFormatter.to2Decimal(basalIob.basaliob) + ")";
}
if (!mPrefs.getBoolean("xdripstatus_showbgi", false)) {
return status;
// BGI
if (mPrefs.getBoolean("xdripstatus_showbgi", true)) {
double bgi = -(bolusIob.activity + basalIob.activity) * 5 * Profile.fromMgdlToUnits(profile.getIsfMgdl(), ProfileFunctions.getSystemUnits());
status += " " + ((bgi >= 0) ? "+" : "") + DecimalFormatter.to2Decimal(bgi);
}
double bgi = -(bolusIob.activity + basalIob.activity) * 5 * Profile.fromMgdlToUnits(profile.getIsfMgdl(), ProfileFunctions.getSystemUnits());
status += " " + ((bgi >= 0) ? "+" : "") + DecimalFormatter.to2Decimal(bgi);
/* COB */
status += " " + IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "StatuslinePlugin").generateCOBString();
return status;

View file

@ -654,16 +654,29 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
* Creates a treatment record based on the request in DetailBolusInfo and the delivered bolus.
*/
private boolean addBolusToTreatments(DetailedBolusInfo detailedBolusInfo, Bolus lastPumpBolus) {
DetailedBolusInfo dbi = detailedBolusInfo.copy();
dbi.date = calculateFakeBolusDate(lastPumpBolus);
dbi.pumpId = dbi.date;
dbi.source = Source.PUMP;
dbi.insulin = lastPumpBolus.amount;
DetailedBolusInfo bolusInfo = detailedBolusInfo.copy();
bolusInfo.date = calculateFakeBolusDate(lastPumpBolus);
bolusInfo.pumpId = bolusInfo.date;
bolusInfo.source = Source.PUMP;
bolusInfo.insulin = lastPumpBolus.amount;
try {
TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi, true);
if (bolusInfo.carbs > 0 && bolusInfo.carbTime != 0) {
// split out a separate carbs record without a pumpId
DetailedBolusInfo carbInfo = new DetailedBolusInfo();
carbInfo.date = bolusInfo.date + bolusInfo.carbTime * 60L * 1000L;
carbInfo.carbs = bolusInfo.carbs;
carbInfo.source = Source.USER;
TreatmentsPlugin.getPlugin().addToHistoryTreatment(carbInfo, true);
// remove carbs from bolusInfo to not trigger any unwanted code paths in
// TreatmentsPlugin.addToHistoryTreatment() method
bolusInfo.carbTime = 0;
bolusInfo.carbs = 0;
}
TreatmentsPlugin.getPlugin().addToHistoryTreatment(bolusInfo, true);
} catch (Exception e) {
log.error("Adding treatment record failed", e);
if (dbi.isSMB) {
if (bolusInfo.isSMB) {
Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, MainApp.gs(R.string.combo_error_updating_treatment_record), Notification.URGENT);
RxBus.INSTANCE.send(new EventNewNotification(notification));
}

View file

@ -2,7 +2,6 @@ package info.nightscout.androidaps.plugins.pump.common.bolusInfo
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.logging.L
import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryData
import info.nightscout.androidaps.utils.T
import org.slf4j.LoggerFactory
import java.util.*
@ -20,10 +19,6 @@ object DetailedBolusInfoStorage {
@Synchronized
fun findDetailedBolusInfo(bolusTime: Long, bolus: Double): DetailedBolusInfo? {
if (MedtronicHistoryData.doubleBolusDebug)
log.debug("DoubleBolusDebug: findDetailedBolusInfo::bolusTime={}, bolus={}", bolusTime, bolus)
// Look for info with bolus
for (i in store.indices) {
val d = store[i]
@ -31,11 +26,8 @@ object DetailedBolusInfoStorage {
log.debug("Existing bolus info: " + store[i])
if (bolusTime > d.date - T.mins(1).msecs() && bolusTime < d.date + T.mins(1).msecs() && abs(store[i].insulin - bolus) < 0.01) {
if (L.isEnabled(L.PUMP))
log.debug("Using & removing bolus info: " + store[i])
log.debug("Using & removing bolus info: ${store[i]}")
store.removeAt(i)
if (MedtronicHistoryData.doubleBolusDebug)
log.debug("DoubleBolusDebug: findDetailedBolusInfo::selectedBolus[DetailedBolusInfo={}]", d)
return d
}
}
@ -44,13 +36,24 @@ object DetailedBolusInfoStorage {
val d = store[i]
if (bolusTime > d.date - T.mins(1).msecs() && bolusTime < d.date + T.mins(1).msecs() && bolus <= store[i].insulin + 0.01) {
if (L.isEnabled(L.PUMP))
log.debug("Using & removing bolus info: " + store[i])
log.debug("Using TIME-ONLY & removing bolus info: ${store[i]}")
store.removeAt(i)
if (MedtronicHistoryData.doubleBolusDebug)
log.debug("DoubleBolusDebug: findDetailedBolusInfo::selectedBolus[DetailedBolusInfo={}]", d)
return d
}
}
// If not found, use last record if amount is the same
if (store.size > 0) {
val d = store[store.size - 1]
if (abs(d.insulin - bolus) < 0.01) {
if (L.isEnabled(L.PUMP))
log.debug("Using LAST & removing bolus info: $d")
store.removeAt(store.size - 1)
return d
}
}
//Not found
if (L.isEnabled(L.PUMP))
log.debug("Bolus info not found")
return null
}
}

View file

@ -100,23 +100,23 @@ class DanaRHistoryActivity : NoSplashAppCompatActivity() {
danar_history_reload.setOnClickListener {
val selected = danar_history_spinner.selectedItem as TypeList
runOnUiThread {
danar_history_reload.visibility = View.GONE
danar_history_status.visibility = View.VISIBLE
danar_history_reload?.visibility = View.GONE
danar_history_status?.visibility = View.VISIBLE
}
clearCardView()
ConfigBuilderPlugin.getPlugin().commandQueue.loadHistory(selected.type, object : Callback() {
override fun run() {
loadDataFromDB(selected.type)
runOnUiThread {
danar_history_reload.visibility = View.VISIBLE
danar_history_status.visibility = View.GONE
danar_history_reload?.visibility = View.VISIBLE
danar_history_status?.visibility = View.GONE
}
}
})
}
danar_history_spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
val selected = danar_history_spinner.selectedItem as TypeList
val selected = danar_history_spinner?.selectedItem as TypeList? ?: return
loadDataFromDB(selected.type)
showingType = selected.type
}

View file

@ -1,25 +1,26 @@
package info.nightscout.androidaps.plugins.pump.insight;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Vibrator;
import android.text.Html;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.lifecycle.MutableLiveData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.pump.insight.activities.InsightAlertActivity;
import info.nightscout.androidaps.plugins.pump.insight.app_layer.remote_control.ConfirmAlertMessage;
@ -32,19 +33,21 @@ import info.nightscout.androidaps.plugins.pump.insight.descriptors.AlertType;
import info.nightscout.androidaps.plugins.pump.insight.descriptors.InsightState;
import info.nightscout.androidaps.plugins.pump.insight.exceptions.InsightException;
import info.nightscout.androidaps.plugins.pump.insight.exceptions.app_layer_errors.AppLayerErrorException;
import info.nightscout.androidaps.plugins.pump.insight.utils.AlertUtilsKt;
import info.nightscout.androidaps.plugins.pump.insight.utils.ExceptionTranslator;
public class InsightAlertService extends Service implements InsightConnectionService.StateCallback {
private static final int NOTIFICATION_ID = 31345;
private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM);
private LocalBinder localBinder = new LocalBinder();
private boolean connectionRequested;
private final Object $alertLock = new Object[0];
private Alert alert;
private Alert alert = null;
private MutableLiveData<Alert> alertLiveData = new MutableLiveData<>();
private Thread thread;
private InsightAlertActivity alertActivity;
private Ringtone ringtone;
private Vibrator vibrator;
private boolean vibrating;
private InsightConnectionService connectionService;
@ -65,27 +68,6 @@ public class InsightAlertService extends Service implements InsightConnectionSer
}
};
private void retrieveRingtone() {
Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
ringtone = RingtoneManager.getRingtone(this, uri);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ringtone.setAudioAttributes(new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
.setLegacyStreamType(AudioManager.STREAM_RING).build());
} else ringtone.setStreamType(AudioManager.STREAM_RING);
}
public Alert getAlert() {
synchronized ($alertLock) {
return alert;
}
}
public void setAlertActivity(InsightAlertActivity alertActivity) {
this.alertActivity = alertActivity;
}
public void ignore(AlertType alertType) {
synchronized ($alertLock) {
if (alertType == null) {
@ -98,6 +80,10 @@ public class InsightAlertService extends Service implements InsightConnectionSer
}
}
public MutableLiveData<Alert> getAlertLiveData() {
return alertLiveData;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
@ -108,6 +94,7 @@ public class InsightAlertService extends Service implements InsightConnectionSer
public void onCreate() {
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
bindService(new Intent(this, InsightConnectionService.class), serviceConnection, BIND_AUTO_CREATE);
alertLiveData.setValue(null);
}
@Override
@ -118,6 +105,12 @@ public class InsightAlertService extends Service implements InsightConnectionSer
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if ("mute".equals(intent.getStringExtra("command"))) {
mute();
} else if ("confirm".equals(intent.getStringExtra("command"))) {
dismissNotification();
confirm();
}
return START_STICKY;
}
@ -127,25 +120,47 @@ public class InsightAlertService extends Service implements InsightConnectionSer
thread = new Thread(this::queryActiveAlert);
thread.start();
} else if (thread != null) thread.interrupt();
} else {
dismissNotification();
if (thread != null) thread.interrupt();
}
}
private void queryActiveAlert() {
while (!Thread.currentThread().isInterrupted()) {
try {
Alert alert = connectionService.requestMessage(new GetActiveAlertMessage()).await().getAlert();
if (Thread.currentThread().isInterrupted()) {
connectionService.withdrawConnectionRequest(thread);
break;
}
synchronized ($alertLock) {
if ((this.alert == null && alert != null)
Alert alert = connectionService.requestMessage(new GetActiveAlertMessage()).await().getAlert();
if (alert == null || (alert.getAlertType() == ignoreType && System.currentTimeMillis() - ignoreTimestamp < 10000)) {
if (connectionRequested) {
connectionService.withdrawConnectionRequest(this);
connectionRequested = false;
}
this.alertLiveData.postValue(null);
this.alert = null;
dismissNotification();
stopAlerting();
} else if (!alert.equals(this.alert)) {
if (!connectionRequested) {
connectionService.requestConnection(this);
connectionRequested = true;
}
showNotification(alert);
this.alertLiveData.postValue(alert);
this.alert = alert;
if (alert.getAlertStatus() == AlertStatus.SNOOZED) stopAlerting();
else alert();
}
/*if ((this.alert == null && alert != null)
|| (this.alert != null && alert == null)
|| (this.alert != null && alert != null && !this.alert.equals(alert))) {
if (this.alert != null && (alert == null || this.alert.getAlertId() != alert.getAlertId())) stopAlerting();
this.alert = alert;
if (alertActivity != null && alert != null)
new Handler(Looper.getMainLooper()).post(() -> alertActivity.update(alert));
if (alert != null)
new Handler(Looper.getMainLooper()).post(() -> {
//showNotification(alert);
//alertActivity.update(alert);
});
}
if (alert == null) {
stopAlerting();
@ -153,8 +168,10 @@ public class InsightAlertService extends Service implements InsightConnectionSer
connectionService.withdrawConnectionRequest(this);
connectionRequested = false;
}
if (alertActivity != null)
new Handler(Looper.getMainLooper()).post(() -> alertActivity.finish());
new Handler(Looper.getMainLooper()).post(() -> {
//dismissNotification();
//alertActivity.finish();
});
} else if (!(alert.getAlertType() == ignoreType && System.currentTimeMillis() - ignoreTimestamp < 10000)) {
if (alert.getAlertStatus() == AlertStatus.ACTIVE) alert();
else stopAlerting();
@ -162,12 +179,12 @@ public class InsightAlertService extends Service implements InsightConnectionSer
connectionService.requestConnection(this);
connectionRequested = true;
}
if (alertActivity == null) {
/*if (alertActivity == null) {
Intent intent = new Intent(InsightAlertService.this, InsightAlertActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
new Handler(Looper.getMainLooper()).post(() -> startActivity(intent));
}
}
}*/
//}
}
} catch (InterruptedException ignored) {
connectionService.withdrawConnectionRequest(thread);
@ -189,21 +206,18 @@ public class InsightAlertService extends Service implements InsightConnectionSer
connectionService.withdrawConnectionRequest(thread);
connectionRequested = false;
}
if (alertActivity != null)
new Handler(Looper.getMainLooper()).post(() -> alertActivity.finish());
stopAlerting();
alertLiveData.postValue(null);
this.alert = null;
dismissNotification();
thread = null;
}
private void alert() {
if (!vibrating) {
vibrator.vibrate(new long[] {0, 1000, 1000}, 0);
vibrator.vibrate(new long[]{0, 1000, 1000}, 0);
vibrating = true;
}
if (ringtone == null || !ringtone.isPlaying()) {
retrieveRingtone();
ringtone.play();
}
}
private void stopAlerting() {
@ -211,15 +225,21 @@ public class InsightAlertService extends Service implements InsightConnectionSer
vibrator.cancel();
vibrating = false;
}
if (ringtone != null && ringtone.isPlaying()) ringtone.stop();
}
public void mute() {
new Thread(() -> {
try {
SnoozeAlertMessage snoozeAlertMessage = new SnoozeAlertMessage();
snoozeAlertMessage.setAlertID(alert.getAlertId());
connectionService.requestMessage(snoozeAlertMessage).await();
synchronized ($alertLock) {
if (alert == null) return;
alert.setAlertStatus(AlertStatus.SNOOZED);
alertLiveData.postValue(alert);
stopAlerting();
showNotification(alert);
SnoozeAlertMessage snoozeAlertMessage = new SnoozeAlertMessage();
snoozeAlertMessage.setAlertID(alert.getAlertId());
connectionService.requestMessage(snoozeAlertMessage).await();
}
} catch (AppLayerErrorException e) {
log.info("Exception while muting alert: " + e.getClass().getCanonicalName() + " (" + e.getErrorCode() + ")");
ExceptionTranslator.makeToast(InsightAlertService.this, e);
@ -236,9 +256,16 @@ public class InsightAlertService extends Service implements InsightConnectionSer
public void confirm() {
new Thread(() -> {
try {
ConfirmAlertMessage confirmAlertMessage = new ConfirmAlertMessage();
confirmAlertMessage.setAlertID(alert.getAlertId());
connectionService.requestMessage(confirmAlertMessage).await();
synchronized ($alertLock) {
if (alert == null) return;
stopAlerting();
alertLiveData.postValue(null);
dismissNotification();
ConfirmAlertMessage confirmAlertMessage = new ConfirmAlertMessage();
confirmAlertMessage.setAlertID(alert.getAlertId());
connectionService.requestMessage(confirmAlertMessage).await();
this.alert = null;
}
} catch (AppLayerErrorException e) {
log.info("Exception while confirming alert: " + e.getClass().getCanonicalName() + " (" + e.getErrorCode() + ")");
ExceptionTranslator.makeToast(InsightAlertService.this, e);
@ -252,6 +279,48 @@ public class InsightAlertService extends Service implements InsightConnectionSer
}).start();
}
private void showNotification(Alert alert) {
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, LocalInsightPlugin.ALERT_CHANNEL_ID);
notificationBuilder.setPriority(NotificationCompat.PRIORITY_MAX);
notificationBuilder.setCategory(NotificationCompat.CATEGORY_ALARM);
notificationBuilder.setVibrate(new long[0]);
notificationBuilder.setShowWhen(false);
notificationBuilder.setOngoing(true);
notificationBuilder.setOnlyAlertOnce(true);
notificationBuilder.setAutoCancel(false);
notificationBuilder.setSmallIcon(AlertUtilsKt.getAlertIcon(alert.getAlertCategory()));
notificationBuilder.setContentTitle(AlertUtilsKt.getAlertCode(alert.getAlertType()) + " " + AlertUtilsKt.getAlertTitle(alert.getAlertType()));
String description = AlertUtilsKt.getAlertDescription(alert);
if (description != null)
notificationBuilder.setContentText(Html.fromHtml(description).toString());
Intent fullScreenIntent = new Intent(this, InsightAlertActivity.class);
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 0, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notificationBuilder.setFullScreenIntent(fullScreenPendingIntent, true);
switch (alert.getAlertStatus()) {
case ACTIVE:
Intent muteIntent = new Intent(this, InsightAlertService.class).putExtra("command", "mute");
PendingIntent mutePendingIntent = PendingIntent.getService(this, 1, muteIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notificationBuilder.addAction(0, MainApp.gs(R.string.mute_alert), mutePendingIntent);
case SNOOZED:
Intent confirmIntent = new Intent(this, InsightAlertService.class).putExtra("command", "confirm");
PendingIntent confirmPendingIntent = PendingIntent.getService(this, 2, confirmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notificationBuilder.addAction(0, MainApp.gs(R.string.confirm), confirmPendingIntent);
}
Notification notification = notificationBuilder.build();
NotificationManagerCompat.from(this).notify(NOTIFICATION_ID, notification);
startForeground(NOTIFICATION_ID, notification);
}
private void dismissNotification() {
NotificationManagerCompat.from(this).cancel(NOTIFICATION_ID);
stopForeground(true);
}
public class LocalBinder extends Binder {
public InsightAlertService getService() {
return InsightAlertService.this;

View file

@ -1,9 +1,12 @@
package info.nightscout.androidaps.plugins.pump.insight;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@ -132,6 +135,8 @@ import info.nightscout.androidaps.utils.SP;
public class LocalInsightPlugin extends PluginBase implements PumpInterface, ConstraintsInterface, InsightConnectionService.StateCallback {
public static final String ALERT_CHANNEL_ID = "AndroidAPS-InsightAlert";
private static LocalInsightPlugin instance = null;
private Logger log = LoggerFactory.getLogger(L.PUMP);
@ -245,6 +250,16 @@ public class LocalInsightPlugin extends PluginBase implements PumpInterface, Con
super.onStart();
MainApp.instance().bindService(new Intent(MainApp.instance(), InsightConnectionService.class), serviceConnection, Context.BIND_AUTO_CREATE);
MainApp.instance().bindService(new Intent(MainApp.instance(), InsightAlertService.class), serviceConnection, Context.BIND_AUTO_CREATE);
createNotificationChannel();
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager notificationManager = (NotificationManager) MainApp.instance().getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel(ALERT_CHANNEL_ID, MainApp.gs(R.string.insight_alert_notification_channel), NotificationManager.IMPORTANCE_HIGH);
channel.setSound(null, null);
notificationManager.createNotificationChannel(channel);
}
}
@Override
@ -507,7 +522,7 @@ public class LocalInsightPlugin extends PluginBase implements PumpInterface, Con
nextValue = profile.getBasalValues()[i + 1];
if (profileBlock.getDuration() * 60 != (nextValue != null ? nextValue.timeAsSeconds : 24 * 60 * 60) - basalValue.timeAsSeconds)
return false;
if (Math.abs(profileBlock.getBasalAmount() - basalValue.value) > (basalValue.value > 5 ? 0.05 : 0.005))
if (Math.abs(profileBlock.getBasalAmount() - basalValue.value) > (basalValue.value > 5 ? 0.051 : 0.0051))
return false;
}
return true;
@ -571,6 +586,15 @@ public class LocalInsightPlugin extends PluginBase implements PumpInterface, Con
detailedBolusInfo.date = insightBolusID.timestamp;
detailedBolusInfo.source = Source.PUMP;
detailedBolusInfo.pumpId = insightBolusID.id;
if (detailedBolusInfo.carbs > 0 && detailedBolusInfo.carbTime != 0) {
DetailedBolusInfo carbInfo = new DetailedBolusInfo();
carbInfo.carbs = detailedBolusInfo.carbs;
carbInfo.date = detailedBolusInfo.date + detailedBolusInfo.carbTime * 60L * 1000L;
carbInfo.source = Source.USER;
TreatmentsPlugin.getPlugin().addToHistoryTreatment(carbInfo, false);
detailedBolusInfo.carbTime = 0;
detailedBolusInfo.carbs = 0;
}
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, true);
while (true) {
synchronized ($bolusLock) {
@ -638,8 +662,9 @@ public class LocalInsightPlugin extends PluginBase implements PumpInterface, Con
cancelBolusMessage.setBolusID(bolusID);
connectionService.requestMessage(cancelBolusMessage).await();
bolusCancelled = true;
confirmAlert(AlertType.WARNING_38);
alertService.ignore(null);
}
confirmAlert(AlertType.WARNING_38);
} catch (AppLayerErrorException e) {
log.info("Exception while canceling bolus: " + e.getClass().getCanonicalName() + " (" + e.getErrorCode() + ")");
} catch (InsightException e) {
@ -928,6 +953,7 @@ public class LocalInsightPlugin extends PluginBase implements PumpInterface, Con
@Override
public JSONObject getJSONStatus(Profile profile, String profileName) {
long now = System.currentTimeMillis();
if (connectionService == null) return null;
if (System.currentTimeMillis() - connectionService.getLastConnected() > (60 * 60 * 1000)) {
return null;
}
@ -1524,6 +1550,12 @@ public class LocalInsightPlugin extends PluginBase implements PumpInterface, Con
data.put("created_at", DateUtil.toISOString(date));
data.put("eventType", CareportalEvent.NOTE);
data.put("notes", note);
CareportalEvent careportalEvent = new CareportalEvent();
careportalEvent.date = date;
careportalEvent.source = Source.USER;
careportalEvent.eventType = CareportalEvent.NOTE;
careportalEvent.json = data.toString();
MainApp.getDbHelper().createOrUpdate(careportalEvent);
NSUpload.uploadCareportalEntryToNS(data);
} catch (JSONException e) {
log.error("Unhandled exception", e);
@ -1552,6 +1584,12 @@ public class LocalInsightPlugin extends PluginBase implements PumpInterface, Con
if (!enteredBy.equals("")) data.put("enteredBy", enteredBy);
data.put("created_at", DateUtil.toISOString(date));
data.put("eventType", event);
CareportalEvent careportalEvent = new CareportalEvent();
careportalEvent.date = date;
careportalEvent.source = Source.USER;
careportalEvent.eventType = event;
careportalEvent.json = data.toString();
MainApp.getDbHelper().createOrUpdate(careportalEvent);
NSUpload.uploadCareportalEntryToNS(data);
} catch (JSONException e) {
log.error("Unhandled exception", e);

View file

@ -12,19 +12,18 @@ import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import java.text.DecimalFormat;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity;
import info.nightscout.androidaps.plugins.pump.insight.InsightAlertService;
import info.nightscout.androidaps.plugins.pump.insight.descriptors.Alert;
import info.nightscout.androidaps.plugins.pump.insight.descriptors.AlertStatus;
import info.nightscout.androidaps.plugins.pump.insight.utils.AlertUtilsKt;
public class InsightAlertActivity extends NoSplashAppCompatActivity {
public class InsightAlertActivity extends AppCompatActivity {
private Alert alert;
private InsightAlertService alertService;
private ImageView icon;
@ -38,10 +37,10 @@ public class InsightAlertActivity extends NoSplashAppCompatActivity {
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
alertService = ((InsightAlertService.LocalBinder) binder).getService();
alertService.setAlertActivity(InsightAlertActivity.this);
alert = alertService.getAlert();
if (alert == null) finish();
else update(alert);
alertService.getAlertLiveData().observe(InsightAlertActivity.this, alert -> {
if (alert == null) finish();
else update(alert);
});
}
@Override
@ -70,174 +69,22 @@ public class InsightAlertActivity extends NoSplashAppCompatActivity {
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
WindowManager.LayoutParams layoutParams = getWindow().getAttributes();
layoutParams.screenBrightness = 1.0F;
getWindow().setAttributes(layoutParams);
}
@Override
protected void onDestroy() {
alertService.setAlertActivity(null);
unbindService(serviceConnection);
super.onDestroy();
}
public void update(Alert alert) {
this.alert = alert;
mute.setEnabled(true);
mute.setVisibility(alert.getAlertStatus() == AlertStatus.SNOOZED ? View.GONE : View.VISIBLE);
confirm.setEnabled(true);
int icon = 0;
int code = 0;
int title = 0;
String description = null;
switch (alert.getAlertCategory()) {
case ERROR:
icon = R.drawable.ic_error;
break;
case MAINTENANCE:
icon = R.drawable.ic_maintenance;
break;
case WARNING:
icon = R.drawable.ic_warning;
break;
case REMINDER:
icon = R.drawable.ic_reminder;
break;
}
DecimalFormat decimalFormat = new DecimalFormat("##0.00");
int hours = alert.getTBRDuration() / 60;
int minutes = alert.getTBRDuration() - hours * 60;
switch (alert.getAlertType()) {
case REMINDER_01:
code = R.string.alert_r1_code;
title = R.string.alert_r1_title;
break;
case REMINDER_02:
code = R.string.alert_r2_code;
title = R.string.alert_r2_title;
break;
case REMINDER_03:
code = R.string.alert_r3_code;
title = R.string.alert_r3_title;
break;
case REMINDER_04:
code = R.string.alert_r4_code;
title = R.string.alert_r4_title;
break;
case REMINDER_07:
code = R.string.alert_r7_code;
title = R.string.alert_r7_title;
description = getString(R.string.alert_r7_description, alert.getTBRAmount(), new DecimalFormat("#0").format(hours) + ":" + new DecimalFormat("00").format(minutes));
break;
case WARNING_31:
code = R.string.alert_w31_code;
title = R.string.alert_w31_title;
description = getString(R.string.alert_w31_description, decimalFormat.format(alert.getCartridgeAmount()));
break;
case WARNING_32:
code = R.string.alert_w32_code;
title = R.string.alert_w32_title;
description = getString(R.string.alert_w32_description);
break;
case WARNING_33:
code = R.string.alert_w33_code;
title = R.string.alert_w33_title;
description = getString(R.string.alert_w33_description);
break;
case WARNING_34:
code = R.string.alert_w34_code;
title = R.string.alert_w34_title;
description = getString(R.string.alert_w34_description);
break;
case WARNING_36:
code = R.string.alert_w36_code;
title = R.string.alert_w36_title;
description = getString(R.string.alert_w36_description, alert.getTBRAmount(), new DecimalFormat("#0").format(hours) + ":" + new DecimalFormat("00").format(minutes));
break;
case WARNING_38:
code = R.string.alert_w38_code;
title = R.string.alert_w38_title;
description = getString(R.string.alert_w38_description, decimalFormat.format(alert.getProgrammedBolusAmount()), decimalFormat.format(alert.getDeliveredBolusAmount()));
break;
case WARNING_39:
code = R.string.alert_w39_code;
title = R.string.alert_w39_title;
break;
case MAINTENANCE_20:
code = R.string.alert_m20_code;
title = R.string.alert_m20_title;
description = getString(R.string.alert_m20_description);
break;
case MAINTENANCE_21:
code = R.string.alert_m21_code;
title = R.string.alert_m21_title;
description = getString(R.string.alert_m21_description);
break;
case MAINTENANCE_22:
code = R.string.alert_m22_code;
title = R.string.alert_m22_title;
description = getString(R.string.alert_m22_description);
break;
case MAINTENANCE_23:
code = R.string.alert_m23_code;
title = R.string.alert_m23_title;
description = getString(R.string.alert_m23_description);
break;
case MAINTENANCE_24:
code = R.string.alert_m24_code;
title = R.string.alert_m24_title;
description = getString(R.string.alert_m24_description);
break;
case MAINTENANCE_25:
code = R.string.alert_m25_code;
title = R.string.alert_m25_title;
description = getString(R.string.alert_m25_description);
break;
case MAINTENANCE_26:
code = R.string.alert_m26_code;
title = R.string.alert_m26_title;
description = getString(R.string.alert_m26_description);
break;
case MAINTENANCE_27:
code = R.string.alert_m27_code;
title = R.string.alert_m27_title;
description = getString(R.string.alert_m27_description);
break;
case MAINTENANCE_28:
code = R.string.alert_m28_code;
title = R.string.alert_m28_title;
description = getString(R.string.alert_m28_description);
break;
case MAINTENANCE_29:
code = R.string.alert_m29_code;
title = R.string.alert_m29_title;
description = getString(R.string.alert_m29_description);
break;
case MAINTENANCE_30:
code = R.string.alert_m30_code;
title = R.string.alert_m30_title;
description = getString(R.string.alert_m30_description);
break;
case ERROR_6:
code = R.string.alert_e6_code;
title = R.string.alert_e6_title;
description = getString(R.string.alert_e6_description);
break;
case ERROR_10:
code = R.string.alert_e10_code;
title = R.string.alert_e10_title;
description = getString(R.string.alert_e10_description);
break;
case ERROR_13:
code = R.string.alert_e13_code;
title = R.string.alert_e13_title;
description = getString(R.string.alert_e13_description);
break;
}
this.icon.setImageDrawable(ContextCompat.getDrawable(this, icon));
this.errorCode.setText(code);
this.errorTitle.setText(title);
this.icon.setImageDrawable(ContextCompat.getDrawable(this, AlertUtilsKt.getAlertIcon(alert.getAlertCategory())));
this.errorCode.setText(AlertUtilsKt.getAlertCode(alert.getAlertType()));
this.errorTitle.setText(AlertUtilsKt.getAlertTitle(alert.getAlertType()));
String description = AlertUtilsKt.getAlertDescription(alert);
if (description == null) this.errorDescription.setVisibility(View.GONE);
else {
this.errorDescription.setVisibility(View.VISIBLE);

View file

@ -83,4 +83,24 @@ public class Alert {
public double getCartridgeAmount() {
return cartridgeAmount;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Alert alert = (Alert) o;
if (alertId != alert.alertId) return false;
if (tbrAmount != alert.tbrAmount) return false;
if (tbrDuration != alert.tbrDuration) return false;
if (Double.compare(alert.programmedBolusAmount, programmedBolusAmount) != 0)
return false;
if (Double.compare(alert.deliveredBolusAmount, deliveredBolusAmount) != 0)
return false;
if (Double.compare(alert.cartridgeAmount, cartridgeAmount) != 0) return false;
if (alertCategory != alert.alertCategory) return false;
if (alertType != alert.alertType) return false;
return alertStatus == alert.alertStatus;
}
}

View file

@ -0,0 +1,107 @@
package info.nightscout.androidaps.plugins.pump.insight.utils
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.plugins.pump.insight.descriptors.Alert
import info.nightscout.androidaps.plugins.pump.insight.descriptors.AlertCategory
import info.nightscout.androidaps.plugins.pump.insight.descriptors.AlertType
import java.text.DecimalFormat
fun getAlertCode(alertType: AlertType) = MainApp.gs(when (alertType) {
AlertType.REMINDER_01 -> R.string.alert_r1_code
AlertType.REMINDER_02 -> R.string.alert_r2_code
AlertType.REMINDER_03 -> R.string.alert_r3_code
AlertType.REMINDER_04 -> R.string.alert_r4_code
AlertType.REMINDER_07 -> R.string.alert_r7_code
AlertType.WARNING_31 -> R.string.alert_w31_code
AlertType.WARNING_32 -> R.string.alert_w32_code
AlertType.WARNING_33 -> R.string.alert_w33_code
AlertType.WARNING_34 -> R.string.alert_w34_code
AlertType.WARNING_36 -> R.string.alert_w36_code
AlertType.WARNING_38 -> R.string.alert_w38_code
AlertType.WARNING_39 -> R.string.alert_w39_code
AlertType.MAINTENANCE_20 -> R.string.alert_m20_code
AlertType.MAINTENANCE_21 -> R.string.alert_m21_code
AlertType.MAINTENANCE_22 -> R.string.alert_m22_code
AlertType.MAINTENANCE_23 -> R.string.alert_m23_code
AlertType.MAINTENANCE_24 -> R.string.alert_m24_code
AlertType.MAINTENANCE_25 -> R.string.alert_m25_code
AlertType.MAINTENANCE_26 -> R.string.alert_m26_code
AlertType.MAINTENANCE_27 -> R.string.alert_m27_code
AlertType.MAINTENANCE_28 -> R.string.alert_m28_code
AlertType.MAINTENANCE_29 -> R.string.alert_m29_code
AlertType.MAINTENANCE_30 -> R.string.alert_m30_code
AlertType.ERROR_6 -> R.string.alert_e6_code
AlertType.ERROR_10 -> R.string.alert_e10_code
AlertType.ERROR_13 -> R.string.alert_e13_code
})
fun getAlertTitle(alertType: AlertType) = MainApp.gs(when (alertType) {
AlertType.REMINDER_01 -> R.string.alert_r1_title
AlertType.REMINDER_02 -> R.string.alert_r2_title
AlertType.REMINDER_03 -> R.string.alert_r3_title
AlertType.REMINDER_04 -> R.string.alert_r4_title
AlertType.REMINDER_07 -> R.string.alert_r7_title
AlertType.WARNING_31 -> R.string.alert_w31_title
AlertType.WARNING_32 -> R.string.alert_w32_title
AlertType.WARNING_33 -> R.string.alert_w33_title
AlertType.WARNING_34 -> R.string.alert_w34_title
AlertType.WARNING_36 -> R.string.alert_w36_title
AlertType.WARNING_38 -> R.string.alert_w38_title
AlertType.WARNING_39 -> R.string.alert_w39_title
AlertType.MAINTENANCE_20 -> R.string.alert_m20_title
AlertType.MAINTENANCE_21 -> R.string.alert_m21_title
AlertType.MAINTENANCE_22 -> R.string.alert_m22_title
AlertType.MAINTENANCE_23 -> R.string.alert_m23_title
AlertType.MAINTENANCE_24 -> R.string.alert_m24_title
AlertType.MAINTENANCE_25 -> R.string.alert_m25_title
AlertType.MAINTENANCE_26 -> R.string.alert_m26_title
AlertType.MAINTENANCE_27 -> R.string.alert_m27_title
AlertType.MAINTENANCE_28 -> R.string.alert_m28_title
AlertType.MAINTENANCE_29 -> R.string.alert_m29_title
AlertType.MAINTENANCE_30 -> R.string.alert_m30_title
AlertType.ERROR_6 -> R.string.alert_e6_title
AlertType.ERROR_10 -> R.string.alert_e10_title
AlertType.ERROR_13 -> R.string.alert_e13_title
})
fun getAlertDescription(alert: Alert): String? {
val decimalFormat = DecimalFormat("##0.00")
val hours = alert.tbrDuration / 60
val minutes = alert.tbrDuration - hours * 60
return when (alert.alertType!!) {
AlertType.REMINDER_01 -> null
AlertType.REMINDER_02 -> null
AlertType.REMINDER_03 -> null
AlertType.REMINDER_04 -> null
AlertType.REMINDER_07 -> MainApp.gs(R.string.alert_r7_description, alert.tbrAmount, DecimalFormat("#0").format(hours.toLong()) + ":" + DecimalFormat("00").format(minutes.toLong()))
AlertType.WARNING_31 -> MainApp.gs(R.string.alert_w31_description, decimalFormat.format(alert.cartridgeAmount))
AlertType.WARNING_32 -> MainApp.gs(R.string.alert_w32_description)
AlertType.WARNING_33 -> MainApp.gs(R.string.alert_w33_description)
AlertType.WARNING_34 -> MainApp.gs(R.string.alert_w34_description)
AlertType.WARNING_36 -> MainApp.gs(R.string.alert_w36_description, alert.tbrAmount, DecimalFormat("#0").format(hours.toLong()) + ":" + DecimalFormat("00").format(minutes.toLong()))
AlertType.WARNING_38 -> MainApp.gs(R.string.alert_w38_description, decimalFormat.format(alert.programmedBolusAmount), decimalFormat.format(alert.deliveredBolusAmount))
AlertType.WARNING_39 -> null
AlertType.MAINTENANCE_20 -> MainApp.gs(R.string.alert_m20_description)
AlertType.MAINTENANCE_21 -> MainApp.gs(R.string.alert_m21_description)
AlertType.MAINTENANCE_22 -> MainApp.gs(R.string.alert_m22_description)
AlertType.MAINTENANCE_23 -> MainApp.gs(R.string.alert_m23_description)
AlertType.MAINTENANCE_24 -> MainApp.gs(R.string.alert_m24_description)
AlertType.MAINTENANCE_25 -> MainApp.gs(R.string.alert_m25_description)
AlertType.MAINTENANCE_26 -> MainApp.gs(R.string.alert_m26_description)
AlertType.MAINTENANCE_27 -> MainApp.gs(R.string.alert_m27_description)
AlertType.MAINTENANCE_28 -> MainApp.gs(R.string.alert_m28_description)
AlertType.MAINTENANCE_29 -> MainApp.gs(R.string.alert_m29_description)
AlertType.MAINTENANCE_30 -> MainApp.gs(R.string.alert_m30_description)
AlertType.ERROR_6 -> MainApp.gs(R.string.alert_e6_description)
AlertType.ERROR_10 -> MainApp.gs(R.string.alert_e10_description)
AlertType.ERROR_13 -> MainApp.gs(R.string.alert_e13_description)
}
}
fun getAlertIcon(alertCategory: AlertCategory) = when (alertCategory) {
AlertCategory.ERROR -> R.drawable.ic_error
AlertCategory.MAINTENANCE -> R.drawable.ic_maintenance
AlertCategory.WARNING -> R.drawable.ic_warning
AlertCategory.REMINDER -> R.drawable.ic_reminder
}

View file

@ -528,6 +528,12 @@ public class MedtronicHistoryData {
if (!enteredBy.equals("")) data.put("enteredBy", enteredBy);
data.put("created_at", DateUtil.toISOString(date));
data.put("eventType", event);
CareportalEvent careportalEvent = new CareportalEvent();
careportalEvent.date = date;
careportalEvent.source = Source.USER;
careportalEvent.eventType = event;
careportalEvent.json = data.toString();
MainApp.getDbHelper().createOrUpdate(careportalEvent);
NSUpload.uploadCareportalEntryToNS(data);
} catch (JSONException e) {
LOG.error("Unhandled exception", e);

View file

@ -31,7 +31,7 @@ object RandomBgPlugin : PluginBase(PluginDescription()
private val loopHandler = Handler()
private lateinit var refreshLoop: Runnable
const val interval = 5L // minutes
const val interval = 1L // minutes
init {
refreshLoop = Runnable {
@ -55,7 +55,7 @@ object RandomBgPlugin : PluginBase(PluginDescription()
}
override fun specialEnableCondition(): Boolean {
return VirtualPumpPlugin.getPlugin().isEnabled(PluginType.PUMP) && (MainApp.engineeringMode || isRunningTest())
return isRunningTest() || VirtualPumpPlugin.getPlugin().isEnabled(PluginType.PUMP) && MainApp.engineeringMode
}
override fun handleNewData(intent: Intent) {
@ -65,7 +65,7 @@ object RandomBgPlugin : PluginBase(PluginDescription()
val cal = GregorianCalendar()
val currentMinute = cal.get(Calendar.MINUTE) + (cal.get(Calendar.HOUR_OF_DAY) % 2) * 60
val bgMgdl = min + (max - min) * sin(currentMinute / 120.0 * 2 * PI)
val bgMgdl = min + (max - min) + (max - min) * sin(currentMinute / 120.0 * 2 * PI)
val bgReading = BgReading()
bgReading.value = bgMgdl

View file

@ -9,6 +9,8 @@ import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.RequestDexcomPermissionActivity
import info.nightscout.androidaps.db.BgReading
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.dialogs.CareDialog
import info.nightscout.androidaps.interfaces.BgSourceInterface
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
@ -96,6 +98,13 @@ object SourceDexcomPlugin : PluginBase(PluginDescription()
jsonObject.put("glucoseType", "Finger")
jsonObject.put("glucose", meter.getInt("meterValue"))
jsonObject.put("units", Constants.MGDL)
val careportalEvent = CareportalEvent()
careportalEvent.date = timestamp
careportalEvent.source = Source.USER
careportalEvent.eventType = CareportalEvent.BGCHECK
careportalEvent.json = jsonObject.toString()
MainApp.getDbHelper().createOrUpdate(careportalEvent)
NSUpload.uploadCareportalEntryToNS(jsonObject)
}
}
@ -110,6 +119,12 @@ object SourceDexcomPlugin : PluginBase(PluginDescription()
jsonObject.put("enteredBy", "AndroidAPS-Dexcom$sensorType")
jsonObject.put("created_at", DateUtil.toISOString(sensorInsertionTime))
jsonObject.put("eventType", CareportalEvent.SENSORCHANGE)
val careportalEvent = CareportalEvent()
careportalEvent.date = sensorInsertionTime
careportalEvent.source = Source.USER
careportalEvent.eventType = CareportalEvent.SENSORCHANGE
careportalEvent.json = jsonObject.toString()
MainApp.getDbHelper().createOrUpdate(careportalEvent)
NSUpload.uploadCareportalEntryToNS(jsonObject)
}
}

View file

@ -15,6 +15,7 @@ import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.interfaces.BgSourceInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginDescription;
@ -143,6 +144,12 @@ public class SourceEversensePlugin extends PluginBase implements BgSourceInterfa
data.put("glucoseType", "Finger");
data.put("glucose", calibrationGlucoseLevels[i]);
data.put("units", Constants.MGDL);
CareportalEvent careportalEvent = new CareportalEvent();
careportalEvent.date = calibrationTimestamps[i];
careportalEvent.source = Source.USER;
careportalEvent.eventType = CareportalEvent.BGCHECK;
careportalEvent.json = data.toString();
MainApp.getDbHelper().createOrUpdate(careportalEvent);
NSUpload.uploadCareportalEntryToNS(data);
}
} catch (JSONException e) {

View file

@ -160,7 +160,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
scheduleTreatmentChange(null);
scheduleTreatmentChange(null, true);
}
@ -208,18 +208,30 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
/**
* Schedule a foodChange Event.
*/
public void scheduleTreatmentChange(@Nullable final Treatment treatment) {
this.scheduleEvent(new EventReloadTreatmentData(new EventTreatmentChange(treatment)), treatmentEventWorker, new ICallback() {
@Override
public void setPost(ScheduledFuture<?> post) {
scheduledTreatmentEventPost = post;
public void scheduleTreatmentChange(@Nullable final Treatment treatment, boolean runImmediately) {
if (runImmediately) {
if (L.isEnabled(L.DATATREATMENTS))
log.debug("Firing EventReloadTreatmentData");
RxBus.INSTANCE.send(new EventReloadTreatmentData(new EventTreatmentChange(treatment)));
if (DatabaseHelper.earliestDataChange != null) {
if (L.isEnabled(L.DATATREATMENTS))
log.debug("Firing EventNewHistoryData");
RxBus.INSTANCE.send(new EventNewHistoryData(DatabaseHelper.earliestDataChange));
}
DatabaseHelper.earliestDataChange = null;
} else {
this.scheduleEvent(new EventReloadTreatmentData(new EventTreatmentChange(treatment)), treatmentEventWorker, new ICallback() {
@Override
public void setPost(ScheduledFuture<?> post) {
scheduledTreatmentEventPost = post;
}
@Override
public ScheduledFuture<?> getPost() {
return scheduledTreatmentEventPost;
}
});
@Override
public ScheduledFuture<?> getPost() {
return scheduledTreatmentEventPost;
}
});
}
}
public List<Treatment> getTreatmentData() {
@ -294,7 +306,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
getDao().create(existingTreatment);
DatabaseHelper.updateEarliestDataChange(oldDate);
DatabaseHelper.updateEarliestDataChange(existingTreatment.date);
scheduleTreatmentChange(treatment);
scheduleTreatmentChange(treatment, true);
return new UpdateReturn(sameSource, false); //updating a pump treatment with another one from the pump is not counted as clash
}
return new UpdateReturn(equalRePumpHistory, false);
@ -318,14 +330,14 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
getDao().create(existingTreatment);
DatabaseHelper.updateEarliestDataChange(oldDate);
DatabaseHelper.updateEarliestDataChange(existingTreatment.date);
scheduleTreatmentChange(treatment);
scheduleTreatmentChange(treatment, true);
return new UpdateReturn(equalRePumpHistory || sameSource, false);
}
getDao().create(treatment);
if (L.isEnabled(L.DATATREATMENTS))
log.debug("New record from: " + Source.getString(treatment.source) + " " + treatment.toString());
DatabaseHelper.updateEarliestDataChange(treatment.date);
scheduleTreatmentChange(treatment);
scheduleTreatmentChange(treatment, true);
return new UpdateReturn(true, true);
}
if (treatment.source == Source.NIGHTSCOUT) {
@ -343,7 +355,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
DatabaseHelper.updateEarliestDataChange(oldDate);
DatabaseHelper.updateEarliestDataChange(old.date);
}
scheduleTreatmentChange(treatment);
scheduleTreatmentChange(treatment, false);
return new UpdateReturn(true, true);
}
if (L.isEnabled(L.DATATREATMENTS))
@ -366,7 +378,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
DatabaseHelper.updateEarliestDataChange(oldDate);
DatabaseHelper.updateEarliestDataChange(old.date);
}
scheduleTreatmentChange(treatment);
scheduleTreatmentChange(treatment, false);
return new UpdateReturn(true, true);
}
if (L.isEnabled(L.DATATREATMENTS))
@ -378,7 +390,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
if (L.isEnabled(L.DATATREATMENTS))
log.debug("New record from: " + Source.getString(treatment.source) + " " + treatment.toString());
DatabaseHelper.updateEarliestDataChange(treatment.date);
scheduleTreatmentChange(treatment);
scheduleTreatmentChange(treatment, false);
return new UpdateReturn(true, true);
}
if (treatment.source == Source.USER) {
@ -386,7 +398,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
if (L.isEnabled(L.DATATREATMENTS))
log.debug("New record from: " + Source.getString(treatment.source) + " " + treatment.toString());
DatabaseHelper.updateEarliestDataChange(treatment.date);
scheduleTreatmentChange(treatment);
scheduleTreatmentChange(treatment, true);
return new UpdateReturn(true, true);
}
} catch (SQLException e) {
@ -414,7 +426,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
if (L.isEnabled(L.DATATREATMENTS))
log.debug("New record from: " + Source.getString(treatment.source) + " " + treatment.toString());
DatabaseHelper.updateEarliestDataChange(treatment.date);
scheduleTreatmentChange(treatment);
scheduleTreatmentChange(treatment, true);
return new UpdateReturn(true, true);
} else {
@ -428,7 +440,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
}
getDao().update(existingTreatment);
DatabaseHelper.updateEarliestDataChange(existingTreatment.date);
scheduleTreatmentChange(treatment);
scheduleTreatmentChange(treatment, true);
return new UpdateReturn(true, false);
} else {
if (MedtronicHistoryData.doubleBolusDebug)
@ -439,7 +451,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
optionalTreatmentCopy(existingTreatment, treatment, fromNightScout);
getDao().create(existingTreatment);
DatabaseHelper.updateEarliestDataChange(existingTreatment.date);
scheduleTreatmentChange(treatment);
scheduleTreatmentChange(treatment, true);
return new UpdateReturn(true, false); //updating a pump treatment with another one from the pump is not counted as clash
}
}
@ -626,9 +638,13 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
if (stored != null) {
if (L.isEnabled(L.DATATREATMENTS))
log.debug("Removing Treatment record from database: " + stored.toString());
delete(stored);
try {
getDao().delete(stored);
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
DatabaseHelper.updateEarliestDataChange(stored.date);
scheduleTreatmentChange(null);
this.scheduleTreatmentChange(stored, false);
}
}
@ -643,7 +659,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
try {
getDao().delete(treatment);
DatabaseHelper.updateEarliestDataChange(treatment.date);
this.scheduleTreatmentChange(treatment);
this.scheduleTreatmentChange(treatment, true);
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
@ -656,7 +672,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
scheduleTreatmentChange(treatment);
scheduleTreatmentChange(treatment, true);
}
/**

View file

@ -221,7 +221,7 @@ public class TreatmentsBolusFragment extends Fragment {
});
});
boolean nsUploadOnly = SP.getBoolean(R.string.key_ns_upload_only, false);
boolean nsUploadOnly = SP.getBoolean(R.string.key_ns_upload_only, true);
if (nsUploadOnly)
refreshFromNS.setVisibility(View.GONE);

View file

@ -136,7 +136,7 @@ public class TreatmentsCareportalFragment extends Fragment {
view.findViewById(R.id.careportal_removeandroidapsstartedevents).setOnClickListener(v ->
OKDialog.showConfirmation(getContext(), MainApp.gs(R.string.careportal), MainApp.gs(R.string.careportal_removestartedevents), this::removeAndroidAPSStatedEvents));
boolean nsUploadOnly = SP.getBoolean(R.string.key_ns_upload_only, false);
boolean nsUploadOnly = SP.getBoolean(R.string.key_ns_upload_only, true);
if (nsUploadOnly)
refreshFromNS.setVisibility(View.GONE);

View file

@ -51,7 +51,7 @@ class TreatmentsProfileSwitchFragment : Fragment() {
})
}
}
if (SP.getBoolean(R.string.key_ns_upload_only, false)) profileswitch_refreshfromnightscout.visibility = View.GONE
if (SP.getBoolean(R.string.key_ns_upload_only, true)) profileswitch_refreshfromnightscout.visibility = View.GONE
}

View file

@ -168,7 +168,7 @@ public class TreatmentsTempTargetFragment extends Fragment {
RxBus.INSTANCE.send(new EventNSClientRestart());
}));
boolean nsUploadOnly = SP.getBoolean(R.string.key_ns_upload_only, false);
boolean nsUploadOnly = SP.getBoolean(R.string.key_ns_upload_only, true);
if (nsUploadOnly)
refreshFromNS.setVisibility(View.GONE);

View file

@ -23,9 +23,6 @@ import org.slf4j.LoggerFactory
import kotlin.math.abs
class KeepAliveReceiver : BroadcastReceiver() {
private var lastReadStatus: Long = 0
private var lastRun: Long = 0
private var lastIobUpload: Long = 0
override fun onReceive(context: Context, rIntent: Intent) {
if (L.isEnabled(L.CORE))
@ -47,6 +44,10 @@ class KeepAliveReceiver : BroadcastReceiver() {
private val STATUS_UPDATE_FREQUENCY = T.mins(15).msecs()
private val IOB_UPDATE_FREQUENCY = T.mins(5).msecs()
private var lastReadStatus: Long = 0
private var lastRun: Long = 0
private var lastIobUpload: Long = 0
//called by MainApp at first app start
@JvmStatic
fun setAlarm(context: Context) {

View file

@ -24,8 +24,6 @@ public class NetworkChangeReceiver extends BroadcastReceiver {
private static EventNetworkChange lastEvent = null;
public static final NetworkChangeReceiver instance = new NetworkChangeReceiver();
@Override
public void onReceive(final Context context, final Intent intent) {
EventNetworkChange event = grabNetworkStatus(context);

View file

@ -54,7 +54,7 @@ public class DataService extends IntentService {
log.debug("onHandleIntent " + BundleLogger.log(intent.getExtras()));
}
boolean acceptNSData = !SP.getBoolean(R.string.key_ns_upload_only, false);
boolean acceptNSData = !SP.getBoolean(R.string.key_ns_upload_only, true);
Bundle bundles = intent.getExtras();
final String action = intent.getAction();

View file

@ -32,6 +32,7 @@ public class AndroidPermission {
public static final int CASE_LOCATION = 0x3;
public static final int CASE_BATTERY = 0x4;
public static final int CASE_PHONE_STATE = 0x5;
public static final int CASE_SYSTEM_WINDOW = 0x6;
private static boolean permission_battery_optimization_failed = false;
@ -130,4 +131,22 @@ public class AndroidPermission {
} else
RxBus.INSTANCE.send(new EventDismissNotification(Notification.PERMISSION_LOCATION));
}
public static synchronized void notifyForSystemWindowPermissions(Activity activity) {
// Check if Android Q or higher
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
if (!Settings.canDrawOverlays(activity)) {
NotificationWithAction notification = new NotificationWithAction(Notification.PERMISSION_SYSTEM_WINDOW, MainApp.gs(R.string.needsystemwindowpermission), Notification.URGENT);
notification.action(R.string.request, () -> {
// Show alert dialog to the user saying a separate permission is needed
// Launch the settings activity if the user prefers
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + activity.getPackageName()));
activity.startActivity(intent);
});
RxBus.INSTANCE.send(new EventNewNotification(notification));
} else
RxBus.INSTANCE.send(new EventDismissNotification(Notification.PERMISSION_SYSTEM_WINDOW));
}
}
}

View file

@ -277,6 +277,7 @@ class BolusWizard @JvmOverloads constructor(val profile: Profile,
OKDialog.showConfirmation(context, MainApp.gs(R.string.boluswizard), HtmlHelper.fromHtml(confirmMessage), Runnable {
if (insulinAfterConstraints > 0 || carbs > 0) {
if (useSuperBolus) {
log.debug("USER ENTRY: SUPERBOLUS TBR")
val loopPlugin = LoopPlugin.getPlugin()
if (loopPlugin.isEnabled(PluginType.LOOP)) {
loopPlugin.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000)
@ -325,6 +326,7 @@ class BolusWizard @JvmOverloads constructor(val profile: Profile,
detailedBolusInfo.boluscalc = nsJSON()
detailedBolusInfo.source = Source.USER
detailedBolusInfo.notes = notes
log.debug("USER ENTRY: BOLUS insulin $insulinAfterConstraints carbs: $carbs")
if (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription?.storesCarbInfo == true) {
ConfigBuilderPlugin.getPlugin().commandQueue.bolus(detailedBolusInfo, object : Callback() {
override fun run() {

View file

@ -141,6 +141,14 @@ public class DateUtil {
return new DateTime(mills).toString(DateTimeFormat.forPattern(format));
}
public static String timeStringWithSeconds(long mills) {
String format = "hh:mm:ssa";
if (android.text.format.DateFormat.is24HourFormat(MainApp.instance())) {
format = "HH:mm:ss";
}
return new DateTime(mills).toString(DateTimeFormat.forPattern(format));
}
public static String timeFullString(long mills) {
return new DateTime(mills).toString(DateTimeFormat.fullTime());
}
@ -158,6 +166,11 @@ public class DateUtil {
return dateString(mills) + " " + timeString(mills);
}
public static String dateAndTimeAndSecondsString(long mills) {
if (mills == 0) return "";
return dateString(mills) + " " + timeStringWithSeconds(mills);
}
public static String dateAndTimeFullString(long mills) {
return dateString(mills) + " " + timeFullString(mills);
}

View file

@ -9,3 +9,13 @@ fun isRunningTest(): Boolean {
false
}
}
@Synchronized
fun isRunningRealPumpTest(): Boolean {
return try {
Class.forName("info.nightscout.androidaps.RealPumpTest")
true
} catch (e: ClassNotFoundException) {
false
}
}

View file

@ -62,13 +62,11 @@ object OKDialog {
}
@JvmStatic
@JvmOverloads
fun showConfirmation(activity: Activity, message: String, ok: Runnable?) {
showConfirmation(activity, MainApp.gs(R.string.confirmation), message, ok, null)
}
@JvmStatic
@JvmOverloads
fun showConfirmation(activity: Activity, message: Spanned, ok: Runnable?) {
showConfirmation(activity, MainApp.gs(R.string.confirmation), message, ok, null)
}

View file

@ -57,51 +57,6 @@
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="end"
android:paddingRight="5dp"
android:text="@string/openapsma_lastenact_label"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/loop_lastenact"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
@ -282,6 +237,96 @@
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="end"
android:paddingRight="5dp"
android:text="@string/loop_tbrrequest_time_label"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/loop_tbrrequest_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="end"
android:paddingRight="5dp"
android:text="@string/loop_tbrexecution_time_label"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/loop_tbrexecution_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
@ -327,6 +372,96 @@
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="end"
android:paddingRight="5dp"
android:text="@string/loop_smbrequest_time_label"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/loop_smbrequest_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="end"
android:paddingRight="5dp"
android:text="@string/loop_smbexecution_time_label"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/loop_smbexecution_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"

View file

@ -477,7 +477,8 @@
app:layout_constraintBottom_toTopOf="@id/overview_buttons_layout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/overview_toppart_scrollbar" />
app:layout_constraintTop_toBottomOf="@id/overview_toppart_scrollbar"
android:visibility="gone"/>
<LinearLayout
android:id="@+id/overview_buttons_layout"

View file

@ -0,0 +1,584 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".plugins.general.overview.OverviewFragment">
<ScrollView
android:id="@+id/overview_toppart_scrollbar"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/overview_notifications"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/overview_looplayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.recyclerview.widget.RecyclerView>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/overview_looplayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/overview_pumpstatuslayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/overview_notifications">
<TextView
android:id="@+id/overview_apsmode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:gravity="center_vertical|center_horizontal"
android:paddingTop="3dp"
android:paddingBottom="3dp"
android:text="@string/openloop"
android:textAppearance="?android:attr/textAppearanceSmall"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/overview_activeprofile"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/overview_activeprofile"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:gravity="center_vertical|center_horizontal"
android:paddingTop="3dp"
android:paddingBottom="3dp"
android:text="@string/profile"
android:textAppearance="?android:attr/textAppearanceSmall"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/overview_temptarget"
app:layout_constraintStart_toEndOf="@+id/overview_apsmode"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/overview_temptarget"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:paddingTop="3dp"
android:paddingBottom="3dp"
android:text="@string/temptargetshort"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/mdtp_white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/overview_activeprofile"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:id="@+id/overview_pumpstatuslayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintBottom_toTopOf="@+id/bg_tbr_layout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/overview_looplayout">
<TextView
android:id="@+id/overview_pumpstatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:gravity="center_vertical|center_horizontal"
android:paddingTop="3dp"
android:paddingBottom="3dp"
android:text="@string/initializing"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/bg_tbr_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintBottom_toTopOf="@+id/overview_statuslights"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/overview_pumpstatuslayout">
<TextView
android:id="@+id/overview_bg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="00.0"
android:textSize="42sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@+id/overview_arrow"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/overview_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:paddingStart="-2dp"
android:paddingEnd="0dp"
android:text="→"
android:textSize="28sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@+id/overview_bg_guideline"
app:layout_constraintStart_toEndOf="@+id/overview_bg"
app:layout_constraintTop_toTopOf="@+id/overview_bg" />
<TextView
android:id="@+id/overview_hor_space"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" "
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@+id/overview_bg_guideline"
app:layout_constraintStart_toEndOf="@+id/overview_arrow"
app:layout_constraintTop_toTopOf="@+id/overview_bg" />
<TextView
android:id="@+id/overview_timeago"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1 min ago"
android:textSize="14sp"
app:layout_constraintBottom_toTopOf="@+id/overview_delta"
app:layout_constraintEnd_toEndOf="@+id/overview_arrow"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/overview_bg" />
<TextView
android:id="@+id/overview_delta"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="delta 15m: 0.3"
android:textSize="14sp"
app:layout_constraintBottom_toTopOf="@+id/overview_avgdelta"
app:layout_constraintEnd_toEndOf="@+id/overview_arrow"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/overview_timeago" />
<TextView
android:id="@+id/overview_avgdelta"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="delta 40m: 0.3"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="@+id/overview_arrow"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/overview_delta" />
<!-- right side -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/overview_bg_guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/overview_iob_label"
app:layout_constraintGuide_percent="0.40"
app:layout_constraintStart_toEndOf="@+id/overview_hor_space"
app:layout_constraintTop_toTopOf="parent" />
<!-- right side IOB -->
<TextView
android:id="@+id/overview_iob_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/iob"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="@+id/overview_cob_label"
app:layout_constraintStart_toEndOf="@+id/overview_bg_guideline"
app:layout_constraintTop_toBottomOf="parent" />
<TextView
android:id="@+id/overview_iob_colon"
android:layout_width="5dp"
android:layout_height="wrap_content"
android:text=":"
android:textSize="16sp"
app:layout_constraintStart_toEndOf="@+id/overview_iob_label"
app:layout_constraintTop_toTopOf="@+id/overview_iob_label" />
<TextView
android:id="@+id/overview_iob"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="@string/iob"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/overview_iob_label"
app:layout_constraintStart_toEndOf="@+id/overview_iob_colon" />
<!-- right side COB -->
<TextView
android:id="@+id/overview_cob_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cob"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="@+id/overview_basebasal_label"
app:layout_constraintStart_toEndOf="@+id/overview_bg_guideline"
app:layout_constraintTop_toBottomOf="@+id/overview_iob_label" />
<TextView
android:id="@+id/overview_cob_colon"
android:layout_width="5dp"
android:layout_height="wrap_content"
android:text=":"
android:textSize="16sp"
app:layout_constraintStart_toEndOf="@+id/overview_cob_label"
app:layout_constraintTop_toBottomOf="@+id/overview_iob_label" />
<TextView
android:id="@+id/overview_cob"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="@string/cob"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/overview_cob_label"
app:layout_constraintStart_toEndOf="@+id/overview_cob_colon" />
<!-- right side basal -->
<TextView
android:id="@+id/overview_basebasal_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/basal_short"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="@+id/overview_extendedbolus_label"
app:layout_constraintStart_toEndOf="@+id/overview_bg_guideline"
app:layout_constraintTop_toBottomOf="@+id/overview_cob_label" />
<TextView
android:id="@+id/overview_basebasal_colon"
android:layout_width="5dp"
android:layout_height="wrap_content"
android:text=":"
android:textSize="16sp"
app:layout_constraintStart_toEndOf="@+id/overview_basebasal_label"
app:layout_constraintTop_toBottomOf="@+id/overview_cob_label" />
<TextView
android:id="@+id/overview_basebasal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="0.50U/h @17:35 1/30min"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/overview_basebasal_label"
app:layout_constraintStart_toEndOf="@+id/overview_basebasal_colon" />
<!-- right side extended -->
<TextView
android:id="@+id/overview_extendedbolus_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/extended_bolus_short"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="@+id/overview_sensitivity_label"
app:layout_constraintStart_toEndOf="@+id/overview_bg_guideline"
app:layout_constraintTop_toBottomOf="@+id/overview_basebasal_label" />
<TextView
android:id="@+id/overview_extendedbolus_colon"
android:layout_width="5dp"
android:layout_height="wrap_content"
android:text=":"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="@+id/overview_extendedbolus_label"
app:layout_constraintStart_toEndOf="@+id/overview_extendedbolus_label" />
<TextView
android:id="@+id/overview_extendedbolus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="0.50U/h @17:35 1/30min"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/overview_extendedbolus_label"
app:layout_constraintStart_toEndOf="@+id/overview_extendedbolus_colon" />
<!-- right side AS -->
<TextView
android:id="@+id/overview_sensitivity_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/sensitivity_short"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/overview_bg_guideline"
app:layout_constraintTop_toBottomOf="@+id/overview_extendedbolus_label" />
<TextView
android:id="@+id/overview_sensitivity_colon"
android:layout_width="5dp"
android:layout_height="wrap_content"
android:text=":"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="@+id/overview_sensitivity_label"
app:layout_constraintStart_toEndOf="@+id/overview_sensitivity_label" />
<TextView
android:id="@+id/overview_sensitivity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="100%"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/overview_sensitivity_label"
app:layout_constraintStart_toEndOf="@+id/overview_sensitivity_colon" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:id="@+id/overview_statuslights"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal"
app:layout_constraintBottom_toTopOf="@+id/overview_bggraph"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/bg_tbr_layout">
<TextView
android:id="@+id/overview_canulaage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text=""
android:textSize="14sp" />
<TextView
android:id="@+id/overview_insulinage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text=""
android:textSize="14sp" />
<TextView
android:id="@+id/overview_reservoirlevel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text=""
android:textSize="14sp" />
<TextView
android:id="@+id/overview_sensorage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text=""
android:textSize="14sp" />
<TextView
android:id="@+id/overview_batterylevel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text=""
android:textSize="14sp" />
</LinearLayout>
<com.jjoe64.graphview.GraphView
android:id="@+id/overview_bggraph"
android:layout_width="0dp"
android:layout_height="200dp"
app:layout_constraintBottom_toTopOf="@+id/overview_iobgraph"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/overview_statuslights" />
<ImageButton
android:id="@+id/overview_chartMenuButton"
android:layout_width="30dp"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:contentDescription="@string/chartmenu"
app:layout_constraintEnd_toEndOf="@+id/overview_bggraph"
app:layout_constraintTop_toTopOf="@+id/overview_bggraph"
app:srcCompat="@drawable/ic_arrow_drop_down_white_24dp" />
<TextView
android:id="@+id/overview_iobcalculationprogess"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text=""
android:textSize="15sp"
app:layout_constraintBottom_toBottomOf="@+id/overview_bggraph"
app:layout_constraintEnd_toEndOf="@+id/overview_bggraph"
app:layout_constraintStart_toStartOf="@+id/overview_bggraph"
app:layout_constraintTop_toTopOf="@+id/overview_bggraph" />
<com.jjoe64.graphview.GraphView
android:id="@+id/overview_iobgraph"
android:layout_width="0dp"
android:layout_height="100dp"
app:layout_constraintBottom_toTopOf="@+id/overview_accepttempbutton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/overview_bggraph" />
<info.nightscout.androidaps.utils.SingleClickButton
android:id="@+id/overview_accepttempbutton"
style="?android:attr/buttonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:text="@string/setbasalquestion"
android:textColor="@color/colorAcceptTempButton"
app:layout_constraintBottom_toTopOf="@id/overview_buttons_layout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/overview_iobgraph"
android:visibility="gone"/>
<LinearLayout
android:id="@+id/overview_buttons_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingStart="0dp"
android:paddingEnd="5dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/overview_accepttempbutton">
<info.nightscout.androidaps.utils.SingleClickButton
android:id="@+id/overview_treatmentbutton"
style="?android:attr/buttonStyle"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_marginEnd="-4dp"
android:layout_weight="0.5"
android:drawableTop="@drawable/icon_insulin_carbs"
android:text="@string/overview_treatment_label"
android:textColor="@color/colorTreatmentButton"
android:textSize="10sp"
android:visibility="gone" />
<info.nightscout.androidaps.utils.SingleClickButton
android:id="@+id/overview_insulinbutton"
style="?android:attr/buttonStyle"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_marginEnd="-4dp"
android:layout_weight="0.5"
android:drawableTop="@drawable/icon_bolus"
android:text="@string/overview_insulin_label"
android:textColor="@color/colorInsulinButton"
android:textSize="10sp" />
<info.nightscout.androidaps.utils.SingleClickButton
android:id="@+id/overview_carbsbutton"
style="?android:attr/buttonStyle"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_marginEnd="-4dp"
android:layout_weight="0.5"
android:drawableTop="@drawable/icon_cp_bolus_carbs"
android:text="@string/overview_carbs_label"
android:textColor="@color/colorCarbsButton"
android:textSize="10sp" />
<info.nightscout.androidaps.utils.SingleClickButton
android:id="@+id/overview_wizardbutton"
style="?android:attr/buttonStyle"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_marginEnd="-4dp"
android:layout_weight="0.5"
android:drawableTop="@drawable/icon_calculator"
android:text="@string/overview_calculator_label"
android:textColor="@color/colorCalculatorButton"
android:textSize="10sp" />
<info.nightscout.androidaps.utils.SingleClickButton
android:id="@+id/overview_calibrationbutton"
style="?android:attr/buttonStyle"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_marginEnd="-4dp"
android:layout_weight="0.5"
android:drawableTop="@drawable/icon_calibration"
android:text="@string/overview_calibration"
android:textColor="@color/colorCalibrationButton"
android:textSize="10sp"
android:visibility="gone" />
<info.nightscout.androidaps.utils.SingleClickButton
android:id="@+id/overview_cgmbutton"
style="?android:attr/buttonStyle"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_marginEnd="-4dp"
android:layout_weight="0.5"
android:drawableTop="@drawable/icon_xdrip"
android:text="@string/overview_cgm"
android:textColor="@color/colorCalibrationButton"
android:textSize="10sp"
android:visibility="gone" />
<info.nightscout.androidaps.utils.SingleClickButton
android:id="@+id/overview_quickwizardbutton"
style="?android:attr/buttonStyle"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_marginEnd="-4dp"
android:layout_weight="0.5"
android:drawableTop="@drawable/icon_quickwizard"
android:text="@string/quickwizard"
android:textColor="@color/colorQuickWizardButton"
android:textSize="10sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,3 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources></resources>

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<!-- <string name="fi_lang" translatable="false">Finnish</string> -->
<!-- <string name="he_lang" translatable="false">Hebrew</string> -->

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<string name="objectives_button_back">Назад</string>
<string name="objectives_button_start">Старт</string>
@ -36,7 +35,6 @@
<string name="objectives_useloop">Отворете съдържанието на Цикъл плъгина.</string>
<string name="objectives_usescale">Използвайте функцията за удължаване на периода на графиката, като задържите върху нея.</string>
<string name="objectives_button_enter">Въведи</string>
<string name="enter_code_obtained_from_developers_to_bypass_the_rest_of_objectives">Ако сте били потребител на OpenAPS и НС има най-малко 3 месеца цикъл на данни, можете да изпращате по електронна поща objectives@androidaps.org с адрес на НС, за да поискате код за заобикаляне на останалите цели. Въведете кода, получен от разработчици</string>
<string name="codeaccepted">Код приет!</string>
<string name="codeinvalid">Неправилен код</string>
<string name="objectives_exam_objective">Докажете знанията си</string>

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<!-- <string name="fi_lang" translatable="false">Finnish</string> -->
<!-- <string name="he_lang" translatable="false">Hebrew</string> -->
@ -946,6 +945,7 @@
<string name="startobjective">Започнете първа цел</string>
<string name="permission">Разрешение</string>
<string name="askforpermission">Питане за разрешение</string>
<string name="needsystemwindowpermission">ААПС изисква разрешение за да може да Ви уведомява</string>
<string name="needlocationpermission">Приложението се нуждае от достъп до вашето местоположение за да активира BT сканиране</string>
<string name="needstoragepermission">Приложението се нуждае от разрешение да съхранява данни за да може съхранява лог файлове</string>
<string name="request">Искане</string>
@ -1446,4 +1446,11 @@
<string name="ebstopsloop">Използване на удължен болус ще спре режим затворен цикъл за времето на болуса. Сигурни ли сте?</string>
<string name="closed_loop_disabled_with_eb">Затворен цикъл е недостъпен поради стартиран Удължен болус</string>
<string name="extended_bolus_short">УБ</string>
<string name="phonechecker">\"PhoneChecker\"</string>
<string name="chartmenu">Меню на графиката</string>
<string name="sensitivity_short">АS</string>
<string name="loop_smbrequest_time_label">Диапазон между изпълнение на SMB</string>
<string name="loop_smbexecution_time_label">Макс. време за изпълнение за SMB</string>
<string name="loop_tbrrequest_time_label">Диапазон между временни базали</string>
<string name="loop_tbrexecution_time_label">Продължителност на временни базали</string>
</resources>

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<string name="dia_whatmeansdia">Co je pravda o DIA?</string>
<string name="dia_label">Téma: Doba trvání účinku inzulínu</string>

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<string name="objectives_button_back">Zpět</string>
<string name="objectives_button_start">Začátek</string>
@ -36,7 +35,7 @@
<string name="objectives_useloop">Zobrazte obsah modulu Smyčka</string>
<string name="objectives_usescale">Přepněte režim zobrazení dlouhým stisknutím grafu glykémie</string>
<string name="objectives_button_enter">Zadat</string>
<string name="enter_code_obtained_from_developers_to_bypass_the_rest_of_objectives">Pokud jste byli dříve uživateli OpenAPS a váš NS má alespoň 3 měsíce dat z používání smyčky, můžete poslat e-mail na adresu objectives@androidaps.org s adresou svého NS a požádat o kód, pomocí něhož budete moci obejít zbývající cíle. Zadejte kód získaný od vývojářů.</string>
<string name="enter_code_obtained_from_developers_to_bypass_the_rest_of_objectives">Pokud máte alespoň 3 měsíce zkušeností s uzavřenou smyčkou na jiných systémech, můžete získat kód, který vám umožní přeskočit cíle. Více informací najdete na https://androidaps.readthedocs.io/en/latest/CROWDIN/cs/Usage/Objectives.html#skip-objectives.</string>
<string name="codeaccepted">Kód přijat</string>
<string name="codeinvalid">Neplatný kód</string>
<string name="objectives_exam_objective">Prokažte své znalosti</string>

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<!-- <string name="fi_lang" translatable="false">Finnish</string> -->
<!-- <string name="he_lang" translatable="false">Hebrew</string> -->
@ -341,7 +340,7 @@
<string name="smscommunicator_tempbasalfailed">Spuštění dočasného bazálu selhalo</string>
<string name="smscommunicator_extendedfailed">Spuštění prodlouženého bolusu selhalo</string>
<string name="smscommunicator_basalstopreplywithcode">Na zastavení dočasného bazálu odpovězte SMS s kódem %1$s</string>
<string name="smscommunicator_extendedstopreplywithcode">Na zastavení prodlouženého bolusu odpovězte SMS s kódem %1$s</string>
<string name="smscommunicator_extendedstopreplywithcode">Pro zastavení prodlouženého bolusu odpovězte SMS s kódem %1$s</string>
<string name="smscommunicator_tempbasalcanceled">Dočasný bazál zastaven</string>
<string name="smscommunicator_extendedcanceled">Prodloužený bolus zastaven</string>
<string name="smscommunicator_tempbasalcancelfailed">Rušení dočasného bazálu selhalo</string>
@ -946,6 +945,7 @@
<string name="startobjective">Spusťte první cíl</string>
<string name="permission">Povolení</string>
<string name="askforpermission">Získat povolení</string>
<string name="needsystemwindowpermission">Pro oznámení vyžaduje aplikace oprávnění systémového okna</string>
<string name="needlocationpermission">Aplikace vyžaduje povolení \"umístění\", aby mohla vyhledávat BT zařízení</string>
<string name="needstoragepermission">Aplikace vyžaduje přístup k úložišti, aby mohla ukládat logy</string>
<string name="request">Požadavek</string>
@ -1443,8 +1443,15 @@
<string name="alreadyset">Již nastaveno</string>
<string name="message">Zpráva</string>
<string name="clearqueueconfirm">Vymazat frontu? Všechna data ve frontě budou ztracena!</string>
<string name="ebstopsloop">Použití funkce rozloženého bolusu zastaví uzavřenou smyčku po dobu trvání rozloženého bolusu. Opravdu to chcete?</string>
<string name="closed_loop_disabled_with_eb">Uzavřená smyčka je zastavena kvůli běžícímu rozloženému bolusu</string>
<string name="ebstopsloop">Použití funkce prodlouženého bolusu zastaví uzavřenou smyčku po dobu trvání prodlouženého bolusu. Opravdu to chcete?</string>
<string name="closed_loop_disabled_with_eb">Uzavřená smyčka je zastavena kvůli běžícímu prodlouženému bolusu</string>
<string name="extended_bolus_short">EB</string>
<string name="phonechecker">PhoneChecker</string>
<string name="chartmenu">Možnosti grafu</string>
<string name="sensitivity_short">AS</string>
<string name="loop_smbrequest_time_label">Čas požadavku SMB</string>
<string name="loop_smbexecution_time_label">Čas provedení SMB</string>
<string name="loop_tbrrequest_time_label">Čas požadavku dočasného bazálu</string>
<string name="loop_tbrexecution_time_label">Čas provedení dočasného bazálu</string>
<string name="insight_alert_notification_channel">Upozornění pumpy Insight</string>
</resources>

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<string name="objectives_button_back">Zurück</string>
<string name="objectives_button_start">Start</string>
@ -37,7 +36,7 @@ die Formel maxIOB = durchschnittlicher Essensbolus + 3 x höchste Basalrate</str
<string name="objectives_useloop">Zeige den Inhalt des Loop-Plugins an</string>
<string name="objectives_usescale">Nutze die Skalierfunktion. Drücke dazu lange auf das BZ-Diagramm</string>
<string name="objectives_button_enter">OK</string>
<string name="enter_code_obtained_from_developers_to_bypass_the_rest_of_objectives">Wenn Du früher bereits OpenAPS genutzt hast und auf Deiner Nightscout-Seite mindestens drei Monate Closed-Loop-Daten ersichtlich sind, kannst Du eine E-Mail an objectives@androidaps.org mit Deiner NS-URL und Deinem Anforderungscode senden, um die restlichen Ziele zu überspringen. Code eingeben, der von den Entwicklern übermittelt wurde:</string>
<string name="enter_code_obtained_from_developers_to_bypass_the_rest_of_objectives">Wenn Du mindestens 3 Monate Closed-Loop-Erfahrung mit einem anderen System hast, kannst Du evtl. einen Code zum Überspringen der Objektives erhalten. Weitere Details unter https://androidaps.readthedocs.io/en/latest/CROWDIN/de/Usage/Objectives.html#objectives-ziele-uberspringen.</string>
<string name="codeaccepted">Code akzeptiert</string>
<string name="codeinvalid">Code ungültig</string>
<string name="objectives_exam_objective">Prüfe Dein Wissen</string>

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<!-- <string name="fi_lang" translatable="false">Finnish</string> -->
<!-- <string name="he_lang" translatable="false">Hebrew</string> -->
@ -686,7 +685,7 @@
<string name="shortgramm">g</string>
<string name="shortminute">min</string>
<string name="shorthour">h</string>
<string name="shortday">T</string>
<string name="shortday">d</string>
<string name="none"><![CDATA[<nichts>]]></string>
<string name="shortkilojoul">kJ</string>
<string name="shortenergy">En</string>
@ -846,7 +845,7 @@
<string name="combo_error_failure_reading_changed_basal_rate">Das Einlesen der geänderten Basalrate in der Pumpe schlug fehl</string>
<string name="combo_activity_checking_for_history_changes">Änderungen der Historie werden gesucht</string>
<string name="combo_error_multiple_boluses_with_identical_timestamp">Der Import mehrerer Boli der gleichen Menge, abgegeben in der gleichen Minute, ist gescheitert: Nur ein Datensatz konnte den Behandlungen hinzugefügt werden. Bitte überprüfe die Pumpe und verwende das Careportal, um fehlende Einträge hinzuzufügen. Stelle sicher, dass keine Einträge für genau dieselbe Minute mit derselben Menge hinzugefügt werden.</string>
<string name="about_link_urls">\n\nhttp://www.androidaps.org\nhttp://www.androidaps.de (de)\n\nSupport:\nhttps://de.loopercommunity.org/ (de)\nhttp://facebook.androidaps.org</string>
<string name="about_link_urls">\n\nhttp://www.androidaps.org\nhttp://www.androidaps.de (de)\n\nSupport:\nhttps://de.loopercommunity.org/\nhttp://facebook.androidaps.org</string>
<string name="combo_check_date">Der letzte Bolus liegt mehr als 24 Stunden zurück oder liegt in der Zukunft. Prüfe bitte das Datum auf der Pumpe.</string>
<string name="combo_suspious_bolus_time">Zeit/Datum des abgegebenen Boluses auf der Pumpe erscheint falsch, IOB ist wahrscheinlich nicht korrekt. Bitte prüfe Zeit/Datum der Pumpe.</string>
<string name="profileswitch_ismissing">Profil-Wechsel fehlt, bitte nimm einen Profil-Wechsel vor oder drücke \"AKTIVIERE PROFIL\" im lokalen Profil.</string>
@ -946,6 +945,7 @@
<string name="startobjective">Starte deine erste Zielsetzung</string>
<string name="permission">Berechtigung</string>
<string name="askforpermission">Nach Berechtigung fragen</string>
<string name="needsystemwindowpermission">Die App benötigt die Systemberechtigung für App-Benachrichtigungen</string>
<string name="needlocationpermission">AndroidAPS benötigt die Standortfreigabe für den BT-Scan.</string>
<string name="needstoragepermission">AndroidAPS benötigt Zugriff auf den Speicher, um Log-Dateien speichern zu können.</string>
<string name="request">Anfordern</string>
@ -1446,8 +1446,13 @@ Unerwartetes Verhalten.</string>
<string name="clearqueueconfirm">Warteschlange löschen? Alle Daten in der Warteschlange gehen verloren!</string>
<string name="ebstopsloop">Die Verwendung eines Verzögerungsbolus unterbricht dem Closed Loop Modus für die Dauer des Verzögerungsbolus. Willst Du das wirklich?</string>
<string name="closed_loop_disabled_with_eb">Closed Loop wegen Verzögerungsbolus unterbrochen</string>
<string name="extended_bolus_short">VB</string>
<string name="extended_bolus_short">VerzB</string>
<string name="phonechecker">\"PhoneChecker\"</string>
<string name="chartmenu">Diagrammmenü</string>
<string name="sensitivity_short">AS</string>
<string name="loop_smbrequest_time_label">SMB Anfragezeit</string>
<string name="loop_smbexecution_time_label">SMB Ausführungszeit</string>
<string name="loop_tbrrequest_time_label">Temp. BR Anfragezeit</string>
<string name="loop_tbrexecution_time_label">Temp. BR Ausführungszeit</string>
<string name="insight_alert_notification_channel">Insight Pumpenalarme</string>
</resources>

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<string name="objectives_button_back">Πίσω</string>
<string name="objectives_button_start">Έναρξη</string>

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<!-- <string name="fi_lang" translatable="false">Finnish</string> -->
<!-- <string name="he_lang" translatable="false">Hebrew</string> -->

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<string name="objectives_button_back">Atrás</string>
<string name="objectives_button_start">Inicio</string>
@ -36,7 +35,6 @@
<string name="objectives_useloop">Mostrar contenido del plugin Loop</string>
<string name="objectives_usescale">Usar función de escala mediante un gráfico BG pulsado largo</string>
<string name="objectives_button_enter">Intro</string>
<string name="enter_code_obtained_from_developers_to_bypass_the_rest_of_objectives">Si fuiste usuario de OpenAPS y tu NS tiene al menos 3 meses de datos de lazo cerrado, puedes enviar un correo electrónico a objectives@androidaps.org con tu dirección web de NS y solicitar código para saltarse el resto de objetivos. Ingresa posteriormente el código obtenido de los desarrolladores</string>
<string name="codeaccepted">Código aceptado</string>
<string name="codeinvalid">Código no válido</string>
<string name="objectives_exam_objective">Compruebe su conocimiento</string>

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<!-- <string name="fi_lang" translatable="false">Finnish</string> -->
<!-- <string name="he_lang" translatable="false">Hebrew</string> -->
@ -1446,4 +1445,8 @@
<string name="ebstopsloop">El uso de la función de bolo extendido detendrá el modo de bucle cerrado durante el tiempo de ejecución del bolo extendido. ¿Realmente quieres esto?</string>
<string name="closed_loop_disabled_with_eb">Bucle cerrado inhabilitado debido a la ejecución del bolo extendido</string>
<string name="extended_bolus_short">EB</string>
<string name="chartmenu">Menú gráfico</string>
<string name="sensitivity_short">AS</string>
<string name="loop_smbrequest_time_label">Tiempo requerido de SMB</string>
<string name="loop_smbexecution_time_label">Tiempo de ejecución de SMB</string>
</resources>

View file

@ -1,3 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources></resources>

View file

@ -1,3 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources></resources>

View file

@ -1,3 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources></resources>

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<!-- <string name="fi_lang" translatable="false">Finnish</string> -->
<!-- <string name="he_lang" translatable="false">Hebrew</string> -->

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<string name="objectives_button_back">Retour</string>
<string name="objectives_button_start">Départ</string>
@ -36,7 +35,6 @@
<string name="objectives_useloop">Affichage du contenu du plugin Boucle</string>
<string name="objectives_usescale">Modification de l\'échelle du graphique par un appui long sur la courbe de glycémie</string>
<string name="objectives_button_enter">Entrer</string>
<string name="enter_code_obtained_from_developers_to_bypass_the_rest_of_objectives">Si vous étiez avant un utilisateur d\'OpenAPS et que votre NS a au moins 3 mois de données de bouclage, vous pouvez envoyer un e-mail à objectives@androidaps.org avec votre adresse NS et demander un code pour contourner le reste des objectifs. Entrez le code obtenu auprès des développeurs</string>
<string name="codeaccepted">Code accepté</string>
<string name="codeinvalid">Code invalide</string>
<string name="objectives_exam_objective">Prouver ses connaissances</string>

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<!-- <string name="fi_lang" translatable="false">Finnish</string> -->
<!-- <string name="he_lang" translatable="false">Hebrew</string> -->
@ -43,10 +42,10 @@
<string name="description_pump_dana_rs">Intégration pour les pompes Diabecare DANA RS</string>
<string name="description_pump_mdi">Intégration pompe pour les personnes qui font des injections quotidiennes multiples pour le traitement de leur diabète</string>
<string name="description_pump_virtual">Intégration pour les pompes qui nont pas encore de pilote (Boucle Ouverte)</string>
<string name="description_sensitivity_aaps">La Sensibilité est calculée de la même manière que Oref0, mais vous pouvez spécifier la periode concernée. L\'absorption minimale des glucides est calculée à partir des temps dabsorption max des glucides du menu préférences.</string>
<string name="description_sensitivity_oref0">Sensibilité est calculée à partir des données sur les dernières 24h et les glucides (non absorbés) ne sont plus pris en compte après lheure spécifiée dans les préférences.</string>
<string name="description_sensitivity_oref1">Sensibilité est calculée à partir des données des dernières 8 heures et des glucides (si non absorbés) ne sont plus pris en compte après le temps spécifié dans les préférences. Plugin calcule également RNS (UAM).</string>
<string name="description_sensitivity_weighted_average">Sensibilité est calculée comme une moyenne pondérée des écarts. Les écarts les plus récents ont un poids plus élevé. L\'absorption minimale des glucides est calculée à partir des temps dabsorption des glucides max du menu préférences. Cet algorithme est le plus rapide pour s\'adapter aux changements de sensibilité.</string>
<string name="description_sensitivity_aaps">La sensibilité est calculée de la même manière que Oref0, mais vous pouvez spécifier la période concernée. L\'absorption minimale des glucides est calculée à partir des temps dabsorption max des glucides du menu préférences.</string>
<string name="description_sensitivity_oref0">La sensibilité est calculée à partir des données sur les dernières 24h et les glucides (si non absorbés) ne sont plus pris en compte après lheure spécifiée dans les préférences.</string>
<string name="description_sensitivity_oref1">La sensibilité est calculée à partir des données des dernières 8 heures et les glucides (si non absorbés) ne sont plus pris en compte après le temps spécifié dans les préférences. Le plugin calcule également les RNS (UAM).</string>
<string name="description_sensitivity_weighted_average">La sensibilité est calculée comme une moyenne pondérée des écarts. Les écarts les plus récents ont un poids plus élevé. L\'absorption minimale des glucides est calculée à partir des temps dabsorption des glucides max du menu préférences. Cet algorithme est le plus rapide pour s\'adapter aux changements de sensibilité.</string>
<string name="description_source_eversense">Recevoir les valeurs de glycémie de lapp Eversense patchée.</string>
<string name="description_source_glimp">Recevoir les glycémies depuis Glimp.</string>
<string name="description_source_mm640g">Recevoir les glycémies depuis le 600SeriesAndroidUploder.</string>
@ -146,7 +145,7 @@
<string name="overview_newtempbasal_basalpercent">Valeur Basal [%]</string>
<string name="setbasalquestion">Accepter nouveau basal temporaire :</string>
<string name="overview_treatment_label">Traitement</string>
<string name="overview_calculator_label">Calculatrice</string>
<string name="overview_calculator_label">Assistant</string>
<string name="constraintapllied">Restriction appliquée !</string>
<string name="confirmation">Confirmation</string>
<string name="bolus">Bolus</string>
@ -157,7 +156,7 @@
<string name="changeyourinput">Changez vos entrées !</string>
<string name="configbuilder_bgsource">Source des glycémies</string>
<string name="configbuilder_bgsource_description">Quelle source de données doit être utilisée par AndroidAPS ?</string>
<string name="xdrip">xDrip</string>
<string name="xdrip">xDrip+</string>
<string name="apsmode_title">Mode APS</string>
<string name="closedloop">Boucle Fermée</string>
<string name="openloop">Boucle Ouverte</string>
@ -196,7 +195,7 @@
<string name="careportal_newnstreatment_sensor">Capteur</string>
<string name="careportal_newnstreatment_carbs_label">Glucides</string>
<string name="careportal_newnstreatment_insulin_label">Insuline</string>
<string name="careportal_newnstreatment_carbtime_label">Heure glucides</string>
<string name="careportal_newnstreatment_carbtime_label">Décalage horaire</string>
<string name="careportal_newnstreatment_split_label">Diviser</string>
<string name="careportal_newnstreatment_duration_label">Durée</string>
<string name="careportal_newnstreatment_percent_label">Pourcentage</string>
@ -220,7 +219,7 @@
<string name="nav_import">Importer les paramètres</string>
<string name="openapsma_maxbasal_title">Max. U/hr pour le débit temp Basal</string>
<string name="openapsma_maxbasal_summary">Cette valeur est appelée Basal Maximum dans le contexte OpenAPS</string>
<string name="openapsma_maxiob_title">Le Basal IA maximum que l\'OpenAPS pourra délivrer [U]</string>
<string name="openapsma_maxiob_title">IA basale max que OpenAPS pourra délivrer [U]</string>
<string name="openapsma_maxiob_summary">Cette valeur est appelée Max IA (Insuline Active) dans le contexte OpenAPS\nC\'estlle maximum d\'insuline en [U] que APS peut délivrer en une seule fois.</string>
<string name="dismiss">FERMER</string>
<string name="danarpump">DanaR</string>
@ -385,7 +384,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="resend_all_data">Renvoyer toutes les données</string>
<string name="open_settings_on_wear">Afficher les Paramètres sur la Montre</string>
<string name="pumperror">Erreur Pompe</string>
<string name="lowbattery">Niveau Batterie Bas</string>
<string name="lowbattery">Piles Faibles</string>
<string name="pumpshutdown">Arrêt de la Pompe</string>
<string name="batterydischarged">Batterie Pompe Déchargée</string>
<string name="danarkoreanpump">DanaR Coréenne</string>
@ -438,7 +437,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="loop_shortname">BOUCLE</string>
<string name="simpleprofile_shortname">P.S.</string>
<string name="oaps_shortname">OAPS</string>
<string name="localprofile_shortname">P.L.</string>
<string name="localprofile_shortname">PL</string>
<string name="danarpump_shortname">DANA</string>
<string name="overview_shortname">ACCUEIL</string>
<string name="virtualpump_shortname">POMPEV</string>
@ -457,7 +456,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="openapsama_max_daily_safety_multiplier_summary">Valeur par défaut : 3 Ceci est un paramètre important de sécurité de lOpenAPS. Ceci va limiter vos débits basal à 3 fois votre débit Basal maximum. Il est probable que vous naurez pas besoin de changer cela, mais vous devez être conscient de ce qui est discuté pour les limites de sécurité dans “3x max daily; 4x current”.</string>
<string name="openapsama_current_basal_safety_multiplier_summary">Valeur par défaut : 4 Ceci est lautre moitié des paramètres de sécurité limitant lOpenAPS, et lautre moitié de “3x max daily, 4x current” des paramètres de sécurité. Quel que soit le basal maximum prédéfini dans votre pompe, il ne pourra pas être plus haut que ce nombre multiplié par le Basal actuel. Ceci est fait pour ne pas mettre lutilisateur en danger en programmant des débits Basal maximum trop élevés avant de comprendre comment lalgorithme fonctionne. Encore une fois, la valeur par défaut est 4x, la plupart des gens nauront jamais besoin dajuster ce paramètre, plutôt ils auront tendance à ajuster dautres paramètres sils voient quils atteignent ce paramètre de limite de sécurité.</string>
<string name="openapsama_autosens_max_summary">Valeur par défaut: 1.2\nCeci est la limite du multiplicateur utilisé par Autosens (et bientôt Autotune) pour définir +20%% en limite maximale du ratio Autosens. En consequence, ceci dit va définir la valeur maximale du Basal pour Autosens, la valeur minimale de la Sensibilité à l\'Insuline (SI, ISF), et la valeur minimale de la cible glycémique.</string>
<string name="openapsama_autosens_min_summary">Valeur par défaut: 0.7\nLautre aspect pour les limites de sécurité pour Autosens. Cette valeur va créer une limite qui définit jusqu\'à quelle valeur minimale Autosens va pouvoir ajuster le basal , et jusqu\'à quelles valeurs maximales Autosens pourra ajuster la Sensibilité à l\'Insuline (SI, ISF) et les cibles glycémiques.</string>
<string name="openapsama_autosens_min_summary">Valeur par défaut: 0,7\nL\'autre volet des limites de sécurité de l\'autosens, c\'est de définir une limite basse sur l\'ajustement des débits de basal et une limite haute sur l\'ajustement de la SI et des cibles GLY effectués par l\'autosens.</string>
<string name="openapsama_autosens_adjusttargets">Autosens ajuste aussi les cibles</string>
<string name="openapsama_autosens_adjusttargets_summary">Valeur par défaut : true\nCeci est utilisé pour autoriser Autosens à ajuster les cibles de glycémie en plus de SI et les basals.</string>
<string name="openapsama_bolussnooze_dia_divisor_summary">Valeur par défaut : 2\nBolus snooze est activé apres votre bolus de repas, la boucle ne réagira pas avec des valeurs basses temporaire quand vous venez juste de manger. Lexemple ici et la valeur par défaut est 2 ; donc avec une Durée d\'Action (DIA) de 3 heures signifie que snooze bolus sera graduellement éliminé après 1,5 heures (3DIA/2).</string>
@ -544,7 +543,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="treatments_wizard_cob_label">GA</string>
<string name="superbolus">Superbolus</string>
<string name="ns_logappstartedevent">Démarrage AAPS entré dans NS</string>
<string name="restartingapp">Sortie de lapplication pour appliquer de nouveaux paramètres.</string>
<string name="restartingapp">Sortir de lapplication pour appliquer les nouveaux paramètres.</string>
<string name="danarv2pump">DanaRv2</string>
<string name="configbuilder_insulin">Insuline</string>
<string name="configbuilder_insulin_description">Quel type d\'insuline utilisez-vous ?</string>
@ -566,7 +565,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="virtualpump_firmware_label">Firmware</string>
<string name="pump_lastconnection_label">Dernière connexion</string>
<string name="danar_bluetooth_status">État Bluetooth</string>
<string name="nav_about">À propos de</string>
<string name="nav_about">À propos</string>
<string name="smscommunicator_missingsmspermission">Autorisation SMS manquante</string>
<string name="smscommunicator_missingphonestatepermission">Autorisation du téléphone manquante</string>
<string name="xdripstatus_settings">état Xdrip (montre)</string>
@ -644,7 +643,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="insulin_peak_time">Temps du Pic [min]</string>
<string name="free_peak_oref">Profil d\'insuline ajustable Oref</string>
<string name="rapid_acting_oref">Insuline à Action Rapide Oref </string>
<string name="ultrarapid_oref">Insuline à Action Ultra Rapide Oref</string>
<string name="ultrarapid_oref">Insuline Ultra Rapide Oref</string>
<string name="dia_too_short">Durée dAction pour %1$f trop courte - utiliser %2$f à la place !</string>
<string name="activate_profile">Activer le profil</string>
<string name="date"> Date</string>
@ -701,7 +700,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="pumpdrivercorrected">Pilote pompe corrigé</string>
<string name="pump_unreachable">Pompe hors de portée</string>
<string name="missed_bg_readings">Valeurs de glycémie manquantes</string>
<string name="raise_notifications_as_android_notifications">Utiliser le système des notifications</string>
<string name="raise_notifications_as_android_notifications">Utiliser les notifications système pour les alertes et notifications</string>
<string name="localalertsettings_title">Alertes locales</string>
<string name="enable_missed_bg_readings_alert">Alerte pas nouvelle donnée glycémique</string>
<string name="enable_pump_unreachable_alert">Alerte si la pompe est hors de portée</string>
@ -766,7 +765,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="danar_history">Historique pompe</string>
<string name="combo_activity_setting_basal_profile">Définir le profil basal</string>
<string name="combo_pump_cartridge_low_warrning">Niveau réservoir pompe bas</string>
<string name="combo_pump_battery_low_warrning">Niveau batterie pompe bas</string>
<string name="combo_pump_battery_low_warrning">Pile pompe faible</string>
<string name="combo_is_in_error_state">La pompe affiche lerreur E%1$d: %2$s</string>
<string name="combo_reservoir_low">Bas</string>
<string name="combo_reservoir_empty">Vide</string>
@ -885,7 +884,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="reset">réinitialiser</string>
<string name="waitingfortimesynchronization">En attente de synchronisation de l\'heure (%1$d sec)</string>
<string name="loopdisconnectedfor">Déconnecté (%1$d m)</string>
<string name="openapssmb_maxiob_title">Maximum Insuline Active IA pour OpenAPS [U]</string>
<string name="openapssmb_maxiob_title">IA totale maximale pour OpenAPS [U]</string>
<string name="openapssmb_maxiob_summary">Cette valeur est appelée Max IA (Insuline Active) dans le contaxte OpenAPS\nOpenAPS najoutera pas plus dinsuline si l\'IA (Insuline Active) actuelle est supérieure à cette valeur</string>
<string name="pump_stopped">Pompe arrêtée</string>
<string name="pump_started">Pompe démarrée</string>
@ -909,15 +908,15 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="cgm">MGC</string>
<string name="ns_wifionly">Utilisez uniquement connexion Wi-fi</string>
<string name="ns_wifi_ssids">Wi-fi SSID</string>
<string name="ns_chargingonly">Wi-fi uniquement pendant la charge</string>
<string name="ns_chargingonly">Uniquement si en charge</string>
<string name="connectionsettings_title">Paramètres de connexion</string>
<string name="ns_wifi_allowedssids">SSIDs autorisés (séparés par point-virgule)</string>
<string name="ns_allowroaming">Autoriser connexion données itinérance</string>
<string name="openapsama_autosens_max">Maximum Ratio Autosens</string>
<string name="openapsama_autosens_min">Minimum Ratio Autosens</string>
<string name="openapsama_bolussnooze_dia_divisor">Diviseur de Bolus snooze DIA</string>
<string name="openapsama_max_daily_safety_multiplier">Maximum multiplicateur quotidien de sécurité</string>
<string name="openapsama_current_basal_safety_multiplier">Multiplicateur actuel de sécurité du Basal</string>
<string name="openapsama_bolussnooze_dia_divisor">Snooze bolus Diviseur de DAI</string>
<string name="openapsama_max_daily_safety_multiplier">Multiplicateur max quotidien de sécurité</string>
<string name="openapsama_current_basal_safety_multiplier">Multiplicateur de sécurité basale courante</string>
<string name="value_unavailable_short">ND</string>
<string name="virtualpump_type">Type de pompe virtuelle</string>
<string name="virtualpump_definition">Définition de pompe</string>
@ -947,6 +946,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="startobjective">Démarrez votre premier objectif</string>
<string name="permission">Autorisation</string>
<string name="askforpermission">Demande d\'autorisation</string>
<string name="needsystemwindowpermission">L\'application a besoin de l\'autorisation d\'accès à la fenêtre système pour les notifications</string>
<string name="needlocationpermission">L\'application requiert l\'autorisation de localisation pour le balayage Bluetooth</string>
<string name="needstoragepermission">L\'application requiert une autorisation de stockage de données afin de pouvoir sauvegarder les fichiers journaux</string>
<string name="request">Demande</string>
@ -984,7 +984,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="combo_invalid_setup">Paramétrage de la pompe invalide. Vérifiez la documentation et le menu QUICK INFO en utilisant le logiciel de configuration 360.</string>
<string name="custom">Personnalisé</string>
<string name="largetimedifftitle">Différence horaire importante</string>
<string name="largetimediff">La différence horaire importante:\nTime avec la pompe de plus d\'1,5 heure.\nMerci d\'ajuster manuellement l\'heure de la pompe et assurez-vous que la lecture de l\'historique de la pompe ne cause pas de dysfonctionnements.\nSi possible, effacez l\'historique de la pompe avant de modifier l\'heure ou désactivez la Boucle Fermée pour une DIA après la dernière entrée erronée de l\'historique et en tout état de cause au minimum une DIA à partir de maintenant.</string>
<string name="largetimediff">Différence horaire importante:\nL\'heure de la pompe est en écart de plus d\'une heure et demi.\nMerci d\'ajuster manuellement l\'heure de la pompe et assurez-vous que la lecture de l\'historique de la pompe ne cause pas de dysfonctionnements.\nSi possible, effacez l\'historique de la pompe avant de modifier l\'heure ou désactivez la Boucle Fermée pour une DAI après la dernière entrée erronée de l\'historique et au minimum une DAI à partir de maintenant.</string>
<string name="careportal_removestartedevents">Réinitialiser AndroidAPS</string>
<string name="storedsettingsfound">Paramètres sauvegardés trouvés</string>
<string name="allow_hardware_pump_text">ATTENTION : Si vous activez et connectez à une vraie pompe, AndroidAPS copiera les paramètres Basals du profil vers la pompe, écrasant le taux basal existant stocké sur la pompe. Assurez-vous d\'avoir correctement saisi et réglé les paramètres Basal dans AndroidAPS. Si vous ne savez pas ou si ne voulez pas écraser les paramètres Basal sur votre pompe, appuyez sur Annuler et reporter le passage à la pompe à une date ultérieure.</string>
@ -1015,7 +1015,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="commanderror">Erreur de commande</string>
<string name="speederror">Erreur de vitesse</string>
<string name="insulinlimitviolation">Violation d\'une limite d\'insuline</string>
<string name="loop_openmode_min_change">Changement minimum possible [%]</string>
<string name="loop_openmode_min_change">Changement minimum [%]</string>
<string name="loop_openmode_min_change_summary">Le fonctionnement de la Boucle demandera une confirmation uniquement si le changement est supérieur à cette valeur en %. Par défaut, la valeur est 20%</string>
<string name="pairfirst">Appairez SVP votre pompe avec votre téléphone !</string>
<string name="searching_for_devices">Recherche d\'appareils en cours…</string>
@ -1244,7 +1244,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="medtronic_pump_frequency_worldwide">Mondial (868 Mhz)</string>
<string name="medtronic_pump_encoding_4b6b_local">Encodage logiciel 4b6b</string>
<string name="medtronic_pump_encoding_4b6b_rileylink">Encodage matériel 4b6b</string>
<string name="medtronic_custom_action_wake_and_tune">Réveil et mise au point</string>
<string name="medtronic_custom_action_wake_and_tune">Réveil et Réglage</string>
<string name="medtronic_custom_action_clear_bolus_block">Effacer le bloc Bolus</string>
<string name="medtronic_custom_action_reset_rileylink">Réinitialiser la config. RileyLink</string>
<string name="medtronic_pump_battery_select">Type de batterie (vue d\'alimentation)</string>
@ -1270,8 +1270,8 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<!-- RL Status Page -->
<string name="rileylink_settings_tab1">Paramètres</string>
<string name="rileylink_settings_tab2">Historique</string>
<string name="rileylink_status">Statut du RileyLink</string>
<string name="medtronic_pump_status">Statut de la pompe</string>
<string name="rileylink_status">État du RileyLink</string>
<string name="medtronic_pump_status">État de la pompe</string>
<string name="title_activity_rileylink_settings">Paramètres RileyLink</string>
<string name="rileylink_title">RileyLink</string>
<string name="rileylink_configured_address">Adresse configurée</string>
@ -1300,7 +1300,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="rileylink_error_bt_disabled">Bluetooth est désactivé</string>
<string name="rileylink_error_no_bt_adapter">Aucun adaptateur Bluetooth</string>
<string name="rileylink_error_tuneup_failed">Échec du réglage</string>
<string name="rileylink_error_pump_unreachable">Pompe inaccessible</string>
<string name="rileylink_error_pump_unreachable">Pompe hors de portée</string>
<string name="rileylink_error_pod_unreachable">Pod inaccessible</string>
<string name="rileylink_error_address_not_set_short">Non configuré</string>
<!-- RL Target Device -->
@ -1396,7 +1396,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="format_carbs">%1$dg</string>
<string name="common_on">On</string>
<string name="common_off">Off</string>
<string name="objectives_button_unfinish">Suppression terminée</string>
<string name="objectives_button_unfinish">Refaire l\'objectif</string>
<string name="objectives_button_unstart">Suppression démarrée</string>
<string name="timedetection">Détection de temps</string>
<string name="doyouwantresetstart">Voulez-vous réinitialiser le début de l\'objectif ? Vous risquez de perdre vos progrès.</string>
@ -1425,10 +1425,10 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="invalidage">Âge invalide</string>
<string name="invalidweight">Poids invalide</string>
<string name="tddformat"><![CDATA[<b>%1$s:</b> ∑: <b>%2$.2f</b> Bol: <b>%3$.2f</b> Bas: <b>%4$.2f</b>]]></string>
<string name="tirformat"><![CDATA[<b>%1$s:</b> Bas: <b>%2$02d%%</b> Médian: <b>%3$02d%%</b> Haut: <b>%4$02d%%</b>]]></string>
<string name="tirformat"><![CDATA[<b>%1$s:</b> Bas: <b>%2$02d%%</b> Cible: <b>%3$02d%%</b> Haut: <b>%4$02d%%</b>]]></string>
<string name="average">Moyenne</string>
<string name="tdd">DTI</string>
<string name="tir">TIR</string>
<string name="tir">Cible Gly</string>
<string name="activitymonitor">Moniteur d\'activité</string>
<string name="doyouwantresetstats">Voulez-vous réinitialiser les stats d\'activité ?</string>
<string name="statistics">Statistiques</string>
@ -1448,4 +1448,11 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="closed_loop_disabled_with_eb">Boucle fermée désactivée à cause du bolus étendu</string>
<string name="extended_bolus_short">EB</string>
<string name="phonechecker">\"Vérif. du téléphone\"</string>
<string name="chartmenu">Menu Graph</string>
<string name="sensitivity_short">AS</string>
<string name="loop_smbrequest_time_label">Heure de demande SMB</string>
<string name="loop_smbexecution_time_label">Heure d\'exécution SMB</string>
<string name="loop_tbrrequest_time_label">Heure de demande basal temp</string>
<string name="loop_tbrexecution_time_label">Heure d\'exécution basal temp</string>
<string name="insight_alert_notification_channel">Alertes Pompe Insight</string>
</resources>

View file

@ -1,3 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources></resources>

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<!-- <string name="fi_lang" translatable="false">Finnish</string> -->
<!-- <string name="he_lang" translatable="false">Hebrew</string> -->

View file

@ -1,3 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources></resources>

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<!-- <string name="fi_lang" translatable="false">Finnish</string> -->
<!-- <string name="he_lang" translatable="false">Hebrew</string> -->

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<string name="dia_whatmeansdia">Cosa è vero riguardo DIA?</string>
<string name="dia_label">Argomento: Durata dell\'Azione dell\'Insulina</string>
@ -47,8 +46,8 @@
<string name="exercise_switchprofilebelow100">Fare un cambio profilo sotto il 100%.</string>
<string name="exercise_switchprofileabove100">Fare un cambio profilo sopra il 100%.</string>
<string name="exercise_stoploop">Stoppare il loop.</string>
<string name="exercise_doitbeforestart">Impostare un temp-target \"attività\" prima dell\'inizio dell\'esercizio fisico.</string>
<string name="exercise_afterstart">L\'impostazione di un temp-target \"attività\" dopo l\'inizio dell\'esercizio fisico porta a risultati peggiori rispetto all\'avviarlo prima dell\'inizio dell\'esercizio.</string>
<string name="exercise_doitbeforestart">Impostare un temp-target \"attività fisica\" prima dell\'inizio dell\'esercizio fisico.</string>
<string name="exercise_afterstart">L\'impostazione di un temp-target \"attività fisica\" dopo l\'inizio dell\'esercizio fisico porta a risultati peggiori rispetto all\'avviarlo prima dell\'inizio dell\'esercizio.</string>
<string name="exercise_hint1">https://androidaps.readthedocs.io/en/latest/EN/Usage/temptarget.html#activity-temp-target</string>
<string name="suspendloop_label">Argomento: Loop Disabilitato/Sospeso</string>
<string name="suspendloop_doigetinsulin">Ricevo insulina quando il loop è disabilitato/sospeso?</string>

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<string name="alert_r1_title">Eroga bolo</string>
<string name="alert_r2_title">Bolo perso</string>
@ -10,8 +9,8 @@
<string name="alert_w32_title">Batteria quasi scarica</string>
<string name="alert_w33_title">Ora/data non valida</string>
<string name="alert_w34_title">Fine della garanzia</string>
<string name="alert_w36_title">TBR annullato</string>
<string name="alert_w38_title">Bolo annullato</string>
<string name="alert_w36_title">TBR cancellato</string>
<string name="alert_w38_title">Bolo cancellato</string>
<string name="alert_w39_title">Avviso di prestito</string>
<string name="alert_m20_title">Cartuccia non inserita</string>
<string name="alert_m21_title">Cartuccia vuota</string>

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<string name="connection_failed">Connessione fallita</string>
<string name="connection_lost">Connessione persa</string>
@ -7,9 +6,9 @@
<string name="socket_creation_failed">Creazione socket fallita</string>
<string name="timeout">Timeout</string>
<string name="maximum_number_of_bolus_type_already_running">Numero massimo tipo di bolo già in esecuzione</string>
<string name="no_active_tbr_to_cancel">Nessun TBR attivo da annullare</string>
<string name="no_active_tbr_to_cancel">Nessun TBR attivo da cancellare</string>
<string name="no_active_tbr_to_change">Nessun TBR attivo da modificare</string>
<string name="no_such_bolus_to_cancel">Nessun bolo da annullare</string>
<string name="no_such_bolus_to_cancel">Nessun bolo da cancellare</string>
<string name="pump_already_in_that_state_exception">Micro già in questo stato</string>
<string name="run_mode_not_allowed">Modalità di esecuzione non consentita</string>
</resources>

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<string name="objectives_button_back">Indietro</string>
<string name="objectives_button_start">Avvia</string>
@ -18,14 +17,14 @@
<string name="objectives_maxiob_objective">Regolazione del loop chiuso, aumentando max IOB al di sopra di 0 e abbassando gradualmente i target glicemici</string>
<string name="objectives_maxiob_gate">Esegui l\'applicazione per alcuni giorni e almeno una notte senza allarmi di glicemia bassa, prima di abbassare il target glicemico</string>
<string name="objectives_autosens_objective">Adatta basali e rapporti se necessario, quindi attiva auto-sens</string>
<string name="objectives_autosens_gate">1 settimana di looping diurno con dichiarazione regolare dei carboidrati, eseguito con successo</string>
<string name="objectives_autosens_gate">1 settimana di looping diurno con inserimento regolare dei carboidrati, eseguito con successo</string>
<string name="objectives_ama_objective">Abilitazione funzioni aggiuntive per l\'uso diurno, ad esempio AMA (advanced meal assist - assistenza avanzata del pasto)</string>
<string name="objectives_smb_objective">Abilitazione funzioni aggiuntive per l\'uso diurno, come SMB</string>
<string name="objectives_smb_gate">È necessario leggere il wiki e aumentare maxIOB affinché le azioni di SMB funzionino adeguatamente! Un buon inizio è maxIOB = media bolo posto + 3 x max basale giornaliera</string>
<string name="objectives_bgavailableinns">Glicemia disponibile in NS</string>
<string name="objectives_pumpstatusavailableinns">Stato micro disponibile in NS</string>
<string name="objectives_manualenacts">Attivazioni manuali</string>
<string name="accomplished">Compiuto: %1$s</string>
<string name="accomplished">Completato: %1$s</string>
<string name="objectives_usage_objective">Impara a controllare AndroidAPS</string>
<string name="objectives_usage_gate">Esegui varie azioni in AndroidAPS</string>
<string name="objectives_useprofileswitch">Imposta il profilo \"90%\" per 10 min (premi a lungo sul nome profilo nella sezione Panoramica)</string>
@ -36,7 +35,7 @@
<string name="objectives_useloop">Visualizza il contenuto del plugin Loop</string>
<string name="objectives_usescale">Usa la funzione di ridimensionamento premendo a lungo sul grafico delle glicemie</string>
<string name="objectives_button_enter">Entra</string>
<string name="enter_code_obtained_from_developers_to_bypass_the_rest_of_objectives">Se prima eri un utente OpenAPS e il tuo NS ha almeno 3 mesi di dati in loop, puoi inviare un\'e-mail a objectives@androidaps.org con il tuo indirizzo NS e richiedere il codice per ignorare il resto degli obiettivi. Inserisci il codice ottenuto dagli sviluppatori</string>
<string name="enter_code_obtained_from_developers_to_bypass_the_rest_of_objectives">Se hai almeno 3 mesi di esperienza in loop chiuso con altri sistemi potresti beneficiare di un codice per saltare gli obiettivi. Guarda https://androidaps.readthedocs.io/en/latest/EN/Usage/Objectives.html#skip-objectives per i dettagli.</string>
<string name="codeaccepted">Codice accettato</string>
<string name="codeinvalid">Codice non valido</string>
<string name="objectives_exam_objective">Dai prova della tua conoscenza</string>
@ -51,7 +50,7 @@
<string name="useaction_hint" formatted="false">https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/Screenshots.html#config-builder</string>
<string name="usescale_hint" formatted="false">https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/Screenshots.html#the-homescreen</string>
<string name="notconnected">Non connesso a internet</string>
<string name="failedretrievetime">Impossibile recuperare l\'orario</string>
<string name="failedretrievetime">Impossibile recuperare l\'ora</string>
<string name="requirementnotmet">Requisiti obiettivo non soddisfatti</string>
<plurals name="objective_days">
<item quantity="one">%1$d giorno</item>

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<!-- <string name="fi_lang" translatable="false">Finnish</string> -->
<!-- <string name="he_lang" translatable="false">Hebrew</string> -->
@ -14,7 +13,7 @@
<string name="reset_db_confirm">Vuoi davvero resettare i database?</string>
<string name="nav_exit">Esci</string>
<string name="danar_useextended_title">Usa boli estesi per &gt;200%%</string>
<string name="danar_bt_name_title">Dispositivo DanaR Bluetooth</string>
<string name="danar_bt_name_title">Dispositivo Bluetooth DanaR</string>
<string name="ns_sync_use_absolute_title">Utilizza sempre valori basali assoluti</string>
<string name="alert_dialog_storage_permission_text">Per favore riavvia il tuo telefono oppure fai ripartire AndroidAPS dalle impostazioni di sistema \naltrimenti Android APS non farà il log (è importante monitorare e verificare che gli algoritmi stiano funzionando correttamente)!</string>
<string name="alert_dialog_permission_battery_optimization_failed">Questo dispositivo non sembra supportare la whitelist dell\'ottimizzazione della batteria: potrebbero verificarsi problemi di prestazioni.</string>
@ -25,7 +24,7 @@
<string name="description_food">Visualizza l\'elenco dei cibi definiti in Nightscout</string>
<string name="description_insulin_rapid">Preset per insulina Humalog e NovoRapid</string>
<string name="description_insulin_ultra_rapid">Preset per insulina Fiasp</string>
<string name="description_insulin_free_peak">Ti consente di definire il picco dell\'insulina e deve essere utilizzato solo dagli utenti avanzati</string>
<string name="description_insulin_free_peak">Ti consente di definire il picco di attività dell\'insulina e deve essere utilizzato solo dagli utenti avanzati</string>
<string name="description_loop">Attiva o disattiva l\'implementazione del loop.</string>
<string name="description_ns_client">Sincronizza i tuoi dati con Nightscout</string>
<string name="description_ma">Stato dell\'algoritmo nel 2016</string>
@ -42,7 +41,7 @@
<string name="description_pump_dana_r_v2">Integrazione del microinfusore DANA Diabecare R con firmware aggiornato</string>
<string name="description_pump_dana_rs">Integrazione del microinfusore DANA Diabecare RS</string>
<string name="description_pump_mdi">Per le persone in terapia multi-iniettiva</string>
<string name="description_pump_virtual">Per microinfusori che non hanno ancora alcun driver (Loop Aperto)</string>
<string name="description_pump_virtual">Per microinfusori che non hanno ancora alcun driver (Loop aperto)</string>
<string name="description_sensitivity_aaps">La sensibilità è calcolata allo stesso modo di Oref0, ma puoi specificare l\'intervallo di tempo al passato. L\'assorbimento minimo dei carboidrati è calcolato da \'max tempo assorbimento pasto\' nelle preferenze.</string>
<string name="description_sensitivity_oref0">La sensibilità è calcolata dai dati delle ultime 24h e i carboidrati (se non assorbiti) vengono tagliati fuori dopo il tempo specificato nelle preferenze.</string>
<string name="description_sensitivity_oref1">La sensibilità è calcolata dai dati delle ultime 8h e i carboidrati (se non assorbiti) vengono tagliati fuori dopo il tempo specificato nelle preferenze. Il Plugin calcola anche UAM.</string>
@ -51,7 +50,7 @@
<string name="description_source_glimp">Ricevi valori glicemia da Glimp.</string>
<string name="description_source_mm640g">Ricevi valori glicemia da 600SeriesAndroidUploader.</string>
<string name="description_source_ns_client">Scarica dati glicemia da Nightscout</string>
<string name="description_source_xdrip">Ricevi dati glicemia da xDrip.</string>
<string name="description_source_xdrip">Ricevi valori glicemia da xDrip.</string>
<string name="description_treatments">Salva tutti i trattamenti che sono stati fatti</string>
<string name="description_wear">Monitora e controlla AndroidAPS usando il tuo smartwatch WearOS.</string>
<string name="description_xdrip_status_line">Mostra le informazioni del loop sulla watchface di xDrip+.</string>
@ -120,7 +119,7 @@
<string name="configbuilder_treatments">Trattamenti</string>
<string name="configbuilder_treatments_description">Quale plugin dovrebbe essere utilizzato per la gestione del trattamento?</string>
<string name="configbuilder_profile">Profilo</string>
<string name="configbuilder_profile_description">Quale profilo dovrebbe usare AndroidAPS?</string>
<string name="configbuilder_profile_description">Quale profilo AndroidAPS dovrebbe usare?</string>
<string name="configbuilder_aps">APS</string>
<string name="configbuilder_aps_description">Quale algoritmo APS dovrebbe apportare aggiustamenti terapeutici?</string>
<string name="configbuilder_general">Generale</string>
@ -176,7 +175,7 @@
<string name="careportal_announcement">Annuncio</string>
<string name="careportal_note">Nota</string>
<string name="careportal_question">Domanda</string>
<string name="careportal_exercise">Esercizio</string>
<string name="careportal_exercise">Esercizio fisico</string>
<string name="careportal_pumpsitechange">Cambio posizione cannula</string>
<string name="careportal_cgmsensorinsert">Inserimento sensore</string>
<string name="careportal_cgmsensorstart">Avvio Sensore</string>
@ -196,7 +195,7 @@
<string name="careportal_newnstreatment_sensor">Sensore</string>
<string name="careportal_newnstreatment_carbs_label">CHO</string>
<string name="careportal_newnstreatment_insulin_label">Insulina</string>
<string name="careportal_newnstreatment_carbtime_label">Tempo CHO</string>
<string name="careportal_newnstreatment_carbtime_label">Offset CHO</string>
<string name="careportal_newnstreatment_split_label">Frazione</string>
<string name="careportal_newnstreatment_duration_label">Durata</string>
<string name="careportal_newnstreatment_percent_label">Percentuale</string>
@ -248,7 +247,7 @@
<string name="success">OK</string>
<string name="percent">Percentuale</string>
<string name="absolute">Assoluto</string>
<string name="canceltemp">Cancellare basale temporanea</string>
<string name="canceltemp">Cancella basale temporanea</string>
<string name="smscommunicator">Comunicazioni SMS</string>
<string name="waitingforpumpresult">In attesa del risultato</string>
<string name="smscommunicator_allowednumbers">Numeri di telefono consentiti</string>
@ -265,7 +264,7 @@
<string name="smscommunicator_remotebolusmindistance">Quanti minuti devono trascorrere, almeno, tra un bolo e il successivo</string>
<string name="smscommunicator_remotebolusmindistance_caveat">Per la tua sicurezza, per modificare questa preferenza hai bisogno di aggiungere almeno 2 numeri di telefono.</string>
<string name="bolusdelivered">Bolo di %1$.2fU erogato con successo</string>
<string name="bolusrequested">Sto per erogare %1$.2fU</string>
<string name="bolusrequested">A erogare %1$.2fU</string>
<string name="smscommunicator_bolusdelivered">Bolo di %1$.2fU erogato con successo</string>
<string name="smscommunicator_mealbolusdelivered">Bolo pasto di %1$.2fU erogato con successo</string>
<string name="smscommunicator_mealbolusdelivered_tt">Target %1$s per %2$d minuti</string>
@ -344,8 +343,8 @@
<string name="smscommunicator_extendedstopreplywithcode">Per stoppare il bolo esteso rispondi col codice %1$s</string>
<string name="smscommunicator_tempbasalcanceled">Basale temporanea cancellata</string>
<string name="smscommunicator_extendedcanceled">Bolo esteso cancellato</string>
<string name="smscommunicator_tempbasalcancelfailed">Cancellazione basale temporanea fallita</string>
<string name="smscommunicator_extendedcancelfailed">Cancellazione bolo esteso fallita</string>
<string name="smscommunicator_tempbasalcancelfailed">Basale temporanea: cancellazione fallita</string>
<string name="smscommunicator_extendedcancelfailed">Bolo esteso: cancellazione fallita</string>
<string name="smscommunicator_unknowncommand">Comando sconosciuto o risposta errata</string>
<string name="quickwizard">Calcolatore Rapido</string>
<string name="quickwizardsettings">Impostazioni Calcolatore Rapido</string>
@ -415,7 +414,7 @@
<string name="deletefuturetreatments">Elimina trattamenti nel futuro</string>
<string name="eatingsoon">Pasto a breve</string>
<string name="hypo">Ipoglicemia</string>
<string name="activity">Attività</string>
<string name="activity">Attività fisica</string>
<string name="removerecord">Rimuovi record</string>
<string name="danar_stats">Statistiche DanaR</string>
<string name="danar_stats_cumulative_tdd">TDD cumulativo</string>
@ -619,7 +618,7 @@
<string name="basal_short">BAS</string>
<string name="virtualpump_extendedbolus_label_short">EXT</string>
<string name="keep_screen_on_title">Mantieni lo schermo acceso</string>
<string name="keep_screen_on_summary">Evita che Android disattivi lo schermo. Consumerà molta energia quando non è collegato alla presa di corrente.</string>
<string name="keep_screen_on_summary">Evita che Android spenga lo schermo. Consumerà molta energia quando non è collegato alla presa di corrente.</string>
<string name="sensitivity_warning">Attivando la funzione Autosense, ricorda di inserire tutti i carboidrati assunti. Altrimenti le deviazioni di glicemia dovute ai carboidrati saranno identificate erroneamente come variazione di sensibilità !!</string>
<string name="sensitivityweightedaverage">Sensibilità WeightedAverage</string>
<string name="mdtp_ok">OK</string>
@ -639,8 +638,8 @@
<string name="enablesmb">Abilita SMB</string>
<string name="enablesmb_summary">Utilizza Super Micro Boli al posto della basale temporanea per un\'azione più veloce</string>
<string name="enableuam_summary">Rilevazione dei pasti Non Annunciati</string>
<string name="insulin_oref_peak">IOB Curve Peak Time</string>
<string name="insulin_peak_time">Peak Time [min]</string>
<string name="insulin_oref_peak">Tempo picco Curva IOB</string>
<string name="insulin_peak_time">Tempo del picco [min]</string>
<string name="free_peak_oref">Free-Peak Oref</string>
<string name="rapid_acting_oref">Rapid-Acting Oref</string>
<string name="ultrarapid_oref">Ultra-Rapid Oref</string>
@ -650,7 +649,7 @@
<string name="invalid">NON VALIDO</string>
<string name="waitingforpairing">In attesa di associare il micro</string>
<string name="pairingok">Associazione OK</string>
<string name="pairingtimedout">Time out associazione micro</string>
<string name="pairingtimedout">Time out associazione</string>
<string name="pairing">Accoppiamento</string>
<string name="danars_nodeviceavailable">Nessun dispositivo trovato finora</string>
<string name="emptyreservoir">Serbatoio vuoto</string>
@ -668,8 +667,8 @@
<string name="default_temptargets">Temp-Target predefiniti</string>
<string name="eatingsoon_duration">target \"pasto a breve\" - durata</string>
<string name="eatingsoon_target">target \"pasto a breve\"</string>
<string name="activity_duration">target \"attività\" - durata</string>
<string name="activity_target">target \"attività\"</string>
<string name="activity_duration">target \"attività fisica\" - durata</string>
<string name="activity_target">target \"attività fisica\"</string>
<string name="hypo_duration">target \"ipoglicemia\" - durata</string>
<string name="hypo_target">target \"ipoglicemia\"</string>
<string name="danar_history_prime">Riempimento</string>
@ -696,7 +695,7 @@
<string name="waitingforestimatedbolusend">Attesa per la fine del bolo. Rimangono %1$d sec.</string>
<string name="processinghistory">Evento di elaborazione</string>
<string name="startingbolus">Avvio erogazione bolo</string>
<string name="executingrightnow">Il comando verrà eseguito ora</string>
<string name="executingrightnow">Il comando sarà eseguito ora</string>
<string name="pumpdrivercorrected">Driver del micro corretto</string>
<string name="pump_unreachable">Micro irraggiungibile</string>
<string name="missed_bg_readings">Letture BG mancanti</string>
@ -772,7 +771,7 @@
<string name="combo_reservoir_normal">Normale</string>
<string name="combo_notification_check_time_date">Necessario aggiornare orologio micro</string>
<string name="combo_warning">Attenzione</string>
<string name="combo_pump_tbr_cancelled_warrning">Avviso TBR CANCELLATO confermato</string>
<string name="combo_pump_tbr_cancelled_warrning">Avviso TBR CANCELLATO: confermato</string>
<string name="combo_error_no_connection_no_bolus_delivered">Il micro potrebbe non essere raggiungibile. Nessun bolo erogato</string>
<string name="combo_error_no_bolus_delivered">Erogazione bolo fallita. Sembra che nessun bolo sia stato erogato. Per sicurezza, controlla il micro per evitare un doppio bolo e se è tutto ok, erogalo di nuovo. Come protezione da eventuali \"bug\", i boli non vengono ripetuti automaticamente.</string>
<string name="combo_error_partial_bolus_delivered">Solo la quantità di %1$.2f U del bolo richiesto di %2$.2f U è stata erogata a causa di un errore. Controlla il micro per verificare quanto accaduto e intraprendi le azioni necessarie.</string>
@ -790,7 +789,7 @@
<string name="enablesmbwithcob">Abilita SMB con COB</string>
<string name="enablesmbwithcob_summary">Abilita SMB quando COB è attivo (ci sono carboidrati non assorbiti).</string>
<string name="enablesmbwithtemptarget">Abilita SMB con target temporanei</string>
<string name="enablesmbwithtemptarget_summary">Abilita SMB quando è attivo un target temporaneo (pasto a breve, attività)</string>
<string name="enablesmbwithtemptarget_summary">Abilita SMB quando è attivo un target temporaneo (pasto a breve, attività fisica)</string>
<string name="enablesmbwithhightemptarget">Abilita SMB con target temporanei \"alti\"</string>
<string name="enablesmbwithhightemptarget_summary">Abilita SMB quando è attivo un target temporaneo \"alto\"</string>
<string name="let_temp_basal_run">Lascia eseguire la basale temporanea</string>
@ -816,7 +815,7 @@
<string name="allow_automated_crash_reporting">Consenti la segnalazione automatica degli errori e l\'invio dei dati di utilizzo delle funzioni dell\'app agli sviluppatori tramite il servizio fabric.io.</string>
<string name="g5appnotdetected">Aggiorna la tua app Dexcom ad una versione supportata</string>
<string name="dexcom_app_not_installed">App Dexcom non installata.</string>
<string name="start_activity_tt">Avvia TT Attività</string>
<string name="start_activity_tt">Avvia TT Attività fisica</string>
<string name="start_eating_soon_tt">Avvia TT Pasto a breve</string>
<string name="temptargetshort">TT</string>
<string name="do_not_bolus_record_only">No bolo, solo record</string>
@ -839,13 +838,13 @@
<string name="pump_basebasalrate">%1$.2f U/h</string>
<string name="combo_actvity_reading_basal_profile">Lettura profilo basale</string>
<string name="combo_bolus_rejected_due_to_pump_history_change">Lo storico del micro è cambiato dopo il calcolo del bolo. Il bolo non è stato erogato. Ricalcolare se un bolo è ancora necessario.</string>
<string name="combo_error_updating_treatment_record">Bolo erogato con successo, ma impossibile aggiungere la voce ai trattamenti. Questo può accadere se due piccoli boli della stessa quantità sono stati somministrati negli ultimi due minuti. Verifica lo storico del micro e le voci della sezione Trattamenti e utilizza la sezione Portale per aggiungere eventuali voci mancanti. Assicurati di non aggiungere voci con lo stesso orario e con la stessa quantità.</string>
<string name="combo_error_updating_treatment_record">Bolo erogato con successo, ma non è possibile aggiungere la voce ai trattamenti. Questo può accadere se due piccoli boli della stessa quantità sono stati somministrati negli ultimi due minuti. Verifica lo storico del micro e le voci della sezione Trattamenti e utilizza la sezione Portale per aggiungere eventuali voci mancanti. Assicurati di non aggiungere voci che si riferiscano al medesimo minuto e alla stessa quantità.</string>
<string name="combo_high_temp_rejected_due_to_pump_history_changes">Rifiuto basale temporanea \"alta\" in quanto il calcolo non ha considerato i cambiamenti recenti allo storico del micro</string>
<string name="combo_activity_checking_pump_state">Aggiornamento stato micro</string>
<string name="combo_warning_pump_basal_rate_changed">La velocità basale nel micro è cambiata e verrà aggiornata a breve</string>
<string name="combo_error_failure_reading_changed_basal_rate">Velocità basale cambiata sul micro, ma la sua lettura è fallita</string>
<string name="combo_activity_checking_for_history_changes">Controllo modifiche allo storico</string>
<string name="combo_error_multiple_boluses_with_identical_timestamp">Sono appena stati importati più boli con la stessa quantità nello stesso minuto. Solo un record può essere aggiunto ai trattamenti. Controlla il micro e aggiungi manualmente un record di bolo utilizzando la sezione Portale. Assicurati di creare un bolo con un orario non utilizzato da nessun altro bolo.</string>
<string name="combo_error_multiple_boluses_with_identical_timestamp">Sono appena stati importati più boli con la stessa quantità nello stesso minuto. Solo un record può essere aggiunto ai trattamenti. Controlla il micro e aggiungi manualmente un record di bolo utilizzando la sezione Portale. Assicurati di creare un bolo con un\'ora non utilizzata da nessun altro bolo.</string>
<string name="about_link_urls">\n\nhttp://www.androidaps.org\nhttp://www.androidaps.de (de)\n\nfacebook:\nhttp://facebook.androidaps.org\nhttp://facebook.androidaps.de (de)</string>
<string name="combo_check_date">L\'ultimo bolo è più vecchio di 24 ore o ha una data nel futuro. Controlla che la data sul micro sia impostata correttamente.</string>
<string name="combo_suspious_bolus_time">L\'ora/la data del bolo erogato sul micro sembra errata, IOB probabilmente non è corretto. Controlla l\'ora e/o la data del micro.</string>
@ -946,6 +945,7 @@
<string name="startobjective">Avvia il tuo primo obiettivo</string>
<string name="permission">Permesso</string>
<string name="askforpermission">Chiedi il permesso</string>
<string name="needsystemwindowpermission">L\'applicazione richiede il permesso finestra di sistema per le notifiche</string>
<string name="needlocationpermission">L\'applicazione richiede l\'accesso alla posizione per eseguire lo scan bluetooth</string>
<string name="needstoragepermission">L\'applicazione richiede l\'accesso alla memoria per salvare i file di log</string>
<string name="request">Richiesta</string>
@ -982,8 +982,8 @@
<string name="low_temptarget_lowers_sensitivity_summary"><![CDATA[Riduci la sensibilità per temp-target < 100]]></string>
<string name="combo_invalid_setup">Configurazione micro non valida, controlla la documentazione e verifica che il menu Quick Info sia denominato QUICK INFO utilizzando \"360 configuration software\".</string>
<string name="custom">Personalizzato</string>
<string name="largetimedifftitle">Grande differenza d\'orario</string>
<string name="largetimediff">Grande differenza d\'orario:\nL\'orario nel micro differisce per più di 1h e 30m. \nRegola l\'ora manualmente e assicurati che la lettura dello storico dal micro non causi comportamenti imprevisti.\nSe possibile, cancella la cronologia del micro prima di cambiare l\'orario oppure disabilita il loop chiuso per un tempo corrispondente al tuo valore DIA.</string>
<string name="largetimedifftitle">Grande differenza oraria</string>
<string name="largetimediff">Grande differenza oraria:\nL\'ora nel micro differisce per più di 1h e 30m. \nRegola l\'ora manualmente e assicurati che la lettura dello storico dal micro non causi comportamenti imprevisti.\nSe possibile, cancella la cronologia del micro prima di cambiare l\'ora oppure disabilita il loop chiuso per un tempo corrispondente al tuo valore DIA.</string>
<string name="careportal_removestartedevents">Rimuovi gli eventi \"AndroidAPS avviato\"</string>
<string name="storedsettingsfound">Trovate impostazioni salvate</string>
<string name="allow_hardware_pump_text">Attenzione: se attivi e connetti un micro, AndroidAPS copierà le impostazioni della basale dal profilo al micro, sovrascrivendo la velocità basale esistente memorizzata sul micro. Assicurati di avere la giusta impostazione della basale in AndroidAPS. Se non sei sicuro o non vuoi sovrascrivere le impostazioni della basale sul micro, premi annulla e ripeti il processo in un altro momento.</string>
@ -1030,11 +1030,11 @@
<string name="confirm">Conferma</string>
<string name="mute_alert">Muto</string>
<string name="pump_alert">Avviso microinfusore</string>
<string name="log_site_changes">Registra cambi posizione cannula</string>
<string name="log_site_changes">Registra cambi posizione</string>
<string name="log_reservoir_changes">Registra cambi serbatoio</string>
<string name="log_tube_changes">Registra cambi catetere</string>
<string name="log_battery_changes">Registra cambi batteria</string>
<string name="log_operating_mode_changes">Registra cambi modalità di funzionamento</string>
<string name="log_operating_mode_changes">Registra cambi modalità operativa</string>
<string name="log_alerts">Registra avvisi</string>
<string name="enable_tbr_emulation">Abilita emulazione TBR</string>
<string name="enable_tbr_emulation_summary">Usa i bolli estesi invece dei TBR per aggirare il limite del 250%%</string>
@ -1113,9 +1113,9 @@
<string name="glucosecomparedmmol">Glicemia %1$s %2$.1f %3$s</string>
<string name="percentagecompared">PCT profilo %1$s %2$d</string>
<string name="iobcompared">IOB %1$s %2$.1f</string>
<string name="and">E</string>
<string name="or">O</string>
<string name="xor">O (esclusivo)</string>
<string name="and">E (AND)</string>
<string name="or">O (OR)</string>
<string name="xor">O (esclusivo - XOR)</string>
<string name="atspecifiedtime">A %1$s</string>
<string name="use_network_location">Usa posizione di rete</string>
<string name="use_gps_location">Usa posizione GPS</string>
@ -1161,7 +1161,7 @@
<string name="storage">vincolo di archiviazione interna</string>
<string name="diskfull">Libera almeno %1$d MB dalla memoria interna! Loop disabilitato!</string>
<string name="wrongformat">Formato errato</string>
<string name="sms_wrongcode">Codice errato. Comando annullato.</string>
<string name="sms_wrongcode">Codice errato. Comando cancellato.</string>
<string name="notconfigured">Non configurato</string>
<string name="profileswitchcreated">Cambio profilo creato</string>
<string name="recurringTime">Tempo ricorrente</string>
@ -1321,7 +1321,7 @@
<string name="medtronic_error_pump_wrong_max_bolus_set">Max bolo errato impostato nel micro (deve essere %1$.2f).</string>
<string name="medtronic_error_pump_wrong_max_basal_set">Max basale errata impostata nel micro (deve essere %1$.2f).</string>
<string name="medtronic_error_operation_not_possible_no_configuration">Operazione non possibile.\n\n Devi prima configurare il micro Medtronic.</string>
<string name="medtronic_error_pump_24h_time_change_requested">È stata richiesta una modifica d\'orario di oltre 24h.</string>
<string name="medtronic_error_pump_24h_time_change_requested">È stata richiesta una modifica oraria di oltre 24h.</string>
<!-- MDT History -->
<string name="medtronic_history_group_basal">Basali</string>
<string name="medtronic_history_group_configuration">Configurazioni</string>
@ -1352,7 +1352,7 @@
<string name="medtronic_cmd_basal_profile_not_set_is_same">Il profilo basale è lo stesso, non sarà impostato di nuovo.</string>
<string name="medtronic_cmd_desc_get_history">Ottieni storico - Pagina %1$d (%2$d/16)</string>
<string name="medtronic_cmd_desc_get_history_request">Ottieni storico - Pagina %1$d</string>
<string name="medtronic_cmd_desc_get_time">Ottieni orario micro</string>
<string name="medtronic_cmd_desc_get_time">Ottieni ora micro</string>
<string name="medtronic_cmd_desc_get_settings">Ottieni impostazioni</string>
<string name="medtronic_cmd_desc_get_model">Ottieni modello micro</string>
<string name="medtronic_cmd_desc_get_basal_profile">Ottieni profilo basale</string>
@ -1377,7 +1377,7 @@
<string name="loading">Caricamento ...</string>
<string name="snooze">Posticipa</string>
<string name="time_range">Intervallo di tempo</string>
<string name="timerange_value">Il tempo è compreso tra %1$s e %2$s</string>
<string name="timerange_value">L\'intervallo di tempo è compreso tra %1$s e %2$s</string>
<string name="between">Tra </string>
<string name="close">Chiudi</string>
<string name="increasingmaxbasal">Aumento del valore max basale perché l\'impostazione è inferiore alla tua basale massima nel profilo</string>
@ -1395,8 +1395,8 @@
<string name="format_carbs">%1$dg</string>
<string name="common_on">On</string>
<string name="common_off">Off</string>
<string name="objectives_button_unfinish">Cancella completato</string>
<string name="objectives_button_unstart">Cancella avviato</string>
<string name="objectives_button_unfinish">Cancella completamento</string>
<string name="objectives_button_unstart">Cancella avvio</string>
<string name="timedetection">Rilevazione tempo</string>
<string name="doyouwantresetstart">Vuoi resettare l\'avvio dell\'obiettivo? Potresti perdere i tuoi progressi.</string>
<string name="nopumpselected">Nessun micro selezionato</string>
@ -1419,7 +1419,7 @@
<string name="id">ID:</string>
<string name="submit">Invia</string>
<string name="mostcommonprofile">Profilo più comune:</string>
<string name="survey_comment">Nota: solo i dati visibili su questa schermata verranno caricati (in modo anonimo). Un ID è assegnato a questa installazione di AndroidAPS. Puoi inviare nuovamente i dati se il tuo profilo principale viene modificato, ma lascialo in esecuzione almeno per una settimana per rendere visibili i risultati nel time in range. Il tuo aiuto è apprezzato.</string>
<string name="survey_comment">Nota: solo i dati visibili su questa schermata verranno caricati (in modo anonimo). Un ID è assegnato a questa installazione di AndroidAPS. Puoi inviare nuovamente i dati se il tuo profilo principale viene modificato, ma lascialo in esecuzione almeno per una settimana per rendere il risultato visibile nel time in range (TIR). Il tuo aiuto è apprezzato.</string>
<string name="nav_survey">Sondaggio</string>
<string name="invalidage">Inserimento età non valido</string>
<string name="invalidweight">Inserimento peso non valido</string>
@ -1449,4 +1449,9 @@
<string name="phonechecker">\"PhoneChecker\"</string>
<string name="chartmenu">Menu grafico</string>
<string name="sensitivity_short">AS</string>
<string name="loop_smbrequest_time_label">Richiesta SMB (momento)</string>
<string name="loop_smbexecution_time_label">Esecuzione SMB (momento)</string>
<string name="loop_tbrrequest_time_label">Richiesta basale temporanea (momento)</string>
<string name="loop_tbrexecution_time_label">Esecuzione basale temporanea (momento)</string>
<string name="insight_alert_notification_channel">Avvisi micro Insight</string>
</resources>

View file

@ -1,3 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources></resources>

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources>
<!-- <string name="fi_lang" translatable="false">Finnish</string> -->
<!-- <string name="he_lang" translatable="false">Hebrew</string> -->

View file

@ -1,3 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources></resources>

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