Merge branch 'omnipod_eros_dev_upstream_merge' into omnipod_eros_dev

This commit is contained in:
Bart Sopers 2020-09-13 18:47:10 +02:00
commit d21a8ed00e
119 changed files with 3805 additions and 179 deletions

View file

@ -1,33 +0,0 @@
name: Gradle CI
on:
- push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Create NDK path
run: sudo mkdir -p /usr/local/lib/android/sdk/ndk && sudo chmod 777 /usr/local/lib/android/sdk/ndk
- name: Cache NDKs
id: cache-ndk
uses: actions/cache@v2
with:
path: /usr/local/lib/android/sdk/ndk
key: ${{ runner.os }}-ndk-21.0.6113669-21.1.6352462
- name: Install NDK 21.0.6113669
run: echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;21.0.6113669" --sdk_root=${ANDROID_SDK_ROOT}
- name: Install NDK 21.1.6352462
run: echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;21.1.6352462" --sdk_root=${ANDROID_SDK_ROOT}
- uses: eskatos/gradle-command-action@v1
with:
arguments: assembleFullDebug
wrapper-cache-enabled: true
dependencies-cache-enabled: true
configuration-cache-enabled: true

View file

@ -126,7 +126,7 @@ android {
targetSdkVersion 28
multiDexEnabled true
versionCode 1500
version "2.7-omnipod-0.4.1-SNAPSHOT"
version "2.6.7-dev"
buildConfigField "String", "VERSION", '"' + version + '"'
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"'
@ -245,7 +245,6 @@ dependencies {
implementation project(':danar')
implementation project(':rileylink')
implementation project(':medtronic')
implementation project(':omnipod')
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.google.android.gms:play-services-wearable:17.0.0'
@ -353,6 +352,15 @@ dependencies {
kapt "com.google.dagger:dagger-compiler:$dagger_version"
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
//WorkManager
implementation 'androidx.work:work-runtime:2.3.4'
implementation 'androidx.work:work-runtime-ktx:2.3.4'
implementation 'androidx.work:work-rxjava2:2.3.4'
implementation 'com.google.androidbrowserhelper:androidbrowserhelper:1.1.0'
implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
}
/*

View file

@ -260,6 +260,19 @@
android:exported="true" />
<activity android:name=".plugins.pump.medtronic.dialog.MedtronicHistoryActivity" />
<activity android:name=".plugins.general.openhumans.OpenHumansLoginActivity"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="setup-openhumans"
android:scheme="androidaps" />
</intent-filter>
</activity>
<uses-library android:name="org.apache.http.legacy" android:required="false"/>

View file

@ -32,6 +32,7 @@ import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin
import info.nightscout.androidaps.plugins.general.wear.WearPlugin
@ -58,6 +59,7 @@ import info.nightscout.androidaps.utils.sharedPreferences.SP
import javax.inject.Inject
class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListener, HasAndroidInjector {
private var pluginId = -1
@Inject lateinit var rxBus: RxBusWrapper
@ -98,6 +100,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
@Inject lateinit var passwordCheck: PasswordCheck
@Inject lateinit var nsSettingStatus: NSSettingsStatus
@Inject lateinit var openHumansUploader: OpenHumansUploader
// TODO why?
@Inject lateinit var androidInjector: DispatchingAndroidInjector<Any>
@ -183,6 +186,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
addPreferencesFromResource(R.xml.pref_alerts, rootKey) // TODO not organized well
addPreferencesFromResource(R.xml.pref_datachoices, rootKey)
addPreferencesFromResourceIfEnabled(maintenancePlugin, rootKey)
addPreferencesFromResourceIfEnabled(openHumansUploader, rootKey)
}
initSummary(preferenceScreen, pluginId != -1)
preprocessPreferences()

View file

@ -9,6 +9,7 @@ import androidx.annotation.Nullable;
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
import com.j256.ormlite.dao.CloseableIterator;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.stmt.DeleteBuilder;
import com.j256.ormlite.stmt.PreparedQuery;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.Where;
@ -21,6 +22,7 @@ import org.json.JSONObject;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.concurrent.Executors;
@ -53,6 +55,8 @@ import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryBgData;
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData;
import info.nightscout.androidaps.plugins.pump.insight.database.InsightBolusID;
import info.nightscout.androidaps.plugins.pump.insight.database.InsightHistoryOffset;
@ -74,6 +78,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
@Inject AAPSLogger aapsLogger;
@Inject RxBusWrapper rxBus;
@Inject VirtualPumpPlugin virtualPumpPlugin;
@Inject OpenHumansUploader openHumansUploader;
public static final String DATABASE_NAME = "AndroidAPSDb";
public static final String DATABASE_BGREADINGS = "BgReadings";
@ -87,8 +92,9 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public static final String DATABASE_INSIGHT_HISTORY_OFFSETS = "InsightHistoryOffsets";
public static final String DATABASE_INSIGHT_BOLUS_IDS = "InsightBolusIDs";
public static final String DATABASE_INSIGHT_PUMP_IDS = "InsightPumpIDs";
public static final String DATABASE_OPEN_HUMANS_QUEUE = "OpenHumansQueue";
private static final int DATABASE_VERSION = 12;
private static final int DATABASE_VERSION = 13;
public static Long earliestDataChange = null;
@ -141,6 +147,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
TableUtils.createTableIfNotExists(connectionSource, InsightBolusID.class);
TableUtils.createTableIfNotExists(connectionSource, InsightPumpID.class);
TableUtils.createTableIfNotExists(connectionSource, OmnipodHistoryRecord.class);
TableUtils.createTableIfNotExists(connectionSource, OHQueueItem.class);
database.execSQL("INSERT INTO sqlite_sequence (name, seq) SELECT \"" + DATABASE_INSIGHT_BOLUS_IDS + "\", " + System.currentTimeMillis() + " " +
"WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = \"" + DATABASE_INSIGHT_BOLUS_IDS + "\")");
database.execSQL("INSERT INTO sqlite_sequence (name, seq) SELECT \"" + DATABASE_INSIGHT_PUMP_IDS + "\", " + System.currentTimeMillis() + " " +
@ -180,6 +187,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
database.execSQL("UPDATE sqlite_sequence SET seq = " + System.currentTimeMillis() + " WHERE name = \"" + DATABASE_INSIGHT_BOLUS_IDS + "\"");
database.execSQL("UPDATE sqlite_sequence SET seq = " + System.currentTimeMillis() + " WHERE name = \"" + DATABASE_INSIGHT_PUMP_IDS + "\"");
}
TableUtils.createTableIfNotExists(connectionSource, OHQueueItem.class);
} catch (SQLException e) {
aapsLogger.error("Can't drop databases", e);
throw new RuntimeException(e);
@ -366,6 +374,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return getDao(OmnipodHistoryRecord.class);
}
private Dao<OHQueueItem, Long> getDaoOpenHumansQueue() throws SQLException {
return getDao(OHQueueItem.class);
}
public long roundDateToSec(long date) {
long rounded = date - date % 1000;
if (rounded != date)
@ -380,6 +392,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
BgReading old = getDaoBgReadings().queryForId(bgReading.date);
if (old == null) {
getDaoBgReadings().create(bgReading);
openHumansUploader.enqueueBGReading(bgReading);
aapsLogger.debug(LTag.DATABASE, "BG: New record from: " + from + " " + bgReading.toString());
scheduleBgChange(bgReading);
return true;
@ -388,6 +401,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
aapsLogger.debug(LTag.DATABASE, "BG: Similiar found: " + old.toString());
old.copyFrom(bgReading);
getDaoBgReadings().update(old);
openHumansUploader.enqueueBGReading(old);
aapsLogger.debug(LTag.DATABASE, "BG: Updating record from: " + from + " New data: " + old.toString());
scheduleBgHistoryChange(old.date); // trigger cache invalidation
return false;
@ -402,6 +416,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
bgReading.date = roundDateToSec(bgReading.date);
try {
getDaoBgReadings().update(bgReading);
openHumansUploader.enqueueBGReading(bgReading);
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
@ -497,11 +512,21 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return new ArrayList<BgReading>();
}
public List<BgReading> getAllBgReadings() {
try {
return getDaoBgReadings().queryForAll();
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return Collections.emptyList();
}
// ------------------- TDD handling -----------------------
public void createOrUpdateTDD(TDD tdd) {
try {
Dao<TDD, String> dao = getDaoTDD();
dao.createOrUpdate(tdd);
openHumansUploader.enqueueTotalDailyDose(tdd);
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
@ -522,6 +547,15 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return tddList;
}
public List<TDD> getAllTDDs() {
try {
return getDaoTDD().queryForAll();
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return Collections.emptyList();
}
public List<TDD> getTDDsForLastXDays(int days) {
List<TDD> tddList;
GregorianCalendar gc = new GregorianCalendar();
@ -629,6 +663,15 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return new ArrayList<TempTarget>();
}
public List<TempTarget> getAllTempTargets() {
try {
return getDaoTempTargets().queryForAll();
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return Collections.emptyList();
}
public List<TempTarget> getTemptargetsDataFromTime(long from, long to, boolean ascending) {
try {
Dao<TempTarget, Long> daoTempTargets = getDaoTempTargets();
@ -658,6 +701,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
getDaoTempTargets().delete(old); // need to delete/create because date may change too
old.copyFrom(tempTarget);
getDaoTempTargets().create(old);
openHumansUploader.enqueueTempTarget(old);
aapsLogger.debug(LTag.DATABASE, "TEMPTARGET: Updating record by date from: " + Source.getString(tempTarget.source) + " " + old.toString());
scheduleTemporaryTargetChange();
return true;
@ -677,6 +721,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
getDaoTempTargets().delete(old); // need to delete/create because date may change too
old.copyFrom(tempTarget);
getDaoTempTargets().create(old);
openHumansUploader.enqueueTempTarget(old);
aapsLogger.debug(LTag.DATABASE, "TEMPTARGET: Updating record by _id from: " + Source.getString(tempTarget.source) + " " + old.toString());
scheduleTemporaryTargetChange();
return true;
@ -690,6 +735,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
}
if (tempTarget.source == Source.USER) {
getDaoTempTargets().create(tempTarget);
openHumansUploader.enqueueTempTarget(tempTarget);
aapsLogger.debug(LTag.DATABASE, "TEMPTARGET: New record from: " + Source.getString(tempTarget.source) + " " + tempTarget.toString());
scheduleTemporaryTargetChange();
return true;
@ -703,6 +749,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void delete(TempTarget tempTarget) {
try {
getDaoTempTargets().delete(tempTarget);
openHumansUploader.enqueueTempTarget(tempTarget, true);
scheduleTemporaryTargetChange();
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
@ -857,6 +904,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
aapsLogger.debug(LTag.DATABASE, "TEMPBASAL: Updated record with Pump Data : " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
getDaoTemporaryBasal().update(old);
openHumansUploader.enqueueTemporaryBasal(old);
updateEarliestDataChange(tempBasal.date);
scheduleTemporaryBasalChange();
@ -865,6 +913,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
}
getDaoTemporaryBasal().create(tempBasal);
openHumansUploader.enqueueTemporaryBasal(tempBasal);
aapsLogger.debug(LTag.DATABASE, "TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
updateEarliestDataChange(tempBasal.date);
scheduleTemporaryBasalChange();
@ -882,6 +931,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
getDaoTemporaryBasal().delete(old); // need to delete/create because date may change too
old.copyFrom(tempBasal);
getDaoTemporaryBasal().create(old);
openHumansUploader.enqueueTemporaryBasal(old);
aapsLogger.debug(LTag.DATABASE, "TEMPBASAL: Updating record by date from: " + Source.getString(tempBasal.source) + " " + old.toString());
updateEarliestDataChange(oldDate);
updateEarliestDataChange(old.date);
@ -904,6 +954,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
getDaoTemporaryBasal().delete(old); // need to delete/create because date may change too
old.copyFrom(tempBasal);
getDaoTemporaryBasal().create(old);
openHumansUploader.enqueueTemporaryBasal(old);
aapsLogger.debug(LTag.DATABASE, "TEMPBASAL: Updating record by _id from: " + Source.getString(tempBasal.source) + " " + old.toString());
updateEarliestDataChange(oldDate);
updateEarliestDataChange(old.date);
@ -913,6 +964,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
}
}
getDaoTemporaryBasal().create(tempBasal);
openHumansUploader.enqueueTemporaryBasal(tempBasal);
aapsLogger.debug(LTag.DATABASE, "TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
updateEarliestDataChange(tempBasal.date);
scheduleTemporaryBasalChange();
@ -920,6 +972,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
}
if (tempBasal.source == Source.USER) {
getDaoTemporaryBasal().create(tempBasal);
openHumansUploader.enqueueTemporaryBasal(tempBasal);
aapsLogger.debug(LTag.DATABASE, "TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
updateEarliestDataChange(tempBasal.date);
scheduleTemporaryBasalChange();
@ -934,6 +987,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void delete(TemporaryBasal tempBasal) {
try {
getDaoTemporaryBasal().delete(tempBasal);
openHumansUploader.enqueueTemporaryBasal(tempBasal, true);
updateEarliestDataChange(tempBasal.date);
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
@ -941,6 +995,15 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
scheduleTemporaryBasalChange();
}
public List<TemporaryBasal> getAllTemporaryBasals() {
try {
return getDaoTemporaryBasal().queryForAll();
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return Collections.emptyList();
}
public List<TemporaryBasal> getTemporaryBasalsDataFromTime(long mills, boolean ascending) {
try {
List<TemporaryBasal> tempbasals;
@ -1136,6 +1199,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
// and then is record updated with pumpId
if (extendedBolus.pumpId == 0) {
getDaoExtendedBolus().createOrUpdate(extendedBolus);
openHumansUploader.enqueueExtendedBolus(extendedBolus);
} else {
QueryBuilder<ExtendedBolus, Long> queryBuilder = getDaoExtendedBolus().queryBuilder();
Where where = queryBuilder.where();
@ -1147,6 +1211,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return false;
}
getDaoExtendedBolus().createOrUpdate(extendedBolus);
openHumansUploader.enqueueExtendedBolus(extendedBolus);
}
aapsLogger.debug(LTag.DATABASE, "EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.log());
updateEarliestDataChange(extendedBolus.date);
@ -1162,6 +1227,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
old.copyFrom(extendedBolus);
getDaoExtendedBolus().create(old);
aapsLogger.debug(LTag.DATABASE, "EXTENDEDBOLUS: Updating record by date from: " + Source.getString(extendedBolus.source) + " " + old.log());
openHumansUploader.enqueueExtendedBolus(old);
updateEarliestDataChange(oldDate);
updateEarliestDataChange(old.date);
scheduleExtendedBolusChange();
@ -1184,6 +1250,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
old.copyFrom(extendedBolus);
getDaoExtendedBolus().create(old);
aapsLogger.debug(LTag.DATABASE, "EXTENDEDBOLUS: Updating record by _id from: " + Source.getString(extendedBolus.source) + " " + old.log());
openHumansUploader.enqueueExtendedBolus(old);
updateEarliestDataChange(oldDate);
updateEarliestDataChange(old.date);
scheduleExtendedBolusChange();
@ -1193,6 +1260,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
}
getDaoExtendedBolus().create(extendedBolus);
aapsLogger.debug(LTag.DATABASE, "EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.log());
openHumansUploader.enqueueExtendedBolus(extendedBolus);
updateEarliestDataChange(extendedBolus.date);
scheduleExtendedBolusChange();
return true;
@ -1200,6 +1268,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
if (extendedBolus.source == Source.USER) {
getDaoExtendedBolus().create(extendedBolus);
aapsLogger.debug(LTag.DATABASE, "EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.log());
openHumansUploader.enqueueExtendedBolus(extendedBolus);
updateEarliestDataChange(extendedBolus.date);
scheduleExtendedBolusChange();
return true;
@ -1210,6 +1279,15 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return false;
}
public List<ExtendedBolus> getAllExtendedBoluses() {
try {
return getDaoExtendedBolus().queryForAll();
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return Collections.emptyList();
}
public ExtendedBolus getExtendedBolusByPumpId(long pumpId) {
try {
return getDaoExtendedBolus().queryBuilder()
@ -1224,6 +1302,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void delete(ExtendedBolus extendedBolus) {
try {
getDaoExtendedBolus().delete(extendedBolus);
openHumansUploader.enqueueExtendedBolus(extendedBolus, true);
updateEarliestDataChange(extendedBolus.date);
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
@ -1344,6 +1423,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
careportalEvent.date = careportalEvent.date - careportalEvent.date % 1000;
try {
getDaoCareportalEvents().createOrUpdate(careportalEvent);
openHumansUploader.enqueueCareportalEvent(careportalEvent);
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
@ -1353,6 +1433,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void delete(CareportalEvent careportalEvent) {
try {
getDaoCareportalEvents().delete(careportalEvent);
openHumansUploader.enqueueCareportalEvent(careportalEvent, true);
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
@ -1368,6 +1449,15 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return null;
}
public List<CareportalEvent> getAllCareportalEvents() {
try {
return getDaoCareportalEvents().queryForAll();
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return Collections.emptyList();
}
@Nullable
public CareportalEvent getLastCareportalEvent(String event) {
try {
@ -1572,6 +1662,14 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return false;
}
public List<ProfileSwitch> getAllProfileSwitches() {
try {
return getDaoProfileSwitch().queryForAll();
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return Collections.emptyList();
}
@Nullable
private ProfileSwitch getLastProfileSwitchWithoutDuration() {
try {
@ -1644,6 +1742,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
getDaoProfileSwitch().delete(old); // need to delete/create because date may change too
getDaoProfileSwitch().create(profileSwitch);
aapsLogger.debug(LTag.DATABASE, "PROFILESWITCH: Updating record by date from: " + Source.getString(profileSwitch.source) + " " + old.toString());
openHumansUploader.enqueueProfileSwitch(profileSwitch);
scheduleProfileSwitchChange();
return true;
}
@ -1663,6 +1762,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
old.copyFrom(profileSwitch);
getDaoProfileSwitch().create(old);
aapsLogger.debug(LTag.DATABASE, "PROFILESWITCH: Updating record by _id from: " + Source.getString(profileSwitch.source) + " " + old.toString());
openHumansUploader.enqueueProfileSwitch(old);
scheduleProfileSwitchChange();
return true;
}
@ -1672,12 +1772,14 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
profileSwitch.profileName = PercentageSplitter.pureName(profileSwitch.profileName);
getDaoProfileSwitch().create(profileSwitch);
aapsLogger.debug(LTag.DATABASE, "PROFILESWITCH: New record from: " + Source.getString(profileSwitch.source) + " " + profileSwitch.toString());
openHumansUploader.enqueueProfileSwitch(profileSwitch);
scheduleProfileSwitchChange();
return true;
}
if (profileSwitch.source == Source.USER) {
getDaoProfileSwitch().create(profileSwitch);
aapsLogger.debug(LTag.DATABASE, "PROFILESWITCH: New record from: " + Source.getString(profileSwitch.source) + " " + profileSwitch.toString());
openHumansUploader.enqueueProfileSwitch(profileSwitch);
scheduleProfileSwitchChange();
return true;
}
@ -1690,6 +1792,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void delete(ProfileSwitch profileSwitch) {
try {
getDaoProfileSwitch().delete(profileSwitch);
openHumansUploader.enqueueProfileSwitch(profileSwitch, true);
scheduleProfileSwitchChange();
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
@ -1952,4 +2055,69 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return arrow;
}
// ---------------- Open Humans Queue handling ---------------
public void clearOpenHumansQueue() {
try {
TableUtils.clearTable(connectionSource, OHQueueItem.class);
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
}
public void createOrUpdate(OHQueueItem item) {
try {
getDaoOpenHumansQueue().createOrUpdate(item);
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
}
public void removeAllOHQueueItemsWithIdSmallerThan(long id) {
try {
DeleteBuilder<OHQueueItem, Long> deleteBuilder = getDaoOpenHumansQueue().deleteBuilder();
deleteBuilder.where().le("id", id);
deleteBuilder.delete();
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
}
public List<OHQueueItem> getAllOHQueueItems(Long maxEntries) {
try {
return getDaoOpenHumansQueue()
.queryBuilder()
.orderBy("id", true)
.limit(maxEntries)
.query();
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return Collections.emptyList();
}
public long getOHQueueSize() {
try {
return getDaoOpenHumansQueue().countOf();
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return 0L;
}
public long getCountOfAllRows() {
try {
return getDaoBgReadings().countOf()
+ getDaoCareportalEvents().countOf()
+ getDaoExtendedBolus().countOf()
+ getDaoCareportalEvents().countOf()
+ getDaoProfileSwitch().countOf()
+ getDaoTDD().countOf()
+ getDaoTemporaryBasal().countOf()
+ getDaoTempTargets().countOf();
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return 0L;
}
}

View file

@ -0,0 +1,14 @@
package info.nightscout.androidaps.db
import com.j256.ormlite.field.DatabaseField
import com.j256.ormlite.table.DatabaseTable
@DatabaseTable(tableName = DatabaseHelper.DATABASE_OPEN_HUMANS_QUEUE)
data class OHQueueItem @JvmOverloads constructor(
@DatabaseField(generatedId = true)
val id: Long = 0,
@DatabaseField
val file: String = "",
@DatabaseField
val content: String = ""
)

View file

@ -7,6 +7,7 @@ import info.nightscout.androidaps.activities.*
import info.nightscout.androidaps.historyBrowser.HistoryBrowseActivity
import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity
import info.nightscout.androidaps.plugins.general.maintenance.activities.PrefImportListActivity
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansLoginActivity
import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity
import info.nightscout.androidaps.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity
import info.nightscout.androidaps.plugins.pump.common.dialog.RileyLinkBLEScanActivity
@ -40,4 +41,6 @@ abstract class ActivitiesModule {
@ContributesAndroidInjector abstract fun contributesSurveyActivity(): SurveyActivity
@ContributesAndroidInjector abstract fun contributesDefaultProfileActivity(): ProfileHelperActivity
@ContributesAndroidInjector abstract fun contributesPrefImportListActivity(): PrefImportListActivity
@ContributesAndroidInjector abstract fun contributesOpenHumansLoginActivity(): OpenHumansLoginActivity
}

View file

@ -10,7 +10,6 @@ import info.nightscout.androidaps.dana.di.DanaModule
import info.nightscout.androidaps.danar.di.DanaRModule
import info.nightscout.androidaps.danars.di.DanaRSModule
import info.nightscout.androidaps.plugins.pump.common.dagger.RileyLinkModule
import info.nightscout.androidaps.plugins.pump.omnipod.dagger.OmnipodModule
import javax.inject.Singleton
@Singleton
@ -30,7 +29,6 @@ import javax.inject.Singleton
WizardModule::class,
RileyLinkModule::class,
MedtronicModule::class,
OmnipodModule::class,
APSModule::class,
PreferencesModule::class,
OverviewModule::class,
@ -40,7 +38,8 @@ import javax.inject.Singleton
CoreModule::class,
DanaModule::class,
DanaRModule::class,
DanaRSModule::class
DanaRSModule::class,
OHUploaderModule::class
]
)
interface AppComponent : AndroidInjector<MainApp> {

View file

@ -20,6 +20,8 @@ import info.nightscout.androidaps.plugins.general.automation.dialogs.EditTrigger
import info.nightscout.androidaps.plugins.general.food.FoodFragment
import info.nightscout.androidaps.plugins.general.maintenance.MaintenanceFragment
import info.nightscout.androidaps.plugins.general.nsclient.NSClientFragment
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansFragment
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansLoginActivity
import info.nightscout.androidaps.plugins.general.overview.OverviewFragment
import info.nightscout.androidaps.plugins.general.overview.dialogs.EditQuickWizardDialog
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorFragment
@ -34,7 +36,6 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyL
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightFragment
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicFragment
import info.nightscout.androidaps.plugins.pump.medtronic.dialog.RileyLinkStatusDeviceMedtronic
import info.nightscout.androidaps.plugins.pump.omnipod.ui.OmnipodFragment
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpFragment
import info.nightscout.androidaps.plugins.source.BGSourceFragment
import info.nightscout.androidaps.plugins.treatments.TreatmentsFragment
@ -66,23 +67,31 @@ abstract class FragmentsModule {
@ContributesAndroidInjector abstract fun contributesLoopFragment(): LoopFragment
@ContributesAndroidInjector abstract fun contributesMaintenanceFragment(): MaintenanceFragment
@ContributesAndroidInjector abstract fun contributesMedtronicFragment(): MedtronicFragment
@ContributesAndroidInjector abstract fun contributesOmnipodFragment(): OmnipodFragment
@ContributesAndroidInjector abstract fun contributesNSProfileFragment(): NSProfileFragment
@ContributesAndroidInjector abstract fun contributesNSClientFragment(): NSClientFragment
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorFragment(): SmsCommunicatorFragment
@ContributesAndroidInjector
abstract fun contributesSmsCommunicatorFragment(): SmsCommunicatorFragment
@ContributesAndroidInjector abstract fun contributesWearFragment(): WearFragment
@ContributesAndroidInjector abstract fun contributesTidepoolFragment(): TidepoolFragment
@ContributesAndroidInjector abstract fun contributesTreatmentsFragment(): TreatmentsFragment
@ContributesAndroidInjector abstract fun contributesTreatmentsBolusFragment(): TreatmentsBolusFragment
@ContributesAndroidInjector abstract fun contributesTreatmentsTemporaryBasalsFragment(): TreatmentsTemporaryBasalsFragment
@ContributesAndroidInjector abstract fun contributesTreatmentsTempTargetFragment(): TreatmentsTempTargetFragment
@ContributesAndroidInjector abstract fun contributesTreatmentsExtendedBolusesFragment(): TreatmentsExtendedBolusesFragment
@ContributesAndroidInjector abstract fun contributesTreatmentsCareportalFragment(): TreatmentsCareportalFragment
@ContributesAndroidInjector abstract fun contributesTreatmentsProfileSwitchFragment(): TreatmentsProfileSwitchFragment
@ContributesAndroidInjector
abstract fun contributesTreatmentsBolusFragment(): TreatmentsBolusFragment
@ContributesAndroidInjector
abstract fun contributesTreatmentsTemporaryBasalsFragment(): TreatmentsTemporaryBasalsFragment
@ContributesAndroidInjector
abstract fun contributesTreatmentsTempTargetFragment(): TreatmentsTempTargetFragment
@ContributesAndroidInjector
abstract fun contributesTreatmentsExtendedBolusesFragment(): TreatmentsExtendedBolusesFragment
@ContributesAndroidInjector
abstract fun contributesTreatmentsCareportalFragment(): TreatmentsCareportalFragment
@ContributesAndroidInjector
abstract fun contributesTreatmentsProfileSwitchFragment(): TreatmentsProfileSwitchFragment
@ContributesAndroidInjector abstract fun contributesVirtualPumpFragment(): VirtualPumpFragment
@ContributesAndroidInjector abstract fun contributesOpenHumansFragment(): OpenHumansFragment
@ContributesAndroidInjector abstract fun contributesCalibrationDialog(): CalibrationDialog
@ContributesAndroidInjector abstract fun contributesCarbsDialog(): CarbsDialog
@ContributesAndroidInjector abstract fun contributesCareDialog(): CareDialog
@ -106,9 +115,15 @@ abstract class FragmentsModule {
@ContributesAndroidInjector abstract fun contributesWizardDialog(): WizardDialog
@ContributesAndroidInjector abstract fun contributesWizardInfoDialog(): WizardInfoDialog
@ContributesAndroidInjector
abstract fun contributesExchangeAuthTokenDialot(): OpenHumansLoginActivity.ExchangeAuthTokenDialog
@ContributesAndroidInjector abstract fun contributesPasswordCheck(): PasswordCheck
@ContributesAndroidInjector abstract fun contributesRileyLinkStatusGeneral(): RileyLinkStatusGeneralFragment
@ContributesAndroidInjector abstract fun contributesRileyLinkStatusHistoryFragment(): RileyLinkStatusHistoryFragment
@ContributesAndroidInjector abstract fun contributesRileyLinkStatusDeviceMedtronic(): RileyLinkStatusDeviceMedtronic
@ContributesAndroidInjector
abstract fun contributesRileyLinkStatusGeneral(): RileyLinkStatusGeneralFragment
@ContributesAndroidInjector
abstract fun contributesRileyLinkStatusHistoryFragment(): RileyLinkStatusHistoryFragment
@ContributesAndroidInjector
abstract fun contributesRileyLinkStatusDeviceMedtronic(): RileyLinkStatusDeviceMedtronic
}

View file

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

View file

@ -25,6 +25,7 @@ import info.nightscout.androidaps.plugins.general.dataBroadcaster.DataBroadcastP
import info.nightscout.androidaps.plugins.general.food.FoodPlugin
import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin
import info.nightscout.androidaps.plugins.general.persistentNotification.PersistentNotificationPlugin
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
@ -40,7 +41,6 @@ import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
import info.nightscout.androidaps.plugins.pump.mdi.MDIPlugin
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin
import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
@ -148,12 +148,6 @@ abstract class PluginsModule {
@IntKey(150)
abstract fun bindMedtronicPumpPlugin(plugin: MedtronicPumpPlugin): PluginBase
@Binds
@PumpDriver
@IntoMap
@IntKey(155)
abstract fun bindOmnipodPumpPlugin(plugin: OmnipodPumpPlugin): PluginBase
@Binds
@NotNSClient
@IntoMap
@ -341,9 +335,15 @@ abstract class PluginsModule {
abstract fun bindRandomBgPlugin(plugin: RandomBgPlugin): PluginBase
@Binds
@AllConfigs
@NotNSClient
@IntoMap
@IntKey(480)
abstract fun bindOpenHumansPlugin(plugin: OpenHumansUploader): PluginBase
@Binds
@AllConfigs
@IntoMap
@IntKey(490)
abstract fun bindConfigBuilderPlugin(plugin: ConfigBuilderPlugin): PluginBase
@Qualifier

View file

@ -10,7 +10,6 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.Riley
import info.nightscout.androidaps.plugins.pump.insight.InsightAlertService
import info.nightscout.androidaps.plugins.pump.insight.connection_service.InsightConnectionService
import info.nightscout.androidaps.plugins.pump.medtronic.service.RileyLinkMedtronicService
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.service.RileyLinkOmnipodService
import info.nightscout.androidaps.services.AlarmSoundService
import info.nightscout.androidaps.services.DataService
import info.nightscout.androidaps.services.LocationService
@ -30,5 +29,4 @@ abstract class ServicesModule {
@ContributesAndroidInjector abstract fun contributesInsightConnectionService(): InsightConnectionService
@ContributesAndroidInjector abstract fun contributesRileyLinkService(): RileyLinkService
@ContributesAndroidInjector abstract fun contributesRileyLinkMedtronicService(): RileyLinkMedtronicService
@ContributesAndroidInjector abstract fun contributesRileyLinkOmnipodService(): RileyLinkOmnipodService
}

View file

@ -19,6 +19,7 @@ import java.nio.charset.StandardCharsets;
import javax.annotation.Nullable;
import javax.inject.Inject;
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.R;
@ -45,6 +46,7 @@ public class DetermineBasalAdapterAMAJS {
@Inject SP sp;
@Inject ProfileFunction profileFunction;
@Inject TreatmentsPlugin treatmentsPlugin;
@Inject OpenHumansUploader openHumansUploader;
private ScriptReader mScriptReader;
@ -132,7 +134,9 @@ public class DetermineBasalAdapterAMAJS {
String result = NativeJSON.stringify(rhino, scope, jsResult, null, null).toString();
aapsLogger.debug(LTag.APS, "Result: " + result);
try {
determineBasalResultAMA = new DetermineBasalResultAMA(injector, jsResult, new JSONObject(result));
JSONObject resultJson = new JSONObject(result);
openHumansUploader.enqueueAMAData(mProfile, mGlucoseStatus, mIobData, mMealData, mCurrentTemp, mAutosensData, resultJson);
determineBasalResultAMA = new DetermineBasalResultAMA(injector, jsResult, resultJson);
} catch (JSONException e) {
aapsLogger.error(LTag.APS, "Unhandled exception", e);
}

View file

@ -19,6 +19,7 @@ import java.nio.charset.StandardCharsets;
import javax.annotation.Nullable;
import javax.inject.Inject;
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.R;
@ -51,6 +52,7 @@ public class DetermineBasalAdapterSMBJS {
@Inject ProfileFunction profileFunction;
@Inject TreatmentsPlugin treatmentsPlugin;
@Inject ActivePluginProvider activePluginProvider;
@Inject OpenHumansUploader openHumansUploader;
private ScriptReader mScriptReader;
@ -160,7 +162,9 @@ public class DetermineBasalAdapterSMBJS {
String result = NativeJSON.stringify(rhino, scope, jsResult, null, null).toString();
aapsLogger.debug(LTag.APS, "Result: " + result);
try {
determineBasalResultSMB = new DetermineBasalResultSMB(injector, new JSONObject(result));
JSONObject resultJson = new JSONObject(result);
openHumansUploader.enqueueSMBData(mProfile, mGlucoseStatus, mIobData, mMealData, mCurrentTemp, mAutosensData, mMicrobolusAllowed, mSMBAlwaysAllowed, resultJson);
determineBasalResultSMB = new DetermineBasalResultSMB(injector, resultJson);
} catch (JSONException e) {
aapsLogger.error(LTag.APS, "Unhandled exception", e);
}

View file

@ -25,7 +25,8 @@ public class Objective3 extends Objective {
@Inject
public Objective3(HasAndroidInjector injector) {
super(injector, "openloop", R.string.objectives_openloop_objective, R.string.objectives_openloop_gate);
hasSpecialInput = true;
// disable option for skipping objectives for now
// hasSpecialInput = true;
}
@Override

View file

@ -130,6 +130,15 @@ class ImportExportPrefs @Inject constructor(
})
}
private fun askForEncryptionPass(activity: Activity, @StringRes canceledMsg: Int, @StringRes passwordName: Int, @StringRes passwordExplanation: Int?,
@StringRes passwordWarning: Int?, then: ((password: String) -> Unit)) {
passwordCheck.queryAnyPassword(activity, passwordName, R.string.key_master_password, passwordExplanation, passwordWarning, { password ->
then(password)
}, {
ToastUtils.warnToast(activity, resourceHelper.gs(canceledMsg))
})
}
private fun askForMasterPassIfNeeded(activity: Activity, @StringRes canceledMsg: Int, then: ((password: String) -> Unit)) {
if (prefsEncryptionIsDisabled()) {
then("")
@ -182,6 +191,28 @@ class ImportExportPrefs @Inject constructor(
}
}
private fun promptForDecryptionPasswordIfNeeded(activity: Activity, prefs: Prefs, importOk: Boolean,
format: PrefsFormat, importFile: PrefsFile, then: ((prefs: Prefs, importOk: Boolean) -> Unit)) {
// current master password was not the one used for decryption, so we prompt for old password...
if (!importOk && (prefs.metadata[PrefsMetadataKey.ENCRYPTION]?.status == PrefsStatus.ERROR)) {
askForEncryptionPass(activity, R.string.preferences_import_canceled, R.string.old_master_password,
R.string.different_password_used, R.string.master_password_will_be_replaced) { password ->
// ...and use it to load & decrypt file again
val prefsReloaded = format.loadPreferences(importFile.file, password)
prefsReloaded.metadata = prefFileList.checkMetadata(prefsReloaded.metadata)
// import is OK when we do not have errors (warnings are allowed)
val importOkCheckedAgain = checkIfImportIsOk(prefsReloaded)
then(prefsReloaded, importOkCheckedAgain);
}
} else {
then(prefs, importOk);
}
}
private fun exportSharedPreferences(activity: Activity) {
prefFileList.ensureExportDirExists()
@ -258,32 +289,36 @@ class ImportExportPrefs @Inject constructor(
try {
val prefs = format.loadPreferences(importFile.file, password)
prefs.metadata = prefFileList.checkMetadata(prefs.metadata)
val prefsAttempted = format.loadPreferences(importFile.file, password)
prefsAttempted.metadata = prefFileList.checkMetadata(prefsAttempted.metadata)
// import is OK when we do not have errors (warnings are allowed)
val importOk = checkIfImportIsOk(prefs)
val importOkAttempted = checkIfImportIsOk(prefsAttempted)
// if at end we allow to import preferences
val importPossible = (importOk || buildHelper.isEngineeringMode()) && (prefs.values.size > 0)
promptForDecryptionPasswordIfNeeded(activity, prefsAttempted, importOkAttempted, format, importFile) { prefs, importOk ->
PrefImportSummaryDialog.showSummary(activity, importOk, importPossible, prefs, {
if (importPossible) {
sp.clear()
for ((key, value) in prefs.values) {
if (value == "true" || value == "false") {
sp.putBoolean(key, value.toBoolean())
} else {
sp.putString(key, value)
// if at end we allow to import preferences
val importPossible = (importOk || buildHelper.isEngineeringMode()) && (prefs.values.size > 0)
PrefImportSummaryDialog.showSummary(activity, importOk, importPossible, prefs, {
if (importPossible) {
sp.clear()
for ((key, value) in prefs.values) {
if (value == "true" || value == "false") {
sp.putBoolean(key, value.toBoolean())
} else {
sp.putString(key, value)
}
}
}
restartAppAfterImport(activity)
} else {
// for impossible imports it should not be called
ToastUtils.errorToast(activity, resourceHelper.gs(R.string.preferences_import_impossible))
}
})
restartAppAfterImport(activity)
} else {
// for impossible imports it should not be called
ToastUtils.errorToast(activity, resourceHelper.gs(R.string.preferences_import_impossible))
}
})
}
} catch (e: PrefFileNotFoundError) {
ToastUtils.errorToast(activity, resourceHelper.gs(R.string.filenotfound) + " " + importFile)

View file

@ -0,0 +1,209 @@
package info.nightscout.androidaps.plugins.general.openhumans
import java.util.*
fun String.isAllowedKey() = if (startsWith("ConfigBuilder_")) true else allowedKeys.contains(this.toUpperCase(Locale.ROOT))
private val allowedKeys = """
absorption
absorption_maxtime
openapsama_autosens_period
autosens_max
autosens_min
absorption
openapsama_min_5m_carbimpact
absorption_cutoff
autosens_max
autosens_min
absorption
openapsama_min_5m_carbimpact
absorption_cutoff
autosens_max
autosens_min
age
location
dexcomg5_nsupload
dexcomg5_xdripupload
dexcom_lognssensorchange
danars_bolusspeed
danar_useextended
danar_visualizeextendedaspercentage"
bt_watchdog
danar_useextended
danar_visualizeextendedaspercentage"
bt_watchdog
DanaRProfile
danarprofile_dia
blescannner
danars_bolusspeed
bt_watchdog
danars_bolusspeed
bt_watchdog
enable_fabric
insight_log_reservoir_changes
insight_log_tube_changes
insight_log_site_changes
insight_log_battery_changes
insight_log_operating_mode_changes
insight_log_alerts
insight_enable_tbr_emulation
insight_min_recovery_duration
insight_max_recovery_duration
insight_disconnect_delay
insight_log_reservoir_changes
insight_log_tube_changes
insight_log_site_changes
insight_log_battery_changes
insight_log_operating_mode_changes
insight_log_alerts
insight_enable_tbr_emulation
insight_min_recovery_duration
insight_max_recovery_duration
insight_disconnect_delay
InsulinOrefFreePeak
insulin_oref_peak
language
aps_general
aps_mode
loop_openmode_min_change
maintenance
maintenance_logs_amount
pref_medtronic_pump_type
pref_medtronic_frequency
pref_medtronic_max_basal
pref_medtronic_max_bolus
pref_medtronic_bolus_delay
pref_medtronic_encoding
pref_medtronic_battery_type
pref_medtronic_bolus_debug
ns_logappstartedevent
nsalarm_urgent_high
nsalarm_high
nsalarm_low
nsalarm_urgent_low
nsalarm_staledata
nsalarm_staledatavalue
nsalarm_urgent_staledata
nsalarm_urgent_staledatavalue
ns_wifionly
ns_wifi_ssids
ns_allowroaming
ns_chargingonly
ns_autobackfill
ns_create_announcements_from_errors
nsclient_localbroadcasts
ns_upload_only
ns_noupload
ns_sync_use_absolute
openapsama
openapsma_max_basal
openapsma_max_iob
openapsama_useautosens
autosens_adjust_targets
openapsama_min_5m_carbimpact
always_use_shortavg
openapsama_max_daily_safety_multiplier
openapsama_current_basal_safety_multiplier
bolussnooze_dia_divisor
openaps
openapsma_max_basal
openapsma_max_iob
always_use_shortavg
bolussnooze_dia_divisor
openapssmb
openapsma_max_basal
openapsmb_max_iob
openapsama_useautosens
use_smb
enableSMB_with_COB
enableSMB_with_temptarget
enableSMB_with_high_temptarget
enableSMB_always
enableSMB_after_carbs
smbmaxminutes
use_uam
high_temptarget_raises_sensitivity
low_temptarget_lowers_sensitivity
always_use_shortavg
openapsama_max_daily_safety_multiplier
openapsama_current_basal_safety_multiplier
others
eatingsoon_duration
eatingsoon_target
activity_duration
activity_target
hypo_duration
hypo_target
fill_button1
fill_button2
fill_button3
low_mark
high_mark
short_tabtitles
enable_missed_bg_readings
missed_bg_readings_threshold
enable_pump_unreachable_alert
raise_urgent_alarms_as_android_notification
keep_screen_on
show_treatment_button
show_wizard_button
show_insulin_button
insulin_button_increment_1
insulin_button_increment_2
insulin_button_increment_3
show_carbs_button
carbs_button_increment_1
carbs_button_increment_2
carbs_button_increment_3
show_cgm_button
show_calibration_button
show_notes_entry_dialogs
quickwizard
key_advancedsettings
boluswizard_percentage
key_usersuperbolus
key_show_statuslights
key_show_statuslights_extended
key_statuslights_res_warning
key_statuslights_res_critical
key_statuslights_bat_warning
key_statuslights_bat_critical
dexcomg5_nsupload
dexcomg5_xdripupload
treatmentssafety
treatmentssafety_maxbolus
treatmentssafety_maxcarbs
smscommunicator
smscommunicator_remotecommandsallowed
tidepool_upload_screen
tidepool_upload_cgm
tidepool_upload_bolus
tidepool_upload_bg
tidepool_upload_tbr
tidepool_upload_profile
tidepool_dev_servers
tidepool_only_while_charging
tidepool_only_while_unmetered
virtualpump
virtualpump_uploadstatus
virtualpump_type
wearplugin
wearcontrol
wearplugin
wearwizard_bg
wearwizard_tt
wearwizard_trend
wearwizard_cob
wearwizard_bolusiob
wearwizard_basaliob
wearplugin
wear_detailediob
wear_detailed_delta
wear_showbgi
wear_predictions
wearplugin
wear_notifySMB
xdripstatus
xdripstatus_detailediob
xdripstatus_showbgi
""".trimIndent().split("\n").filterNot { it.isBlank() }.map { it.toUpperCase() }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -42,6 +42,7 @@ import info.nightscout.androidaps.interfaces.DatabaseHelperInterface;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData;
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin;
import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryData;
@ -63,6 +64,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
@Inject RxBusWrapper rxBus;
@Inject MedtronicPumpPlugin medtronicPumpPlugin;
@Inject DatabaseHelperInterface databaseHelper;
@Inject OpenHumansUploader openHumansUploader;
private CompositeDisposable disposable = new CompositeDisposable();
@ -107,9 +109,9 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
}
}
public Dao<Treatment, Long> getDao() {
public TreatmentDaoWrapper getDao() {
try {
return DaoManager.createDao(this.getConnectionSource(), Treatment.class);
return new TreatmentDaoWrapper(DaoManager.createDao(this.getConnectionSource(), Treatment.class));
} catch (SQLException e) {
aapsLogger.error("Cannot create Dao for Treatment.class");
}
@ -117,6 +119,53 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
return null;
}
class TreatmentDaoWrapper {
private final Dao<Treatment, Long> wrapped;
TreatmentDaoWrapper(Dao<Treatment, Long> wrapped) {
this.wrapped = wrapped;
}
public void executeRaw(String statement, String... arguments) throws SQLException {
wrapped.executeRaw(statement, arguments);
}
public List<Treatment> queryForAll() throws SQLException {
return wrapped.queryForAll();
}
public void delete(Treatment data) throws SQLException {
wrapped.delete(data);
openHumansUploader.enqueueTreatment(data, true);
}
public void create(Treatment data) throws SQLException {
wrapped.create(data);
openHumansUploader.enqueueTreatment(data);
}
public Treatment queryForId(long id) throws SQLException {
return wrapped.queryForId(id);
}
public void update(Treatment data) throws SQLException {
wrapped.update(data);
openHumansUploader.enqueueTreatment(data);
}
public QueryBuilder<Treatment, Long> queryBuilder() {
return wrapped.queryBuilder();
}
public List<Treatment> query(PreparedQuery<Treatment> data) throws SQLException {
return wrapped.query(data);
}
public long countOf() throws SQLException {
return wrapped.countOf();
}
}
@Override
public void onCreate() {
super.onCreate();
@ -250,6 +299,15 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
return new ArrayList<>();
}
public long count() {
try {
return this.getDao().countOf();
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return 0L;
}
/*
{
"_id": "551ee3ad368e06e80856e6a9",
@ -308,7 +366,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
//preserve carbs
if (existingTreatment.isValid && existingTreatment.carbs > 0 && treatment.carbs == 0) {
treatment.carbs = existingTreatment.carbs;
// preserve insulin
// preserve insulin
} else if (existingTreatment.isValid && existingTreatment.insulin > 0 && treatment.insulin == 0) {
treatment.insulin = existingTreatment.insulin;
}
@ -702,7 +760,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
@Nullable
public Treatment findByNSId(String _id) {
try {
Dao<Treatment, Long> daoTreatments = getDao();
TreatmentDaoWrapper daoTreatments = getDao();
QueryBuilder<Treatment, Long> queryBuilder = daoTreatments.queryBuilder();
Where where = queryBuilder.where();
where.eq("_id", _id);
@ -724,7 +782,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
public List<Treatment> getTreatmentDataFromTime(long mills, boolean ascending) {
try {
Dao<Treatment, Long> daoTreatments = getDao();
TreatmentDaoWrapper daoTreatments = getDao();
List<Treatment> treatments;
QueryBuilder<Treatment, Long> queryBuilder = daoTreatments.queryBuilder();
queryBuilder.orderBy("date", ascending);
@ -741,7 +799,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
public List<Treatment> getTreatmentDataFromTime(long from, long to, boolean ascending) {
try {
Dao<Treatment, Long> daoTreatments = getDao();
TreatmentDaoWrapper daoTreatments = getDao();
List<Treatment> treatments;
QueryBuilder<Treatment, Long> queryBuilder = daoTreatments.queryBuilder();
queryBuilder.orderBy("date", ascending);

View file

@ -79,7 +79,7 @@ class TreatmentsBolusFragment : DaggerFragment() {
})
}
}
val nsUploadOnly = sp.getBoolean(R.string.key_ns_upload_only, false)
val nsUploadOnly = sp.getBoolean(R.string.key_ns_upload_only, true)
if (nsUploadOnly) treatments_reshreshfromnightscout.visibility = View.GONE
}

View file

@ -78,7 +78,7 @@ class TreatmentsCareportalFragment : DaggerFragment() {
}
}
val nsUploadOnly = sp.getBoolean(R.string.key_ns_upload_only, false)
val nsUploadOnly = sp.getBoolean(R.string.key_ns_upload_only, true)
if (nsUploadOnly) careportal_refreshfromnightscout.visibility = View.GONE
}

View file

@ -65,7 +65,7 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
})
}
}
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
}
@Synchronized

View file

@ -418,7 +418,7 @@ class SWDefinition @Inject constructor(
private fun swDefinitionFull() { // List all the screens here
add(screenSetupWizard)
.add(screenLanguage)
//.add(screenLanguage)
.add(screenEula)
.add(if (isRunningTest()) null else screenPermissionBattery) // cannot mock ask battery optimization
.add(screenPermissionBt)
@ -446,7 +446,7 @@ class SWDefinition @Inject constructor(
private fun swDefinitionPumpControl() { // List all the screens here
add(screenSetupWizard)
.add(screenLanguage)
//.add(screenLanguage)
.add(screenEula)
.add(if (isRunningTest()) null else screenPermissionBattery) // cannot mock ask battery optimization
.add(screenPermissionBt)
@ -470,7 +470,7 @@ class SWDefinition @Inject constructor(
private fun swDefinitionNSClient() { // List all the screens here
add(screenSetupWizard)
.add(screenLanguage)
//.add(screenLanguage)
.add(screenEula)
.add(if (isRunningTest()) null else screenPermissionBattery) // cannot mock ask battery optimization
.add(screenPermissionStore)

View file

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

View file

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

View file

@ -46,6 +46,15 @@
style="@style/section_header_label"
android:text="@string/smscommunicator_otp_step3_test_header" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5sp"
android:layout_marginBottom="5sp"
android:paddingStart="15sp"
android:paddingEnd="15sp"
android:text="@string/smscommunicator_code_verify_info" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -56,13 +65,13 @@
android:layout_height="wrap_content"
android:paddingStart="15dp"
android:paddingEnd="5dp"
android:text="@string/smscommunicator_otp_verify_label" />
android:text="@string/smscommunicator_code_verify_label" />
<EditText
android:id="@+id/smscommunicator_otp_verify_edit"
android:layout_width="140sp"
android:layout_height="wrap_content"
android:hint="000 000 000"
android:hint="@string/smscommunicator_code_verify_hint"
android:inputType="number"
android:maxLength="12"
android:textAlignment="center"

View file

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:contentDescription="@null"
android:paddingBottom="16dp"
app:srcCompat="@drawable/open_humans" />
<TextView
android:id="@+id/member_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
tools:text="Project Member ID: 5151515" />
<TextView
android:layout_marginTop="8dp"
android:id="@+id/queue_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
tools:text="Queue Size: 155" />
<TextView
android:layout_marginTop="8dp"
android:id="@+id/worker_state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
tools:text="Worker State: Running" />
<Button
android:layout_marginTop="16dp"
android:id="@+id/login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/login" />
<Button
android:id="@+id/logout"
android:layout_marginTop="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/logout" />
</LinearLayout>
</ScrollView>

View file

@ -559,6 +559,7 @@
<string name="pump_unreachable">Помпата е недостъпна</string>
<string name="missed_bg_readings">Липсват данни за КЗ</string>
<string name="raise_notifications_as_android_notifications">Използвай системни известия за аларми и съобщения</string>
<string name="gradually_increase_notification_volume">Постепенно увеличаване на звука за сигнали и аларми</string>
<string name="localalertsettings_title">Локални аларми</string>
<string name="enable_missed_bg_readings_alert">Аларма при липса на данни за КЗ</string>
<string name="enable_pump_unreachable_alert">Аларма при недостъпна помпа</string>
@ -1133,10 +1134,8 @@
<string name="loop_tbrexecution_time_label">Продължителност на временни базали</string>
<string name="insight_alert_notification_channel">Информация за Insight Pump</string>
<!-- SMS Communicator & OTP Authenticator -->
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">от приложението AUTHENTICATOR за: %1$s</string>
<string name="smscommunicator_otp_enabled">Активиране на удостоверител</string>
<string name="smscommunicator_otp_enabled_summary">Удостоверяване чрез еднократна парола, генерирана с Google Authenticator или подобна програма за 2-факторна оторизация.</string>
<string name="smscommunicator_otp_pin">Допълнителен PIN в края на токен</string>
<string name="smscommunicator_otp_pin_summary">Допълнителни цифри, които следва да бъдат залепени в края на всяка генерирана еднократна парола</string>
<string name="smscomunicator_tab_otp_label">Настройка на удостоверителя</string>
<string name="smscommunicator_otp_verify_label">ОТР за проверка:</string>

View file

@ -174,6 +174,9 @@
<string name="preferences_import_canceled">Import zrušen! Předvolby NEBYLY importovány!</string>
<string name="preferences_import_impossible">Nelze naimportovat nastavení!</string>
<string name="goto_main_try_again">Prosím vraťte se zpět na hlavní obrazovku a zkuste to znovu.</string>
<string name="old_master_password">Původní hlavní heslo</string>
<string name="different_password_used">Tento soubor byl exportován a zašifrován jiným hlavním heslem. Chcete-li dešifrovat soubor, zadejte staré hlavní heslo.</string>
<string name="master_password_will_be_replaced">V důsledku úspěšného importu bude aktuální hlavní heslo NAHRAZENO tímto starým hlavním heslem!</string>
<string name="preferences_import_list_title">Vyberte soubor, který chcete importovat</string>
<string name="check_preferences_before_import">Před importem zkontrolujte předvolby:</string>
<string name="check_preferences_cannot_import">Předvolby nelze importovat!</string>
@ -1134,12 +1137,15 @@
<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>
<!-- SMS Communicator & OTP Authenticator -->
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">z aplikace Authenticator pro: %1$s</string>
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">z aplikace Authenticator pro: %1$s následováno kódem PIN</string>
<string name="smscommunicator_otp_enabled">Povolit Autentikátor</string>
<string name="smscommunicator_otp_enabled_summary">Ověření příkazů pomocí jednočasových hesel generovaných Google Authenticator nebo podobných 2FA aplikací.</string>
<string name="smscommunicator_otp_pin">Další PIN na konci tokenu</string>
<string name="smscommunicator_otp_pin">Další povinný kód PIN na konci tokenu</string>
<string name="smscommunicator_otp_pin_summary">Další číslice, které by měly být zapamatovány a přidány na konec každého vygenerovaného jednorázového hesla</string>
<string name="smscomunicator_tab_otp_label">Nastavení Autentikátoru</string>
<string name="smscommunicator_code_verify_label">Kód pro kontrolu:</string>
<string name="smscommunicator_code_verify_hint">OTP + PIN</string>
<string name="smscommunicator_code_verify_info">Ověřovací kód se skládá ze 6 číslic zobrazených aplikací Authenticator (známé jako OTP) následované 3 nebo více číslicemi povinného kódu PIN.</string>
<string name="smscommunicator_otp_verify_label">OTP pro kontrolu:</string>
<string name="smscommunicator_otp_reset_btn">Resetovat autentikátory</string>
<string name="smscommunicator_otp_reset_title">Resetovat klíč pro autentikátory</string>
@ -1178,4 +1184,34 @@
<string name="formatwithweight">Věk: %1$.0f Hmotnost: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% bazálu</string>
<string name="dpvdefaultprofile">Výchozí profil DPV</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Dokončit nastavení Open Humans…</string>
<string name="this_may_take_a_while">Může to chvíli trvat. Nevypínejte telefon nebo tento plugin.</string>
<string name="setup_finished">Nastavení dokončeno</string>
<string name="your_phone_will_upload_data">Váš telefon brzy odešle data do Open Humans.</string>
<string name="your_phone_is_upload_data">Váš telefon nyní nahrává data do Open Humans.</string>
<string name="setup_failed">Nastavení selhalo</string>
<string name="there_was_an_error">Došlo k chybě. Chcete-li pokračovat, zkuste se přihlásit znovu. Lituji &amp; Děkuji!</string>
<string name="open_humans_terms">Jedná se o open source nástroj, který zkopíruje vaše data do Open Humans. Zachováváme práva ke sdílení vašich údajů s třetími stranami bez vašeho výslovného povolení. Data, která projekt a aplikace obdrží, jsou identifikována pomocí náhodného ID uživatele a budou bezpečně přenášena pouze na účet Otevřít Humans a jen s vaším svolením. Můžete kdykoli zastavit odesílání a smazat Vaše data prostřednictvím adresy www.openhumans.org.</string>
<string name="i_understand_and_agree">Rozumím a souhlasím.</string>
<string name="login">Přihlášení</string>
<string name="logout">Odhlášení</string>
<string name="oh_logout_confirmation">Opravdu se chcete odhlásit a zastavit darování dat vědě?</string>
<string name="project_member_id">ID člena projektu: %s</string>
<string name="queue_size">Velikost fronty: %d</string>
<string name="terms_of_use">Smluvní podmínky</string>
<string name="not_logged_in">Nejste přihlášen</string>
<string name="you_need_to_accept_the_of_use_first">Nejprve je třeba přijmout podmínky použití.</string>
<string name="successfully_logged_in">Přihlášení proběhlo úspěšně</string>
<string name="setup_will_continue_in_background">Nastavení bude nyní dokončeno na pozadí. Děkujeme za nahrání vašich dat.\n\nNechte prosím tento plugin a váš telefon na krátkou dobu zapnutý, aby bylo dokončeno nastavení.</string>
<string name="completing_login">Dokončení přihlášení…</string>
<string name="donate_your_data_to_science">Darujte svá data vědě</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Byl jste odhlášen z Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Chcete-li se znovu přihlásit, klepněte zde, pokud to nebylo schválně.</string>
<string name="only_upload_if_connected_to_wifi">Odeslat pouze při připojení k Wi-Fi</string>
<string name="only_upload_if_charging">Odeslat pouze při nabíjení</string>
<string name="worker_state">Stav procesu: %s</string>
<string name="uploaded_data">Odeslaná data</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">Následující data budou nahrána do vašeho účtu Open Humans: hodnoty glykémie, události péče (kromě poznámek), rozložené bolusy, přepnutí profilu, celkové denní dávky, dočasné bazály, nastavení, verze aplikace, model zařízení a rozměry obrazovky. Tajné nebo soukromé informace, jako je URL nebo API heslo vašeho Nightscoutu, nahrány nebudou.</string>
</resources>

View file

@ -174,6 +174,9 @@
<string name="preferences_import_canceled">Import abgebrochen! Einstellungen wurden NICHT importiert!</string>
<string name="preferences_import_impossible">Einstellungen können nicht importiert werden!</string>
<string name="goto_main_try_again">Bitte gehe zurück zur Startseite und versuche es erneut.</string>
<string name="old_master_password">Altes Master-Passwort</string>
<string name="different_password_used">Diese Datei wurde mit einem anderen Master-Passwort exportiert und verschlüsselt. Gib zum Entschlüsseln Dein altes Master-Passwort ein.</string>
<string name="master_password_will_be_replaced">Der erfolgreiche Import führt dazu, dass Dein aktuelles Master-Passwort durch das alte Master-Passwort ERSETZT wird!</string>
<string name="preferences_import_list_title">Wähle die zu importierende Datei</string>
<string name="check_preferences_before_import">Überprüfe die Einstellungen vor dem Import:</string>
<string name="check_preferences_cannot_import">Einstellungen können nicht importiert werden!</string>
@ -559,7 +562,7 @@
<string name="pump_unreachable">Pumpe ist nicht erreichbar</string>
<string name="missed_bg_readings">BZ-Werte fehlen</string>
<string name="raise_notifications_as_android_notifications">Benutze Systemmeldungen für Alarme und Meldungen</string>
<string name="gradually_increase_notification_volume">Passe die Lautstärke für Alarme und Hinweise etwas an. </string>
<string name="gradually_increase_notification_volume">Lautstärke für Alarme und Benachrichtigungen schrittweise erhöhen</string>
<string name="localalertsettings_title">Lokale Alarme</string>
<string name="enable_missed_bg_readings_alert">Alarm, wenn keine Glukose-Daten empfangen werden</string>
<string name="enable_pump_unreachable_alert">Alarm, wenn die Pumpe nicht erreichbar ist</string>
@ -1135,12 +1138,15 @@ Unerwartetes Verhalten.</string>
<string name="loop_tbrexecution_time_label">Temp. BR Ausführungszeit</string>
<string name="insight_alert_notification_channel">Insight Pumpenalarme</string>
<!-- SMS Communicator & OTP Authenticator -->
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">von der Authentifizierungs-App für: %1$s</string>
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">von der Authenticator App für: %1$s gefolgt von der PIN</string>
<string name="smscommunicator_otp_enabled">Authentifizierung einschalten</string>
<string name="smscommunicator_otp_enabled_summary">Authentifiziere Befehle mit Einmal-Passwörtern, die von Google Authenticator oder ähnlichen Apps zur 2-Faktor-Authentifizierung generiert wurden.</string>
<string name="smscommunicator_otp_pin">Zusätzliche PIN am Ende des Tokens</string>
<string name="smscommunicator_otp_pin">Zusätzliche obligatorische PIN am Token-Ende</string>
<string name="smscommunicator_otp_pin_summary">Zusätzliche Ziffern, die auswendig gelernt und am Ende jedes generierten Einmal-Passworts angehängt werden sollten.</string>
<string name="smscomunicator_tab_otp_label">Konfiguration des Authentifikators</string>
<string name="smscommunicator_code_verify_label">Zu prüfender Code:</string>
<string name="smscommunicator_code_verify_hint">OTP + PIN</string>
<string name="smscommunicator_code_verify_info">Der Verifizierungscode besteht aus 6 Ziffern, die von Authenticator App (auch OTP genannt) angezeigt werden, gefolgt von 3 oder mehr Ziffern der obligatorischen PIN.</string>
<string name="smscommunicator_otp_verify_label">Zu überprüfendes OTP:</string>
<string name="smscommunicator_otp_reset_btn">Authentifikators zurücksetzen</string>
<string name="smscommunicator_otp_reset_title">Authentifikatorschlüssel zurücksetzen</string>
@ -1179,4 +1185,34 @@ Unerwartetes Verhalten.</string>
<string name="formatwithweight">Alter: %1$.0f Gewicht: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% der Basalrate</string>
<string name="dpvdefaultprofile">DPV-Standard-Profil</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Einrichtung von Open Humans abschließen…</string>
<string name="this_may_take_a_while">Das kann eine Weile dauern. Schalte Dein Telefon oder dieses Plugin nicht aus.</string>
<string name="setup_finished">Einrichtung abgeschlossen</string>
<string name="your_phone_will_upload_data">Dein Telefon wird in Kürze Daten zu Open Human hochladen.</string>
<string name="your_phone_is_upload_data">Dein Telefon lädt nun Daten zu Open Human hoch.</string>
<string name="setup_failed">Einrichtung fehlgeschlagen</string>
<string name="there_was_an_error">Es gab einen Fehler. Bitte logge Dich erneut ein, um fortzufahren. Entschuldigung &amp; Danke!</string>
<string name="open_humans_terms">Dies ist ein Open-Source-Tool, das Deine Daten nach Open Humans kopiert. Wir behalten uns keine Rechte vor, Deine Daten ohne Deine ausdrückliche Genehmigung an Dritte weiterzugeben. Die Daten, die das Projekt und die Anwendung erhalten, werden über eine zufällige Benutzer-ID identifiziert und nur dann sicher auf ein Open Humans-Konto übertragen, wenn Du diesem Vorgang zugestimmt habst. Du kannst das Hochladen beenden und Deine hochgeladenen Daten jederzeit über www.openhumans.org löschen.</string>
<string name="i_understand_and_agree">Verstanden und akzeptiert. </string>
<string name="login">Login</string>
<string name="logout">Logout</string>
<string name="oh_logout_confirmation">Willst Du Dich wirklich abmelden und die Spende von Daten an die Wissenschaft beenden?</string>
<string name="project_member_id">Project Member ID: %s</string>
<string name="queue_size">Größe der Warteschlange: %d</string>
<string name="terms_of_use">Nutzungsbedingungen</string>
<string name="not_logged_in">Nicht angemeldet</string>
<string name="you_need_to_accept_the_of_use_first">Du musst zuerst die Nutzungsbedingungen akzeptieren.</string>
<string name="successfully_logged_in">Erfolgreich angemeldet</string>
<string name="setup_will_continue_in_background">Die Einrichtung wird jetzt im Hintergrund abgeschlossen. Vielen Dank für das Hochladen Deiner Daten.\n\nBitte halte dieses Plugin und Dein Handy für kurze Zeit eingeschaltet, damit das Setup abgeschlossen werden kann.</string>
<string name="completing_login">Login wird abgeschlossen…</string>
<string name="donate_your_data_to_science">Spende deine Daten an Wissenschaft</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Du wurdest von Open Humans abgemeldet.</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Klicke hier, um Dich erneut anzumelden, falls dies versehentlich passiert ist.</string>
<string name="only_upload_if_connected_to_wifi">Nur über WLAN hochladen</string>
<string name="only_upload_if_charging">Nur beim Laden hochladen</string>
<string name="worker_state">Worker State: %s</string>
<string name="uploaded_data">Daten hochgeladen</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">Die folgenden Daten werden auf Dein Open Humans-Konto hochgeladen: Glukosewerte, Careportal-Ereignisse (außer Notizen), erweiterte Boli, Profilwechsel, Gesamttagesdosen, temporäre Basalwerte, Temporäre Ziele, Einstellungen, Anwendungsversion, Gerätemodell und Bildschirmabmessungen. Vertrauliche oder private Informationen wie z.B. Deine Nightscout-URL oder Dein API-Secret werden nicht hochgeladen.</string>
</resources>

View file

@ -1133,10 +1133,8 @@
<string name="loop_tbrexecution_time_label">Tiempo de ejecución para Temp Basal</string>
<string name="insight_alert_notification_channel">Alertas de bomba Insight</string>
<!-- SMS Communicator & OTP Authenticator -->
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">de app de Autentificación a: %1$s</string>
<string name="smscommunicator_otp_enabled">Habilitar autentificador</string>
<string name="smscommunicator_otp_enabled_summary">Comandos de autentificación usando One Time Password de Google Autenticator o apps 2FA similar.</string>
<string name="smscommunicator_otp_pin">PIN adicional en token final</string>
<string name="smscommunicator_otp_pin_summary">Los dígitos adicionales se deben memorizar y pegar al final de cada una de las contraseñas generadas por One Time Password</string>
<string name="smscomunicator_tab_otp_label">Configuración de autentificación</string>
<string name="smscommunicator_otp_verify_label">OTP para comprobar:</string>

View file

@ -174,6 +174,9 @@
<string name="preferences_import_canceled">Import annulé ! Les préférences n\'ont PAS été importées !</string>
<string name="preferences_import_impossible">Impossible d\'importer les préférences !</string>
<string name="goto_main_try_again">Veuillez retourner à l\'écran principal et réessayer.</string>
<string name="old_master_password">Ancien mot de passe principal</string>
<string name="different_password_used">Ce fichier a été exporté et chiffré avec un mot de passe principal différent. Veuillez renseigner votre ancien mot de passe principal pour déchiffrer le fichier.</string>
<string name="master_password_will_be_replaced">Suite à l\'importation réussie, le mot de place principal actuel SERA REMPLACÉ par cet ancien mot de passe!</string>
<string name="preferences_import_list_title">Sélectionner le fichier à importer</string>
<string name="check_preferences_before_import">Vérifiez les préférences avant d\'importer :</string>
<string name="check_preferences_cannot_import">Les préférences ne peuvent pas être importées !</string>
@ -560,6 +563,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<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 les notifications système pour les alertes et notifications</string>
<string name="gradually_increase_notification_volume">Augmentation progressive du volume pour les alertes et les 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>
@ -1134,10 +1138,8 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="loop_tbrexecution_time_label">Heure d\'exécution basal temp</string>
<string name="insight_alert_notification_channel">Alertes Pompe Insight</string>
<!-- SMS Communicator & OTP Authenticator -->
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">depuis l\'appli. Authenticateur pour : %1$s</string>
<string name="smscommunicator_otp_enabled">Activer l\'Authentificateur</string>
<string name="smscommunicator_otp_enabled_summary">Authentifier les commandes à l\'aide des mots de passe uniques (OTP) générés par Google Authenticator ou des applications 2FA similaires.</string>
<string name="smscommunicator_otp_pin">Code PIN supplémentaire à la fin de l\'OTP</string>
<string name="smscommunicator_otp_pin_summary">Chiffres supplémentaires qui doivent être mémorisés et collés à la fin de chaque OTP généré</string>
<string name="smscomunicator_tab_otp_label">Configuration de l\'Authentificateur</string>
<string name="smscommunicator_otp_verify_label">OTP à vérifier :</string>
@ -1178,4 +1180,33 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="formatwithweight">Âge: %1$.0f Poids: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% de basal</string>
<string name="dpvdefaultprofile">Profil par défaut DPV</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Fin de la configuration d\'Open Humans…</string>
<string name="this_may_take_a_while">Cela peut prendre un certain temps. N\'éteignez pas votre téléphone ni ce plugin.</string>
<string name="setup_finished">Configuration terminée</string>
<string name="your_phone_will_upload_data">Votre téléphone va bientôt télécharger les données vers Open Humans.</string>
<string name="your_phone_is_upload_data">Votre téléphone télécharge les données vers Open Humans.</string>
<string name="setup_failed">Échec de la configuration</string>
<string name="there_was_an_error">Une erreur s\'est produite. Essayez de vous reconnecter pour continuer. Désolé &amp; merci !</string>
<string name="open_humans_terms">Il s\'agit d\'un outil open source qui va copier vos données vers Open Humans. Nous ne conservons aucun droit de partage et vos données ne seront pas partagées avec des tiers sans votre autorisation explicite. Les données que le projet et l\'application reçoivent sont identifiées par un Identifiant utilisateur aléatoire et ne seront transmises à un compte Open Humans qu\'avec votre autorisation et en toute sécurité. Vous pouvez arrêter de télécharger et supprimer vos données de téléchargées à tout moment via www.openhumans.org.</string>
<string name="i_understand_and_agree">Je comprends et je suis d\'accord.</string>
<string name="login">Connexion</string>
<string name="logout">Déconnexion</string>
<string name="oh_logout_confirmation">Voulez-vous vraiment vous déconnecter et arrêter de donner vos données à la science?</string>
<string name="project_member_id">ID utilisateur : %s</string>
<string name="queue_size">Taille de la queue : %d</string>
<string name="terms_of_use">Conditions dUtilisation</string>
<string name="not_logged_in">Non connecté</string>
<string name="you_need_to_accept_the_of_use_first">Vous devez d\'abord accepter les conditions dutilisation.</string>
<string name="successfully_logged_in">Connexion réussie</string>
<string name="setup_will_continue_in_background">La configuration sera terminée en arrière-plan. Merci de télécharger vos données.\n\nVeuillez conserver ce plug-in et votre téléphone allumés pendant un petit moment pour que la configuration se termine.</string>
<string name="completing_login">Fin de la connexion…</string>
<string name="donate_your_data_to_science">Donner vos données à la science</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Vous avez été déconnecté d\'Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Cliquez ici pour vous connecter à nouveau si ce n\'était pas volontaire.</string>
<string name="only_upload_if_connected_to_wifi">Ne télécharger que si connecté au WiFi</string>
<string name="only_upload_if_charging">Ne télécharger que si en charge</string>
<string name="worker_state">État du travail : %s</string>
<string name="uploaded_data">Données transférées</string>
</resources>

View file

@ -76,7 +76,7 @@
<string name="prerequisites_supportedcgm">Un CGM Supportato.</string>
<string name="update_label">Argomento: aggiornamento di AndroidAPS</string>
<string name="whatistrue">Cosa è vero?</string>
<string name="update_git">Hai bisogno di avere Git installato.</string>
<string name="update_git">Devi avere Git installato.</string>
<string name="update_asap">Aggiornare appena la nuova versione viene rilasciata e avere abbastanza tempo per farlo.</string>
<string name="update_keys">Dovresti usare le stesse chiavi di firma.</string>
<string name="update_neverupdate">Non aggiornare mai se il sistema funziona bene.</string>

View file

@ -168,12 +168,15 @@
<string name="openapsma_maxbasal_summary">Questo valore è chiamato max basale nel contesto OpenAPS</string>
<string name="openapsma_maxiob_title">Max IOB da basale a cui limitare OpenAPS [U]</string>
<string name="openapsma_maxiob_summary">Questo valore è chiamato Max IOB nel contesto OpenAPS\nIndica l\'insulina massima in [U] che APS può erogare in contemporanea.</string>
<string name="password_preferences_encrypt_prompt">Ti verrà richiesta la password principale, che verrà utilizzata per crittografare le preferenze esportate.</string>
<string name="password_preferences_encrypt_prompt">Ti verrà richiesta la password master, che verrà utilizzata per crittografare le preferenze esportate.</string>
<string name="password_preferences_decrypt_prompt">Ti verrà chiesta la password master, che è necessaria per decrittare le preferenze importate.</string>
<string name="preferences_export_canceled">Esportazione annullata! Le preferenze NON sono state esportate!</string>
<string name="preferences_import_canceled">Importazione annullata! Le preferenze NON sono state importate!</string>
<string name="preferences_import_impossible">Impossibile importare le preferenze!</string>
<string name="goto_main_try_again">Torna alla schermata principale e riprova.</string>
<string name="old_master_password">Password Master precedente</string>
<string name="different_password_used">Questo file è stato esportato e crittografato con una password master differente. Fornire la password master precedente per decrittare il file.</string>
<string name="master_password_will_be_replaced">Come risultato dell\'importazione riuscita, la password master corrente VERRÀ SOSTITUITA con la password master precedente contenuta nel file importato!</string>
<string name="preferences_import_list_title">Seleziona il file da importare</string>
<string name="check_preferences_before_import">Verifica le preferenze prima dell\'importazione:</string>
<string name="check_preferences_cannot_import">Le preferenze non possono essere importate!</string>
@ -559,6 +562,7 @@
<string name="pump_unreachable">Micro irraggiungibile</string>
<string name="missed_bg_readings">Letture BG mancanti</string>
<string name="raise_notifications_as_android_notifications">Usa le notifiche di sistema per gli avvisi</string>
<string name="gradually_increase_notification_volume">Aumenta gradualmente il volume per avvisi e notifiche</string>
<string name="localalertsettings_title">Avvisi locali</string>
<string name="enable_missed_bg_readings_alert">Avviso se non si ricevono dati BG</string>
<string name="enable_pump_unreachable_alert">Avviso se il micro è irraggiungibile</string>
@ -1090,7 +1094,7 @@
<string name="isf_short">ISF</string>
<string name="target_short">TARG</string>
<string name="clone_label">Clona</string>
<string name="saveorresetchangesfirst">Salva o reimposta prima le modifiche correnti</string>
<string name="saveorresetchangesfirst">Salva o resetta prima le modifiche correnti</string>
<string name="deletecurrentprofile">Rimuovere il profilo corrente?</string>
<string name="copytolocalprofile">Creare un nuovo profilo locale da questo profilo?</string>
<string name="profilenamecontainsdot">Il nome profilo contiene dei punti.\nQuesto non è supportato da NS.\nIl profilo non viene caricato in NS.</string>
@ -1133,12 +1137,14 @@
<string name="loop_tbrexecution_time_label">Esecuzione basale temporanea (momento)</string>
<string name="insight_alert_notification_channel">Avvisi micro Insight</string>
<!-- SMS Communicator & OTP Authenticator -->
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">da app autenticatore per: %1$s</string>
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">da app autenticatore: %1$s seguito da PIN</string>
<string name="smscommunicator_otp_enabled">Abilita autenticatore</string>
<string name="smscommunicator_otp_enabled_summary">Autentica i comandi utilizzando OTP (One Time Password) generate da Google Authenticator o app 2FA simili.</string>
<string name="smscommunicator_otp_pin">PIN aggiuntivo a fine token</string>
<string name="smscommunicator_otp_pin">PIN obbligatorio aggiuntivo a fine token</string>
<string name="smscommunicator_otp_pin_summary">Cifre aggiuntive che devono essere memorizzate e incollate alla fine di ogni OTP generata</string>
<string name="smscomunicator_tab_otp_label">Configurazione autenticatore</string>
<string name="smscommunicator_code_verify_hint">OTP + PIN</string>
<string name="smscommunicator_code_verify_info">Il codice di verifica è composto da 6 cifre visualizzate dall\'app autenticatore (note come OTP) seguite da 3 o più cifre del PIN obbligatorio.</string>
<string name="smscommunicator_otp_verify_label">OTP per verifica:</string>
<string name="smscommunicator_otp_reset_btn">Resetta autenticatori</string>
<string name="smscommunicator_otp_reset_title">Resetta chiave autenticatore</string>
@ -1177,4 +1183,34 @@
<string name="formatwithweight">Età: %1$.0f Peso: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% di basale</string>
<string name="dpvdefaultprofile">Profilo DPV predefinito</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Completamento configurazione Open Humans…</string>
<string name="this_may_take_a_while">Potrebbe volerci un po\' di tempo. Non spegnere il tuo telefono e non disattivare questo plugin.</string>
<string name="setup_finished">Configurazione completata</string>
<string name="your_phone_will_upload_data">Il tuo telefono caricherà a breve i dati su Open Humans.</string>
<string name="your_phone_is_upload_data">Il tuo telefono sta caricando ora i dati su Open Humans.</string>
<string name="setup_failed">Configurazione fallita</string>
<string name="there_was_an_error">Si è verificato un errore. Prova ad accedere di nuovo per procedere.</string>
<string name="open_humans_terms">Questo è uno strumento open source che copierà i tuoi dati su Open Humans. Non ci riserviamo alcun diritto di condividere i tuoi dati con terze parti senza la tua esplicita autorizzazione. I dati che il progetto e l\'app ricevono vengono identificati tramite un ID utente casuale e verranno trasmessi in modo sicuro a un account Open Humans solo con la tua autorizzazione per tale processo. Puoi interrompere il caricamento ed eliminare i dati di caricamento in qualsiasi momento tramite www.openhumans.org.</string>
<string name="i_understand_and_agree">Comprendo e accetto.</string>
<string name="login">Login</string>
<string name="logout">Logout</string>
<string name="oh_logout_confirmation">Vuoi davvero fare il logout e smettere di donare dati alla scienza?</string>
<string name="project_member_id">Project Member ID: %s</string>
<string name="queue_size">Dimensione coda: %d</string>
<string name="terms_of_use">Termini di utilizzo</string>
<string name="not_logged_in">Accesso non effettuato</string>
<string name="you_need_to_accept_the_of_use_first">Devi prima accettare i termini di utilizzo.</string>
<string name="successfully_logged_in">Accesso riuscito</string>
<string name="setup_will_continue_in_background">La configurazione verrà ora completata in background. Grazie per il caricamento dei tuoi dati.\n\nPer completare la configurazione, mantieni questo plugin attivo e il telefono acceso per un po\' di tempo.</string>
<string name="completing_login">Completamento accesso…</string>
<string name="donate_your_data_to_science">Dona i tuoi dati alla scienza</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Sei stato disconnesso da Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Fare click qui per accedere di nuovo.</string>
<string name="only_upload_if_connected_to_wifi">Upload solo se connesso a WiFi</string>
<string name="only_upload_if_charging">Upload solo se in carica</string>
<string name="worker_state">Worker State: %s</string>
<string name="uploaded_data">Dati caricati</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">I seguenti dati verranno caricati sul tuo account Open Humans: valori glicemia, eventi portale (eccetto note), boli estesi, cambi profilo, dosi giornaliere totali (TDD), basali temporanee, target temporanei, preferenze, versione dell\'applicazione, modello del dispositivo e dimensioni dello schermo. Informazioni segrete o private come l\'URL di Nightscout o l\'API secret non verranno caricate.</string>
</resources>

View file

@ -174,6 +174,9 @@
<string name="preferences_import_canceled">Importas nutrauktas! Nustatymai NE importuoti!</string>
<string name="preferences_import_impossible">Negalima importuoti nustatymų!</string>
<string name="goto_main_try_again">Prašome grįžti į pagrindinį ekraną ir bandyti dar kartą.</string>
<string name="old_master_password">Senasis pagrindinis slaptažodis</string>
<string name="different_password_used">Šis failas buvo eksportuotas ir užšifruotas su kitokiu pagrindiniu slaptažodžiu. Įveskite senąjį pagrindinį slaptažodį dešifruoti failui.</string>
<string name="master_password_will_be_replaced">Sėkmingas importavimas reiškia, kad dabartinis pagrindinis slaptažodis BUS PAKEISTAS senuoju pagrindiniu slaptažodžiu!</string>
<string name="preferences_import_list_title">Pasirinkite failą importavimui</string>
<string name="check_preferences_before_import">Prašom patikrinti nustatymus prieš importuojant:</string>
<string name="check_preferences_cannot_import">Nustatymai negali būti importuoti!</string>
@ -559,6 +562,7 @@
<string name="pump_unreachable">Pompa nepasiekiama</string>
<string name="missed_bg_readings">Negauti KG duomenys</string>
<string name="raise_notifications_as_android_notifications">Naudoti sistemos perspėjimus aliarmams ir įspėjimams</string>
<string name="gradually_increase_notification_volume">Palaipsniui didinkite įspėjimų ir pranešimų garso lygį</string>
<string name="localalertsettings_title">Lokalūs perspėjimai</string>
<string name="enable_missed_bg_readings_alert">Perspėjimas apie negautus KG duomenis</string>
<string name="enable_pump_unreachable_alert">Perspėjimas apie nepasiekiamą pompą</string>
@ -1133,12 +1137,15 @@
<string name="loop_tbrexecution_time_label">Laikinos bazės įvykdymo laikas</string>
<string name="insight_alert_notification_channel">Insight pompos aliarmai</string>
<!-- SMS Communicator & OTP Authenticator -->
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">tapatybės nustatymo programos: %1$s</string>
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">Authenticator programėlės: %1$s, po to - PIN</string>
<string name="smscommunicator_otp_enabled">Įgalinti tapatybės nustatymo funkciją</string>
<string name="smscommunicator_otp_enabled_summary">Autentifikuokite komandas naudodami vienkartinius slaptažodžius, sugeneruotus Google Authenticator ar panašiose 2FA programose.</string>
<string name="smscommunicator_otp_pin">Papildomas PIN kodas žymeklio gale</string>
<string name="smscommunicator_otp_pin">Papildomas privalomas PIN kodas žymeklio gale</string>
<string name="smscommunicator_otp_pin_summary">Papildomi skaitmenys, kuriuos reikia atsiminti ir pridėti kiekvieno sugeneruoto slaptažodžio pabaigoje</string>
<string name="smscomunicator_tab_otp_label">Autentifikavimo sąrankos nustatymas</string>
<string name="smscommunicator_code_verify_label">Kodas patikrinimui:</string>
<string name="smscommunicator_code_verify_hint">OTP + PIN</string>
<string name="smscommunicator_code_verify_info">Patvirtinimo kodą sudaro 6 skaitmenys, kuriuos rodo Authenticator programa (dar vadinama OTP), po 3 ar daugiau privalomo PIN skaitmenų.</string>
<string name="smscommunicator_otp_verify_label">OTP tikrinimas:</string>
<string name="smscommunicator_otp_reset_btn">Atstatyti tapatybės nustatymą</string>
<string name="smscommunicator_otp_reset_title">Atstatyti autentifikatoriaus kodą</string>
@ -1177,4 +1184,34 @@
<string name="formatwithweight">Amžius: %1$.0f Svoris: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% bazės</string>
<string name="dpvdefaultprofile">Numatytasis profilis</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Baigiama Open Humans sąranka…</string>
<string name="this_may_take_a_while">Tai gali užtrukti. Neišjunkite telefono ar šio papildinio.</string>
<string name="setup_finished">Sąranka baigta</string>
<string name="your_phone_will_upload_data">Netrukus jūsų telefonas įkels duomenis į Open Human.</string>
<string name="your_phone_is_upload_data">Jūsų telefonas įkelia duomenis į Open Human.</string>
<string name="setup_failed">Sąranka nepavyko</string>
<string name="there_was_an_error">Įvyko klaida. Norėdami tęsti, prisijunkite dar kartą. Atsiprašome &amp; Ačiū!</string>
<string name="open_humans_terms">Tai yra atviro kodo įrankis, kuris nukopijuoja jūsų duomenis į Open Humans. Mes neturime teisės perduoti jūsų duomenų trečiosioms šalims be aiškaus jūsų sutikimo. Duomenys, kuriuos gauna projektas ir programa, identifikuojami pagal atsitiktinį vartotojo ID ir tik tada saugiai perkeliami į Open Humans paskyrą, jei sutinkate su šiuo procesu. Galite bet kada sustabdyti įkėlimą ir ištrinti savo įkeltus duomenis apsilankę www.openhumans.org.</string>
<string name="i_understand_and_agree">Aš suprantu ir sutinku.</string>
<string name="login">Prisijungti</string>
<string name="logout">Atsijungti</string>
<string name="oh_logout_confirmation">Ar tikrai norite atsisakyti prenumeratos ir nebeteikti duomenų mokslui?</string>
<string name="project_member_id">Projekto nario ID: %s</string>
<string name="queue_size">Eilės Dydis: %d</string>
<string name="terms_of_use">Naudojimosi sąlygos</string>
<string name="not_logged_in">Neprisijungęs</string>
<string name="you_need_to_accept_the_of_use_first">Jūs turite sutikti su naudojimo sąlygomis.</string>
<string name="successfully_logged_in">Sėkmingai prisijungta</string>
<string name="setup_will_continue_in_background">Sąranka bus baigta fone. Dėkojame, kad įkėlėte duomenis. \n\n Palaikykite šį papildinį ir telefoną įjungtus, kad būtų galima užbaigti sąranką.</string>
<string name="completing_login">Užbaigiamas prisijungimas…</string>
<string name="donate_your_data_to_science">Paaukokite savo duomenis mokslui</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Jūs buvote atjungtas iš Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Spustelėkite čia, kad prisijungtumėte dar kartą, jei tai atsitiko netyčia.</string>
<string name="only_upload_if_connected_to_wifi">Tik įkelti, jei prijungta prie WiFi</string>
<string name="only_upload_if_charging">Įkelti tik akumuliatoriaus įkrovimo metu</string>
<string name="worker_state">Darbinė Būklė: %s</string>
<string name="uploaded_data">Įkelti duomenis</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">Į jūsų Open Humans paskyrą bus įkelti šie duomenys: glikemijos reikšmės, priežiūros portalo įvykiai (išskyrus pastabas), ištęstiniai bolusai, profilio pakeitimai, visos paros dozės, laikinos valandinės bazės, laikini tikslai, nustatymai, programos versija, įrenginio modelis ir ekrano matmenys. Konfidenciali ar privati informacija, pvz., Jūsų Nightscout URL arba API slaptažodis, nebus įkelta.</string>
</resources>

View file

@ -1114,10 +1114,8 @@
<string name="loop_tbrexecution_time_label">Tijdelijke basaal uitvoering tijd</string>
<string name="insight_alert_notification_channel">Insight pomp waarschuwingen</string>
<!-- SMS Communicator & OTP Authenticator -->
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">van authentificatie app voor: %1$s</string>
<string name="smscommunicator_otp_enabled">Authentificatie inschakelen</string>
<string name="smscommunicator_otp_enabled_summary">Authentificeer SMS commando\'s met behulp van One Time Passwords (OTPs, eenmalige wachtwoorden) gegenereerd door Google Authenticator of soortgelijke 2FA apps.</string>
<string name="smscommunicator_otp_pin">Extra PIN aan einde van token</string>
<string name="smscommunicator_otp_pin_summary">Extra cijfers die je moet onthouden, en aan het eind van elk gegenereerd eenmalig wachtwoord moet toevoegen.</string>
<string name="smscomunicator_tab_otp_label">Authentificatie instellingen</string>
<string name="smscommunicator_otp_verify_label">Te controleren OTP:</string>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- <string name="fi_lang" translatable="false">Finnish</string> -->
<!-- <string name="he_lang" translatable="false">Hebrew</string> -->
<!-- <string name="ga_lang" translatable="false">Irish</string> -->
<!-- <string name="ja_lang" translatable="false">Japanese</string> -->
<!-- SMS Communicator & OTP Authenticator -->
</resources>

View file

@ -1116,10 +1116,8 @@
<string name="loop_tbrexecution_time_label">Czas wykonywania bazy tymczasowej</string>
<string name="insight_alert_notification_channel">Alarmy pompy Insight</string>
<!-- SMS Communicator & OTP Authenticator -->
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">z aplikacji Uwierzytelniającej: %1$s</string>
<string name="smscommunicator_otp_enabled">Włącz uwierzytelnianie</string>
<string name="smscommunicator_otp_enabled_summary">Uwierzytelnianie komend za pomocą haseł jednorazowych generowanych przez aplikację Google Authenticator lub podobnych aplikacji 2FA.</string>
<string name="smscommunicator_otp_pin">Dodatkowy PIN na końcu tokenu</string>
<string name="smscommunicator_otp_pin_summary">Dodatkowe cyfry, które powinny być zapamiętywane i przyklejone na końcu każdego wygenerowanego hasła jednorazowego</string>
<string name="smscomunicator_tab_otp_label">Ustawienia uwierzytelnienia</string>
<string name="smscommunicator_otp_verify_label">OTP do sprawdzenia:</string>

View file

@ -1068,10 +1068,8 @@
<string name="loop_tbrexecution_time_label">Hora de execução Basal Temp</string>
<string name="insight_alert_notification_channel">Alertas Bomba Insight</string>
<!-- SMS Communicator & OTP Authenticator -->
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">a partir da app Autenticador para: %1$s</string>
<string name="smscommunicator_otp_enabled">Ativar Autenticador</string>
<string name="smscommunicator_otp_enabled_summary">Autenticar comandos usando Uma-Password-Única que sejam geradas pelo Google Authenticator ou app 2FA similar.</string>
<string name="smscommunicator_otp_pin">PIN adicional no token final</string>
<string name="smscommunicator_otp_pin_summary">Dígitos adicionais que devem ser memorizados e colados no final de cada Uma-Password-Única que seja gerada</string>
<string name="smscomunicator_tab_otp_label">Configuração do Autenticador</string>
<string name="smscommunicator_otp_verify_label">OTP para verificar:</string>

View file

@ -168,12 +168,15 @@
<string name="openapsma_maxbasal_summary">Este valor é chamado max basal no contexto do OpenAPS</string>
<string name="openapsma_maxiob_title">Basal Máxima IOB que OpenAPS pode administrar [U]</string>
<string name="openapsma_maxiob_summary">Este valor é denominado Max IOB em contexto OpenAPS \nEste é o valor máximo de insulina em [U] que APS pode administrar de uma vez.</string>
<string name="password_preferences_encrypt_prompt">Será perguntado pela senha mestre, que será usada para encriptar preferências exportadas.</string>
<string name="password_preferences_decrypt_prompt">Será perguntado pela senha mestre, que será necessária para desencriptar preferências importadas.</string>
<string name="password_preferences_encrypt_prompt">Será perguntado pela senha mestra, que será usada para encriptar preferências exportadas.</string>
<string name="password_preferences_decrypt_prompt">Será perguntado pela senha mestra, que será necessária para desencriptar preferências importadas.</string>
<string name="preferences_export_canceled">Exportação cancelada! Preferências NÃO foram exportadas!</string>
<string name="preferences_import_canceled">Importação cancelada! Preferências NÃO foram importadas!</string>
<string name="preferences_import_impossible">Não é possível importar as preferências!</string>
<string name="goto_main_try_again">Por favor, volte ao ecrã principal e tente novamente.</string>
<string name="old_master_password">Senha mestra antiga</string>
<string name="different_password_used">Este ficheiro foi exportado e criptografado com senha mestra diferente. Forneça a senha mestra antiga para descriptografar o ficheiro.</string>
<string name="master_password_will_be_replaced">Como resultado da importação bem sucedida senha mestra actual VAI SER SUBSTITUÍDA com a antiga senha mestra!</string>
<string name="preferences_import_list_title">Seleccione o ficheiro para importação</string>
<string name="check_preferences_before_import">Por favor, verifique as preferências antes da importação:</string>
<string name="check_preferences_cannot_import">Preferências não podem ser importadas!</string>
@ -208,7 +211,7 @@
<string name="prefdecrypt_issue_missing_file_hash">Ficheiro de verificação (hash) em falta, não é possível verificar a autenticidade de configurações!</string>
<string name="prefdecrypt_issue_modified">Ficheiro foi modificado após exportação!</string>
<string name="prefdecrypt_issue_parsing">Erro Desencriptação, a análise de preferências falhou!</string>
<string name="prefdecrypt_issue_wrong_pass">Erro de Desencriptação, a senha é inválida ou configurações de arquivo foram modificadas! Pode acontecer que o ficheiro importado foi exportado com uma Senha Mestre diferente.</string>
<string name="prefdecrypt_issue_wrong_pass">Erro de Desencriptação, a senha é inválida ou configurações de arquivo foram modificadas! Pode acontecer que o ficheiro importado foi exportado com uma Senha Mestra diferente.</string>
<string name="prefdecrypt_issue_wrong_format">Configuração de encriptação ausente, formato de configurações é inválido!</string>
<string name="prefdecrypt_issue_wrong_algorithm">Algoritmo de encriptação não suportado ou não especificado!</string>
<string name="exported_today">exportado hoje</string>
@ -1134,10 +1137,8 @@
<string name="loop_tbrexecution_time_label">Hora de execução Basal Temp</string>
<string name="insight_alert_notification_channel">Alertas Bomba Insight</string>
<!-- SMS Communicator & OTP Authenticator -->
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">a partir da app Autenticador para: %1$s</string>
<string name="smscommunicator_otp_enabled">Activar Autenticador</string>
<string name="smscommunicator_otp_enabled_summary">Autenticar comandos usando Uma-Senha-Única que sejam geradas pelo Google Authenticator ou app 2FA similar.</string>
<string name="smscommunicator_otp_pin">PIN adicional no token final</string>
<string name="smscommunicator_otp_pin_summary">Dígitos adicionais que devem ser memorizados e colados no final de cada Uma-Senha-Única que seja gerada</string>
<string name="smscomunicator_tab_otp_label">Configuração do Autenticador</string>
<string name="smscommunicator_otp_verify_label">OTP para verificar:</string>
@ -1159,7 +1160,7 @@
<string name="authorizationfailed">Falha na autorização</string>
<string name="overview_show_absinsulin">Insulina absoluta</string>
<string name="master_password_summary">Senha Mestre é usada para encriptação da cópia de segurança e substituir segurança na aplicação. Lembre-se dela ou guarde-a em um lugar seguro.</string>
<string name="current_master_password">Senha Mestre actual</string>
<string name="current_master_password">Senha Mestra actual</string>
<string name="statuslights">Luzes de Estado</string>
<string name="statuslights_copy_ns">Copiar definições do NS</string>
<string name="copyexistingvalues">Copiar definições do NS (se existir)?</string>
@ -1178,4 +1179,21 @@
<string name="formatwithweight">Idade: %1$.0f Peso: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% de basal</string>
<string name="dpvdefaultprofile">Perfil Padrão DPV</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">A terminar configuração Open Humans...</string>
<string name="setup_finished">Configuração terminada</string>
<string name="setup_failed">Falha na configuração</string>
<string name="i_understand_and_agree">Compreendo e concordo.</string>
<string name="login">Login</string>
<string name="logout">Terminar Sessão</string>
<string name="queue_size">Tamanho da Fila: %d</string>
<string name="terms_of_use">Termos de Utilização</string>
<string name="not_logged_in">Não tem sessão iniciada</string>
<string name="successfully_logged_in">Login bem sucedido</string>
<string name="completing_login">A completar o login…</string>
<string name="donate_your_data_to_science">Doar seus dados para a ciência</string>
<string name="open_humans_short">OH</string>
<string name="only_upload_if_connected_to_wifi">Apenas enviar se ligado ao Wi-Fi</string>
<string name="only_upload_if_charging">Apenas enviar se estiver a carregar</string>
<string name="uploaded_data">Dados Enviados</string>
</resources>

View file

@ -156,6 +156,7 @@
<string name="overview_tempbasal_button">Bazală temporară</string>
<string name="overview_extendedbolus_button">Bolus extins</string>
<string name="configbuilder_nightscoutversion_label">Versiune Nightscout:</string>
<string name="missing_carbs">Lipsă %1$d g</string>
<string name="exported">Am exportat preferințele</string>
<string name="export_to">Exportă setările către</string>
<string name="import_from">Importă setările din</string>
@ -173,6 +174,9 @@
<string name="preferences_import_canceled">Importarea a eșuat! Preferințele NU au fost importate!</string>
<string name="preferences_import_impossible">Nu se pot prelua setările!</string>
<string name="goto_main_try_again">Mergeți la ecranul principal și încercați din nou.</string>
<string name="old_master_password">Parola Master veche</string>
<string name="different_password_used">Acest fişier a fost exportat şi criptat cu o parolă master diferită. Furnizaţi parola master veche pentru a decripta fişierul.</string>
<string name="master_password_will_be_replaced">Ca rezultat al unui import reusit, parola master curenta VA FI INLOCUITA cu parola master veche!</string>
<string name="preferences_import_list_title">Selectați fișierul pentru import</string>
<string name="check_preferences_before_import">Verificați preferințele înainte de a le importa:</string>
<string name="check_preferences_cannot_import">Preferințele nu pot fi importate!</string>
@ -234,6 +238,10 @@
<string name="smscommunicator_remotebolusmindistance_summary">Numarul minim de minute care trebuie sa treaca intre un bolus la distanta si urmatorul</string>
<string name="smscommunicator_remotebolusmindistance">Cate minute trebuie sa treaca, cel puţin, intre un bolus si următorul</string>
<string name="smscommunicator_remotebolusmindistance_caveat">Pentru siguranta dumneavoastra, pentru a edita aceasta preferinta trebuie sa adaugati cel putin 2 numere de telefon.</string>
<string name="bolusdelivered">Bolusul de %1$.2fU a fost livrat cu succes</string>
<string name="bolusrequested">Se vor livra %1$.2fU</string>
<string name="smscommunicator_bolusdelivered">Bolusul de %1$.2fU a fost livrat cu succes</string>
<string name="smscommunicator_mealbolusdelivered">Bolusul de masa de %1$.2fU a fost livrat cu succes</string>
<string name="smscommunicator_mealbolusdelivered_tt">Țintă %1$s pentru %2$d minute</string>
<string name="smscommunicator_tt_set">Tinta %1$s pentru %2$d minute este setata cu succes</string>
<string name="smscommunicator_tt_canceled">Tinta temporara anulata cu succes</string>
@ -257,7 +265,9 @@
<string name="smscommunicator_reconnect">Pompă reconectată</string>
<string name="smscommunicator_remotecommandnotallowed">Comanda de la distanță nu este permisă</string>
<string name="smscommunicator_remotebolusnotallowed">Bolus de la distanță nu este disponibil. Încearcă din nou mai târziu.</string>
<string name="smscommunicator_basalreplywithcode">Pentru a iniția bazala de %1$.2fU/h pentru %2$d min trimiteți codul %3$s</string>
<string name="smscommunicator_profilereplywithcode">Pentru a schimba profilul în %1$s %2$d%% trimiteți codul %3$s</string>
<string name="smscommunicator_extendedreplywithcode">Pentru a iniția bolusul extins de %1$.2fU/h pentru %2$d min trimiteți codul %3$s</string>
<string name="smscommunicator_carbsreplywithcode">Pentru a introduce %1$dg la %2$s, raspundeti cu: %3$s</string>
<string name="smscommunicator_basalpctreplywithcode">Pentru a iniția bazala de %1$d%% pentru %2$d min trimiteți codul %3$s</string>
<string name="smscommunicator_suspendreplywithcode">Pentru suspendarea buclei pentru %1$d minute trimiteți codul %2$s</string>
@ -266,6 +276,7 @@
<string name="smscommunicator_loopdisablereplywithcode">Pentru a dezactiva bucla inchisa, raspundeti cu %1$s</string>
<string name="smscommunicator_tempbasalset">Bazala temporară %1$.2fU/h pentru %2$d minute a fost trimisă cu succes</string>
<string name="smscommunicator_extendedset">Bolusul extins de %1$.2fU pentru %2$d min a fost inițiat</string>
<string name="smscommunicator_carbsset">%1$dg carbohidrați introduși cu succes</string>
<string name="smscommunicator_carbsfailed">Introducerea a %1$dg de carbohidrati a esuat</string>
<string name="smscommunicator_tempbasalset_percent">Bazala temporară %1$d%% pentru %2$d minute a fost stabilită cu succes</string>
<string name="smscommunicator_tempbasalfailed">Trimiterea bazalei temporare a eșuat</string>
@ -551,6 +562,7 @@
<string name="pump_unreachable">Pompă indisponibilă</string>
<string name="missed_bg_readings">Lipsesc date glicemie</string>
<string name="raise_notifications_as_android_notifications">Se folosesc notificările sistemului pentru alerte și notificări</string>
<string name="gradually_increase_notification_volume">Creşterea treptată a volumului pentru alerte şi notificări</string>
<string name="localalertsettings_title">Alerte locale</string>
<string name="enable_missed_bg_readings_alert">Alarmează dacă nu se primesc glicemii</string>
<string name="enable_pump_unreachable_alert">Se alertează dacă pompa este indisponibilă</string>
@ -846,6 +858,7 @@
<string name="code_compare">Sunt identice codurile afișate aici și cele de pe pompă?</string>
<string name="insight_pairing">Asociere Insight</string>
<string name="insight_local">Accu-Chek Insight</string>
<string name="insight_delivered">%1$.2f U din %2$.2f U livrate</string>
<string name="insight_alert_formatter">%1$s:%2$s</string>
<string name="tube_changed">Canulă schimbată</string>
<string name="pump_time_updated">Timpul din pompă a fost actualizat</string>
@ -903,6 +916,7 @@
<string name="short_status_extended">Extins: %1$.2f / %2$.2f U pentru %3$d min</string>
<string name="short_status_multiwave">Multiwave: %1$.2f / %2$.2f U pentru %3$d min</string>
<string name="short_status_tdd">TDD: %1$.2f</string>
<string name="short_status_reservoir">Rezervor: %1$.2fU</string>
<string name="short_status_battery">Bat.: %1$d%%</string>
<string name="max_recovery_duration">Timpul maxim de restabilire [s]</string>
<string name="min_recovery_duration">Timpul minim de restabilire [s]</string>
@ -1045,6 +1059,8 @@
<string name="sendsmsactionlabel">Trimite SMS: %1$s</string>
<string name="sendsmsactiondescription">Trimite SMS către toate numerele</string>
<string name="sendsmsactiontext">Trimite SMS cu text</string>
<string name="cobvsiob">COB vs IOB</string>
<string name="bolusconstraintappliedwarn">Este aplicatâ limitarea bolusului %1$.2f U la %2$.2f U</string>
<string name="slowabsorptiondetected"><![CDATA[<font color=\'%1$s\'>!!!!! A fost detectată o absorbție lentă a carbohidraților: %2$d%% din timp. Reverificați calculele. COB poate fi supraestimat, astfel că este posibilă administrarea de mai multă insulină !!!!!</font>]]></string>
<string name="partialboluswizard">Livrați doar partea aceasta din rezultatul sugerat de wizard [%]</string>
<string name="deliverpartofboluswizard">Wizard bolus face un calcul, dar numai o parte din insulina calculată este și livrată. Este mai eficient când se folosește cu algoritmul SMB.</string>
@ -1121,12 +1137,15 @@
<string name="loop_tbrexecution_time_label">Timpul de execuție al bazalei temporare</string>
<string name="insight_alert_notification_channel">Alerte pompă Insight</string>
<!-- SMS Communicator & OTP Authenticator -->
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">de la aplicația Authenticator pentru: %1$s</string>
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">de la aplicația Authenticator pentru: %1$s urmat de PIN</string>
<string name="smscommunicator_otp_enabled">Activare Authenticator</string>
<string name="smscommunicator_otp_enabled_summary">Autentificați comenzile folosind o parolă unica generată de Google Authenticator sau alte aplicații 2FA similare.</string>
<string name="smscommunicator_otp_pin">PIN adițional la sfârșitul token-ului</string>
<string name="smscommunicator_otp_pin">PIN obligatoriu suplimentar la sfârșitul token-ului</string>
<string name="smscommunicator_otp_pin_summary">Cifre suplimentare care ar trebui să fie memorate și adăugate la sfârșitul fiecărei parole unice generate</string>
<string name="smscomunicator_tab_otp_label">Setare Authenticator</string>
<string name="smscommunicator_code_verify_label">Cod de verificat:</string>
<string name="smscommunicator_code_verify_hint">OTP + cod PIN</string>
<string name="smscommunicator_code_verify_info">Codul de verificare constă din 6 cifre afişate de către aplicaţia Authentificator (cunoscută ca OTP), urmat de 3 sau mai multe cifre de PIN obligatoriu.</string>
<string name="smscommunicator_otp_verify_label">Parola unică pentru verificare:</string>
<string name="smscommunicator_otp_reset_btn">Resetați Authenticatori</string>
<string name="smscommunicator_otp_reset_title">Resetați cheia pentru Authenticator</string>
@ -1165,4 +1184,34 @@
<string name="formatwithweight">Vârstă: %1$.0f Greutate: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% din bazală</string>
<string name="dpvdefaultprofile">Profil implicit DPV</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Finalizare configurare Open Humans…</string>
<string name="this_may_take_a_while">Acest lucru poate dura un timp. Nu opriți telefonul și nici acest plugin.</string>
<string name="setup_finished">Configurare terminată</string>
<string name="your_phone_will_upload_data">Telefonul tău va încărca date către Open Humans în curând.</string>
<string name="your_phone_is_upload_data">Telefonul tău încarcă date în Open Humans acum.</string>
<string name="setup_failed">Configurare eșuată</string>
<string name="there_was_an_error">A apărut o eroare. Te rugăm să încerci să te autentifici din nou pentru a continua. Ne pare rău. Mulțumim!</string>
<string name="open_humans_terms">Aceasta este un instrument open source care va copia datele tale în Open Humans. Nu avem dreptul sa împărtășim datele tale cu terțe părți fără autorizație explicită. Datele pe care le primesc proiectul și aplicația sunt identificate printr-un ID de utilizator aleatoriu și vor fi transmise în siguranță într-un cont Open Humans numai cu autorizarea acestui proces. Poți înceta încărcarea și șterge datele oricând folosind www.openhumans.org.</string>
<string name="i_understand_and_agree">Înţeleg şi sunt de acord.</string>
<string name="login">Autentificare</string>
<string name="logout">Deconectare</string>
<string name="oh_logout_confirmation">Sigur doriți să vă deconectați și să încetați să donați date in scopuri științifice?</string>
<string name="project_member_id">ID Membru proiect: %s</string>
<string name="queue_size">Dimensiunea cozii: %d</string>
<string name="terms_of_use">Condiții de utilizare</string>
<string name="not_logged_in">Nu ești autentificat(ă)</string>
<string name="you_need_to_accept_the_of_use_first">Trebuie mai întâi să acceptați condițiile de utilizare.</string>
<string name="successfully_logged_in">Conectare reușită</string>
<string name="setup_will_continue_in_background">Setarea va fi finalizată în fundal acum. Vă mulțumim pentru încărcarea datelor.\n\nVă rugăm să păstrați acest plugin și telefonul pornit pentru o scurtă perioadă de timp astfel încât setarea să se finalizeze.</string>
<string name="completing_login">Finalizare autentificare…</string>
<string name="donate_your_data_to_science">Donează datele în scopuri științifice</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Ai fost deconectat de la Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Dați click aici pentru a vă conecta din nou dacă nu a fost intenționat.</string>
<string name="only_upload_if_connected_to_wifi">Încarcă numai pe conexiune WiFi</string>
<string name="only_upload_if_charging">Încărca numai dacă telefonul este la încărcat</string>
<string name="worker_state">Stare prelucrare: %s</string>
<string name="uploaded_data">Date încărcate</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">Următoarele date vor fi încărcate în contul Open Humans: glicemii, evenimente careportal (cu excepția notelor), bolusuri extinse, schimbări de profil, doze zilnice totale, bazale temporare, ținte temporare, preferințe, versiunea aplicației, model dispozitiv și dimensiunile ecranului. Informațiile secrete sau private, cum ar fi URL-ul Nightscout sau secretul API, nu vor fi încărcate.</string>
</resources>

View file

@ -71,7 +71,7 @@
<string name="openapsma_glucosestatus_label">статус гликемии</string>
<string name="openapsma_currenttemp_label">текущий врем базал</string>
<string name="openapsma_iobdata_label">данные IOB (активн инс)</string>
<string name="openapsma_profile_label">профиль</string>
<string name="openapsma_profile_label">Профиль</string>
<string name="openapsma_mealdata_label">данные приема пищи</string>
<string name="result">результат</string>
<string name="result_insulin_carbs">Результат: %1$s %2$s</string>
@ -80,12 +80,12 @@
<string name="glucose">гликемия</string>
<string name="delta">изменение</string>
<string name="sms_delta">дельта:</string>
<string name="configbuilder">конфигуратор</string>
<string name="overview">начало</string>
<string name="configbuilder">Конфигуратор</string>
<string name="overview">Начало</string>
<string name="nsprofile">профиль NS</string>
<string name="simpleprofile">простой профиль</string>
<string name="treatments">Терапия</string>
<string name="virtualpump">виртуальная помпа</string>
<string name="virtualpump">Виртуальная помпа</string>
<string name="careportal">Портал лечения / назначений</string>
<string name="configbuilder_pump">помпа</string>
<string name="configbuilder_pump_description">Какой помпой вы хотели бы пользоваться с AndroidAPS?</string>
@ -122,9 +122,9 @@
<string name="changeyourinput">измените введенные данные</string>
<string name="configbuilder_bgsource">источник СК</string>
<string name="configbuilder_bgsource_description">Откуда должен получать данные AndroidAPS?</string>
<string name="xdrip">xdrip</string>
<string name="xdrip">xDrip +</string>
<string name="apsmode_title">режим APS</string>
<string name="closedloop">замкнутый цикл</string>
<string name="closedloop">Замкнутый цикл</string>
<string name="openloop">открытый цикл</string>
<string name="lowglucosesuspend">Приостановка помпы на низкой ГК</string>
<string name="disabledloop">цикличность неактивирована</string>
@ -174,6 +174,9 @@
<string name="preferences_import_canceled">Импорт отменен! Настройки не импортированы!</string>
<string name="preferences_import_impossible">Не удается импортировать настройки!</string>
<string name="goto_main_try_again">Вернитесь на главный экран и повторите попытку.</string>
<string name="old_master_password">Старый главный пароль</string>
<string name="different_password_used">Этот файл был экспортирован и зашифрован с использованием другого главного пароля. Укажите старый главный пароль для расшифровки файла.</string>
<string name="master_password_will_be_replaced">В результате успешного импорта текущий главный пароль БУДЕТ ЗАМЕНЁН на старый главный пароль!</string>
<string name="preferences_import_list_title">Выберите файл для импорта</string>
<string name="check_preferences_before_import">Проверьте настройки перед импортом:</string>
<string name="check_preferences_cannot_import">Не удается импортировать настройки!</string>
@ -510,7 +513,7 @@
<string name="keep_screen_on_title">Не отключать экран</string>
<string name="keep_screen_on_summary">Не давать системе Android отключать экран. Это увеличит потребление энергии при отключенной сети питания.</string>
<string name="sensitivity_warning">Активируя Autosense не забывайте вводить все съеденные углеводы. Иначе отклонения в углеводах будут неверно определены как изменение чувствительности !!</string>
<string name="sensitivityweightedaverage">средневзвешенная чувствительность</string>
<string name="sensitivityweightedaverage">Средневзвешенная чувствительность</string>
<string name="mdtp_ok">OK</string>
<string name="mdtp_cancel">отмена</string>
<string name="notloadedplugins">не все профили загружены!</string>
@ -530,7 +533,7 @@
<string name="insulin_oref_peak">Время пика действующего инс IOB</string>
<string name="insulin_peak_time">время пика (в мин.)</string>
<string name="free_peak_oref">Свободный от пиков Oref</string>
<string name="rapid_acting_oref">быстро действующий Oref</string>
<string name="rapid_acting_oref">Быстро действующий Oref</string>
<string name="ultrarapid_oref">Сверхбыстрый Oref</string>
<string name="dia_too_short">Значение длительности работы инс %1$f слишком мало - применено %2$f!</string>
<string name="activate_profile">АКТИВИРОВАТЬ ПРОФИЛЬ</string>
@ -559,6 +562,7 @@
<string name="pump_unreachable">Помпа недоступна</string>
<string name="missed_bg_readings">Пропущенные данные СК</string>
<string name="raise_notifications_as_android_notifications">Использовать системные уведомления для предупреждений и уведомлений</string>
<string name="gradually_increase_notification_volume">Постепенно увеличивать громкость оповещений и уведомлений</string>
<string name="localalertsettings_title">Локальные оповещения</string>
<string name="enable_missed_bg_readings_alert">Оповещать при отсутствии данных СК</string>
<string name="enable_pump_unreachable_alert">Оповещать в случае недоступности помпы</string>
@ -1135,10 +1139,8 @@ Context | Edit Context</string>
<string name="loop_tbrexecution_time_label">Время выполнения временной базальной скорости</string>
<string name="insight_alert_notification_channel">Оповещения помпы Insight</string>
<!-- SMS Communicator & OTP Authenticator -->
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">из приложения Authenticator на: %1$s</string>
<string name="smscommunicator_otp_enabled">Включить аутентификатор</string>
<string name="smscommunicator_otp_enabled_summary">Аутентифицировать команды с помощью одноразовых паролей, сгенерированных Google Authenticator или похожими приложениями 2FA.</string>
<string name="smscommunicator_otp_pin">Дополнительный PIN-код в конце маркера</string>
<string name="smscommunicator_otp_pin_summary">Дополнительные цифры, которые должны быть запомнены и добавлены в конце каждого сгенерированного одноразового пароля</string>
<string name="smscomunicator_tab_otp_label">Настройка аутентификации</string>
<string name="smscommunicator_otp_verify_label">OTP для проверки:</string>
@ -1179,4 +1181,34 @@ Context | Edit Context</string>
<string name="formatwithweight">Возраст: %1$.0f Вес: %2$.0f кг</string>
<string name="basalpctfromtdd_label">% базального</string>
<string name="dpvdefaultprofile">Значение для профиля по умолчанию</string>
<string name="open_humans">Проект Open Humans</string>
<string name="finishing_open_humans_setup">Завершение установки Open Humans…</string>
<string name="this_may_take_a_while">Это может занять некоторое время. Не выключайте телефон или этот плагин.</string>
<string name="setup_finished">Установка завершена</string>
<string name="your_phone_will_upload_data">Ваш телефон скоро загрузит данные на Open Humans.</string>
<string name="your_phone_is_upload_data">Ваш телефон сейчас загружает данные на Open Humans.</string>
<string name="setup_failed">Установка не выполнена</string>
<string name="there_was_an_error">Произошла ошибка. &amp; для продолжения попробуйте заново войти в систему!</string>
<string name="open_humans_terms">Это проект с открытым исходным кодом, который будет копировать ваши данные на Open Humans. Мы не будем обмениваться вашими данными с третьими лицами без вашего явного разрешения. Данные, отправляемые на проект и приложение, идентифицируются с помощью случайного идентификатора и будут безопасно передаваться на учетную запись Open Humans при вашем одобрении этого процесса. Вы можете остановить загрузку и удалить загруженные данные в любое время здесь: www.openhumans.org.</string>
<string name="i_understand_and_agree">Я понимаю и соглашаюсь.</string>
<string name="login">Вход</string>
<string name="logout">Выход</string>
<string name="oh_logout_confirmation">Вы действительно хотите выйти из системы и перестать отправлять данные исследователям?</string>
<string name="project_member_id">Идентификатор участника проекта: %s</string>
<string name="queue_size">Объем данных в очереди на отправку %d</string>
<string name="terms_of_use">Условия пользования</string>
<string name="not_logged_in">Не выполнен вход</string>
<string name="you_need_to_accept_the_of_use_first">Сначала нужно принять условия использования.</string>
<string name="successfully_logged_in">Вход выполнен успешно</string>
<string name="setup_will_continue_in_background">Настройка будет завершена в фоновом режиме. Спасибо, что загрузила ваши данные.\n\nНе выключайте этот плагин и телефон до завершения установки.</string>
<string name="completing_login">Завершение входа в систему…</string>
<string name="donate_your_data_to_science">Передайте свои данные исследователям</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Вы вышли из Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Нажмите здесь, чтобы снова войти в систему, если выход произошел случайно.</string>
<string name="only_upload_if_connected_to_wifi">Загружать только при подключении к WiFi</string>
<string name="only_upload_if_charging">Загружать только при зарядке</string>
<string name="worker_state">Рабочее состояние: %s</string>
<string name="uploaded_data">Загруженные данные</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">На ваш аккаунт Open Humans будут загружены следующие данные: значения ГК, события careportal (за исключением примечаний), пролонгированные болюсы, переключения профиля, суммарные суточные дозы, временные базалы, временные цели, настройки, версии приложения, модель устройства и размеры экрана. Секретная или конфиденциальная информация, такая как адрес вашего сайта Nightscout или API secret, не будет загружена.</string>
</resources>

View file

@ -13,7 +13,7 @@
<string name="reset_db_confirm">Naozaj chcete vymazať databázu?</string>
<string name="nav_exit">Ukončiť</string>
<string name="ns_sync_use_absolute_title">Vždy používaj absolútne hodnoty bazálov</string>
<string name="alert_dialog_storage_permission_text">Prosím reštartuj svoj telefón, alebo reštartuj AndroidAPS zo systémových nastavení, v opačnom prípade AndroidAPS nebude mocť zapisovať údaje (dôležité kvôli sledovaniu a overovaniu, že algoritmus pracuje správne)!</string>
<string name="alert_dialog_storage_permission_text">Prosím reštartuj svoj telefón, alebo reštartuj AndroidAPS zo systémových nastavení \nv opačnom prípade AndroidAPS nebude mocť zapisovať údaje (dôležité kvôli sledovaniu a overovaniu, že algoritmus pracuje správne)!</string>
<string name="alert_dialog_permission_battery_optimization_failed">Toto zariadenie zrejme neumožňuje vypnúť optimalizáciu batérie - môže dochádzať k problémom s výkonom.</string>
<string name="description_actions">Niektoré tlačidlá na rýchly prístup do spoločných funkcií</string>
<string name="description_config_builder">Používané na konfiguráciu aktívnych pluginov</string>
@ -174,6 +174,9 @@
<string name="preferences_import_canceled">Import zrušený! Nastavenia neboli importované!</string>
<string name="preferences_import_impossible">Nastavenia sa nedajú importovať!</string>
<string name="goto_main_try_again">Prosím, vráťte se späť na hlavnú obrazovku a skúste to znovu.</string>
<string name="old_master_password">Staré hlavné heslo</string>
<string name="different_password_used">Tento súbor bol exportovaný a zašifrovaný iným hlavným heslom. Pre dešifrovanie súboru použite staré hlavné heslo.</string>
<string name="master_password_will_be_replaced">V dôsledku úspešného importu bude aktuálne hlavné heslo NAHRADENÉ týmto starým hlavným heslom!</string>
<string name="preferences_import_list_title">Vyberte súbor, ktorý chcete importovať</string>
<string name="check_preferences_before_import">Prosím skontrolujte nastavenia predtým, ako importujete:</string>
<string name="check_preferences_cannot_import">Nastavenia nemôžu byť importované!</string>
@ -1134,12 +1137,15 @@
<string name="loop_tbrexecution_time_label">Čas spustenia dočasného bazálu</string>
<string name="insight_alert_notification_channel">Výstrahy pumpy Insight</string>
<!-- SMS Communicator & OTP Authenticator -->
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">z aplikácie Authenticator pre: %1$s</string>
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">z aplikácie Authenticator pre: %1$s nasledované kódom PIN</string>
<string name="smscommunicator_otp_enabled">Povoliť Autentifikátor</string>
<string name="smscommunicator_otp_enabled_summary">Autentifikačné príkazy používajú jednorázové heslá generované Google Authenticator, alebo podobnými 2FA aplikáciami.</string>
<string name="smscommunicator_otp_pin">Ďalší PIN na konci tokenu</string>
<string name="smscommunicator_otp_pin">Ďalší povinný kód PIN na konci tokenu</string>
<string name="smscommunicator_otp_pin_summary">Ďalšie číslice, ktoré by mali byť zapamätané a pridané na koniec každého vygenerovaného jednorázového hesla</string>
<string name="smscomunicator_tab_otp_label">Nastavenie autentifikátora</string>
<string name="smscommunicator_code_verify_label">Kód pre kontrolu:</string>
<string name="smscommunicator_code_verify_hint">OTP + PIN</string>
<string name="smscommunicator_code_verify_info">Overovací kód sa skladá zo 6 číslic zobrazených aplikáciou Authenticator (známej ako OTP) nasledované 3, alebo viacerými číslicami povinného kódu PIN.</string>
<string name="smscommunicator_otp_verify_label">OTP pre kontrolu:</string>
<string name="smscommunicator_otp_reset_btn">Resetovať autentifikátory</string>
<string name="smscommunicator_otp_reset_title">Resetovať autentifikačný kľúč</string>
@ -1178,4 +1184,34 @@
<string name="formatwithweight">Vek: %1$.0f Hmotnosť: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% bazálu</string>
<string name="dpvdefaultprofile">Predvolený DPV profil</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Dokončovanie nastavenia Open Humans...</string>
<string name="this_may_take_a_while">Môže to chvíľu trvať. Nevypínajte Váš telefón ani tento modul.</string>
<string name="setup_finished">Nastavenie dokončené</string>
<string name="your_phone_will_upload_data">Váš telefón čoskoro nahrá dáta na Open Humans.</string>
<string name="your_phone_is_upload_data">Váš telefón práve nahráva dáta na Open Humans.</string>
<string name="setup_failed">Nastavenie zlyhalo</string>
<string name="there_was_an_error">Vyskytla sa chyba. Prosím, skúste sa znova prihlásiť, aby ste mohli pokračovať. Prepáčte &amp; Ďakujem!</string>
<string name="open_humans_terms">Jedná sa o open source nástroj, ktorý skopíruje vaše dáta do Open Humans. Zachovávame práva na zdieľanie vašich údajov s tretími stranami bez vašeho výslovného povolenia. Dáta, ktoré projekt a aplikácia obdržia, sú identifikované pomocou náhodného ID užívateľa a budú bezpečne prenášané iba na účet Open Humans a len s vaším povolením. Môžete kedykoľvek zastaviť odosielanie a zmazať Vaše dáta prostredníctvom adresy www.openhumans.org.</string>
<string name="i_understand_and_agree">Rozumiem a potvrdzujem.</string>
<string name="login">Prihlásenie</string>
<string name="logout">Odhlásiť</string>
<string name="oh_logout_confirmation">Naozaj sa chceš odhlásiť a prestať tak prispievať údajmi vede?</string>
<string name="project_member_id">ID člena projektu: %s</string>
<string name="queue_size">Veľkosť fronty: %d</string>
<string name="terms_of_use">Podmienky používania</string>
<string name="not_logged_in">Neprihlásený</string>
<string name="you_need_to_accept_the_of_use_first">Musíte najskôr akceptovať podmienky používania.</string>
<string name="successfully_logged_in">Prihlásenie úspešné</string>
<string name="setup_will_continue_in_background">Nastavenie bude teraz dokončené na pozadí. Vďaka za odoslanie vašich údajov.\n\nProsím, ponechajte tento modul a Váš telefón na chvíľu zapnutý, kým sa dokončí nastavenie.</string>
<string name="completing_login">Dokončuje sa prihlasovanie…</string>
<string name="donate_your_data_to_science">Darujte svoje údaje vede</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Boli ste odhlásený z Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Kliknite sem, ak sa chcete prihlásiť znova, v prípade, že sa to nestalo omylom.</string>
<string name="only_upload_if_connected_to_wifi">Odoslať iba ak ste pripojený k Wi-Fi</string>
<string name="only_upload_if_charging">Odoslať iba pri nabíjaní</string>
<string name="worker_state">Stav procesu: %s</string>
<string name="uploaded_data">Odoslané údaje</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">Nasledujúce dáta budú nahrané na váš účet Open Humans: hodnoty glykémie, udalosti starostlivosti (okrem poznámok), rozložené bolusy, prepnutia profilu, celkové denné dávky, dočasné bazály, nastavenia, verzie aplikácie, model zariadenia a rozmery obrazovky. Tajné, alebo súkromné informácie, ako je URL, alebo API heslo vašeho Nightscoutu, nahrané nebudú.</string>
</resources>

View file

@ -175,6 +175,9 @@ Eversense-appen.</string>
<string name="preferences_import_canceled">Importen avbröts. Inställningarna har inte importerats!</string>
<string name="preferences_import_impossible">Kan inte importera inställningar!</string>
<string name="goto_main_try_again">Vänligen gå tillbaka till huvudskärmen och försök igen.</string>
<string name="old_master_password">Gamla huvudlösenordet</string>
<string name="different_password_used">Den här filen har exporterats och krypterats med ett annat lösenord. Ange det gamla lösenordet för att dekryptera filen.</string>
<string name="master_password_will_be_replaced">OBS! Som ett resultat av en lyckad import, kommer det nuvarande huvudlösenordet att ersättas av det gamla huvudlösenordet!</string>
<string name="preferences_import_list_title">Välj fil att importera</string>
<string name="check_preferences_before_import">Vänligen kontrollera inställningarna innan du importerar:</string>
<string name="check_preferences_cannot_import">Inställningarna kan inte importeras!</string>
@ -227,7 +230,7 @@ Eversense-appen.</string>
<string name="smscommunicator_allowednumbers_summary">+4670XXXXXXX; +4670YYYYYYY</string>
<string name="smscommunicator_bolusreplywithcode">För att ge bolus %1$.2f enheter, svara med kod %2$s</string>
<string name="smscommunicator_mealbolusreplywithcode">För att ge bolus %1$.2f enheter, svara med kod: %2$s</string>
<string name="smscommunicator_temptargetwithcode">För att sätta ett temporärt mål på %1$s, svara med kod: %2$s</string>
<string name="smscommunicator_temptargetwithcode">För att sätta ett temporärt mål på %1$s svara med kod %2$s</string>
<string name="smscommunicator_temptargetcancel">För att avbryta temporärt mål, svara med kod: %1$s</string>
<string name="smscommunicator_stopsmswithcode">För att inaktivera fjärrkommandon via SMS, svara med kod: %1$s \n\nTänk på att måste ha tillgång till huvudtelefonen för att kunna återaktivera.</string>
<string name="smscommunicator_stoppedsms">Fjärrkommandon via SMS stoppas. För att återaktivera detta, använd Konfigurationsverktyget på huvudtelefonen.</string>
@ -560,6 +563,7 @@ Eversense-appen.</string>
<string name="pump_unreachable">Pumpen kan inte nås</string>
<string name="missed_bg_readings">BG-värden saknas</string>
<string name="raise_notifications_as_android_notifications">Systemaviseringar för larm &amp; info</string>
<string name="gradually_increase_notification_volume">Öka volymen gradvis för larm och aviseringar</string>
<string name="localalertsettings_title">Lokala larm</string>
<string name="enable_missed_bg_readings_alert">Varna om BG-data saknas</string>
<string name="enable_pump_unreachable_alert">Varna om pumpen inte går att nå</string>
@ -1134,10 +1138,8 @@ Eversense-appen.</string>
<string name="loop_tbrexecution_time_label">Basalförändring utförd</string>
<string name="insight_alert_notification_channel">Pumpvarningar Insight</string>
<!-- SMS Communicator & OTP Authenticator -->
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">från autentiseringsapp för: %1$s</string>
<string name="smscommunicator_otp_enabled">Aktivera autentiseraren</string>
<string name="smscommunicator_otp_enabled_summary">Autentisera kommandon med hjälp av engångslösenord som genererats av Google Authenticator eller liknande appar för tvåfaktorsautentisering.</string>
<string name="smscommunicator_otp_pin">Extra PIN-kod</string>
<string name="smscommunicator_otp_pin_summary">Ytterligare siffror som ska memoreras och läggas till i slutet av varje genererat engångslösenord</string>
<string name="smscomunicator_tab_otp_label">Konfiguration av tvåfaktorsautentisering</string>
<string name="smscommunicator_otp_verify_label">Engångslösenord att kontrollera:</string>
@ -1178,4 +1180,34 @@ Eversense-appen.</string>
<string name="formatwithweight">Ålder: %1$.0f Vikt: %2$.0f kg</string>
<string name="basalpctfromtdd_label">% av basal</string>
<string name="dpvdefaultprofile">DPV-standardprofil</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Slutför Open Humans-konfiguration…</string>
<string name="this_may_take_a_while">Det här kan ta ett tag. Avbryt inte den här processen.</string>
<string name="setup_finished">Konfigurationen slutförd</string>
<string name="your_phone_will_upload_data">Din telefon kommer att ladda upp data till Open Humans snart.</string>
<string name="your_phone_is_upload_data">Din telefon laddar upp data till Open Humans nu.</string>
<string name="setup_failed">Konfiguration misslyckades</string>
<string name="there_was_an_error">Ett fel uppstod. Försök att logga in igen för att fortsätta. Tack!</string>
<string name="open_humans_terms">Detta är ett open source-verktyg som kommer att ladda upp dina data till Open Humans. Vi förbehåller oss inga rättigheter att dela dina uppgifter med tredje part utan ditt uttryckliga tillstånd. De data som projektet och appen tar emot identifieras via ett slumpmässigt användar-ID och kommer endast att överföras på ett säkert sätt till ett Open Humans-konto om du tillåter det. Du kan när som helst sluta ladda upp och radera dina uppladdningsdata via www.openhumans.org.</string>
<string name="i_understand_and_agree">Jag förstår och instämmer.</string>
<string name="login">Logga in</string>
<string name="logout">Logga ut</string>
<string name="oh_logout_confirmation">Vill du verkligen logga ut och sluta donera data till vetenskapen?</string>
<string name="project_member_id">Projektmedlems-ID: %s</string>
<string name="queue_size">Köstorlek: %d</string>
<string name="terms_of_use">Användarvillkor</string>
<string name="not_logged_in">Inte inloggad</string>
<string name="you_need_to_accept_the_of_use_first">Du måste acceptera användarvillkoren först.</string>
<string name="successfully_logged_in">Inloggning lyckades</string>
<string name="setup_will_continue_in_background">Konfigurationen kommer att slutföras i bakgrunden nu. Tack för att du laddade upp dina data.\n\nBehåll det här appen och din telefon påslagen en stund till för installationen ska slutföras helt.</string>
<string name="completing_login">Slutför inloggning…</string>
<string name="donate_your_data_to_science">Donera dina data till vetenskapen</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">Du har loggats ut från Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Klicka här om du vill logga in igen om det inte var meningen.</string>
<string name="only_upload_if_connected_to_wifi">Ladda bara upp om ansluten till WiFi</string>
<string name="only_upload_if_charging">Ladda bara upp vid laddning</string>
<string name="worker_state">Jobbstatus: %s</string>
<string name="uploaded_data">Uppladdad data</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">Följande data kommer att överföras till ditt Open Humans-konto: Glukosvärden, careportalhändelser (utom anteckningar), utökade bolusar, profilbyten, totala dagliga doser, temp basaler, temp mål, inställningar, appversion, enhetsmodell och skärmstorlek. Hemlig eller privat information, t. ex. din Nightscout-adress eller API-hemlighet, kommer inte att överföras.</string>
</resources>

View file

@ -208,6 +208,9 @@
<string name="preferences_import_canceled">Import canceled! Preferences were NOT imported!</string>
<string name="preferences_import_impossible">Cannot import preferences!</string>
<string name="goto_main_try_again">Please go back to main screen and try again.</string>
<string name="old_master_password">Old Master Password</string>
<string name="different_password_used">This file was exported and encrypted with different master password. Provide old master password to decrypt file.</string>
<string name="master_password_will_be_replaced">As a result of successful import current master password WILL BE REPLACED with that old master password!</string>
<string name="preferences_import_list_title">Select file to import</string>
@ -1353,15 +1356,18 @@
<string name="key_smscommunicator_otp_password" translatable="false">smscommunicator_otp_password</string>
<string name="key_smscommunicator_otp_secret" translatable="false">smscommunicator_otp_secret</string>
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">from Authenticator app for: %1$s</string>
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">from Authenticator app for: %1$s followed by PIN</string>
<string name="smscommunicator_otp_enabled">Enable Authenticator</string>
<string name="smscommunicator_otp_enabled_summary">Authenticate commands using One Time Passwords generated by Google Authenticator or similar 2FA apps.</string>
<string name="smscommunicator_otp_pin">Additional PIN at token end</string>
<string name="smscommunicator_otp_pin">Additional mandatory PIN at token end</string>
<string name="smscommunicator_otp_pin_summary">Additional digits that should be memorised and glued at end of each generated One Time Password</string>
<string name="smscomunicator_tab_otp_label">Authenticator setup</string>
<string name="smscommunicator_code_verify_label">Code to check:</string>
<string name="smscommunicator_code_verify_hint">OTP + PIN</string>
<string name="smscommunicator_code_verify_info">The verification code consist of 6 digits displayed by Authenticator app (known as OTP) followed by 3 or more digits of mandatory PIN.</string>
<string name="smscommunicator_otp_verify_label">OTP to check:</string>
<string name="smscommunicator_otp_reset_btn">Reset Authenticators</string>
<string name="smscommunicator_otp_reset_title">Reset Authenticator Key</string>
@ -1408,4 +1414,34 @@
<string name="basalpctfromtdd_label">% of basal</string>
<string name="dpvdefaultprofile">DPV Default profile</string>
<string name="open_humans">Open Humans</string>
<string name="finishing_open_humans_setup">Finishing Open Humans setup…</string>
<string name="this_may_take_a_while">This may take a while. Do not turn your phone or this plugin off.</string>
<string name="setup_finished">Setup finished</string>
<string name="your_phone_will_upload_data">Your phone will upload data to Open Humans soon.</string>
<string name="your_phone_is_upload_data">Your phone is uploading data to Open Humans now.</string>
<string name="setup_failed">Setup failed</string>
<string name="there_was_an_error">There was an error. Please try to log in again in order to proceed. Sorry &amp; Thank you!</string>
<string name="open_humans_terms">This is an open source tool that will copy your data to Open Humans. We retain no rights to share your data with third parties without your explicit authorization. The data the project and app receive are identified via a random user ID and will only be securely transmitted to an Open Humans account with your authorization of that process. You can stop uploading and delete your upload data at any time via www.openhumans.org.</string>
<string name="i_understand_and_agree">I understand and agree.</string>
<string name="login">Login</string>
<string name="logout">Logout</string>
<string name="oh_logout_confirmation">Do you really want to log out and stop donating data to science?</string>
<string name="project_member_id">Project Member ID: %s</string>
<string name="queue_size">Queue Size: %d</string>
<string name="terms_of_use">Terms of Use</string>
<string name="not_logged_in">Not logged in</string>
<string name="you_need_to_accept_the_of_use_first">You need to accept the terms of use first.</string>
<string name="successfully_logged_in">Successfully logged in</string>
<string name="setup_will_continue_in_background">The setup will be completed in background now. Thanks for uploading your data.\n\nPlease keep this plugin and your phone turned on for a short while for the setup to complete.</string>
<string name="completing_login">Completing login…</string>
<string name="donate_your_data_to_science">Donate your data to science</string>
<string name="open_humans_short">OH</string>
<string name="you_have_been_signed_out_of_open_humans">You have been signed out of Open Humans</string>
<string name="click_here_to_sign_in_again_if_this_wasnt_on_purpose">Click here to sign in a again if this wasn\'t on purpose.</string>
<string name="only_upload_if_connected_to_wifi">Only upload if connected to WiFi</string>
<string name="only_upload_if_charging">Only upload if charging</string>
<string name="worker_state">Worker State: %s</string>
<string name="uploaded_data">Uploaded Data</string>
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">The following data will be uploaded to your Open Humans account: Glucose values, careportal events (except notes), extended boluses, profile switches, total daily doses, temporary basals, temp targets, preferences, application version, device model and screen dimensions. Secret or private information such as your Nightscout URL or API secret will not be uploaded.</string>
</resources>

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="@string/open_humans">
<CheckBoxPreference
android:defaultValue="true"
android:key="key_oh_wifi_only"
android:title="@string/only_upload_if_connected_to_wifi" />
<CheckBoxPreference
android:defaultValue="false"
android:key="key_oh_charging_only"
android:title="@string/only_upload_if_charging" />
</PreferenceCategory>
</PreferenceScreen>

View file

@ -35,13 +35,6 @@
android:title="@string/smscommunicator_otp_enabled"
app:isPreferenceVisible="false" />
<Preference
android:dependency="@string/key_smscommunicator_remotecommandsallowed"
android:key="otpsetup"
android:title="@string/smscomunicator_tab_otp_label">
<intent android:action="info.nightscout.androidaps.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity" />
</Preference>
<info.nightscout.androidaps.utils.textValidator.ValidatingEditTextPreference
android:dependency="@string/key_smscommunicator_remotecommandsallowed"
android:key="@string/key_smscommunicator_otp_password"
@ -49,6 +42,13 @@
android:title="@string/smscommunicator_otp_pin"
validate:testType="pinStrength" />
<Preference
android:dependency="@string/key_smscommunicator_remotecommandsallowed"
android:key="otpsetup"
android:title="@string/smscomunicator_tab_otp_label">
<intent android:action="info.nightscout.androidaps.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity" />
</Preference>
</PreferenceCategory>
</androidx.preference.PreferenceScreen>

View file

@ -3,7 +3,9 @@ package info.nightscout.androidaps.events
import info.nightscout.androidaps.utils.resources.ResourceHelper
class EventPreferenceChange : Event {
private var changedKey: String? = null
var changedKey: String? = null
private set
constructor(key: String) {
changedKey = key

View file

@ -17,6 +17,7 @@ enum class LTag(val tag: String, val defaultValue : Boolean = true, val requires
LOCATION("LOCATION"),
NOTIFICATION("NOTIFICATION"),
NSCLIENT("NSCLIENT"),
OHUPLOADER("OHUPLOADER"),
PUMP("PUMP"),
PUMPBTCOMM("PUMPBTCOMM", defaultValue = true),
PUMPCOMM("PUMPCOMM"),

View file

@ -6,6 +6,7 @@ import android.os.Build
import android.view.LayoutInflater
import android.view.View
import android.widget.EditText
import android.widget.TextView
import androidx.annotation.StringRes
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.utils.CryptoUtil
@ -24,6 +25,9 @@ class PasswordCheck @Inject constructor(
private val cryptoUtil: CryptoUtil
) {
/**
Asks for "managed" kind of password, checking if it is valid.
*/
@SuppressLint("InflateParams")
fun queryPassword(context: Context, @StringRes labelId: Int, @StringRes preference: Int, ok: ((String) -> Unit)?, cancel: (() -> Unit)? = null, fail: (() -> Unit)? = null) {
val password = sp.getString(preference, "")
@ -115,4 +119,51 @@ class PasswordCheck @Inject constructor(
alertDialogBuilder.create().show()
}
/**
Prompt free-form password, with additional help and warning messages.
Preference ID (preference) is used only to generate ID for password managers,
since this query does NOT check validity of password.
*/
@SuppressLint("InflateParams")
fun queryAnyPassword(context: Context, @StringRes labelId: Int, @StringRes preference: Int, @StringRes passwordExplanation: Int?,
@StringRes passwordWarning: Int?, ok: ((String) -> Unit)?, cancel: (() -> Unit)? = null) {
val promptsView = LayoutInflater.from(context).inflate(R.layout.passwordprompt, null)
val alertDialogBuilder = AlertDialogHelper.Builder(context)
alertDialogBuilder.setView(promptsView)
passwordExplanation?.let { alertDialogBuilder.setMessage(it) }
passwordWarning?.let {
val extraWarning: TextView = promptsView.findViewById<View>(R.id.password_prompt_extra_message) as TextView;
extraWarning.text = context.getString(it);
extraWarning.visibility = View.VISIBLE;
}
val userInput = promptsView.findViewById<View>(R.id.password_prompt_pass) as EditText
val userInput2 = promptsView.findViewById<View>(R.id.password_prompt_pass_confirm) as EditText
userInput2.visibility = View.GONE
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val autoFillHintPasswordKind = context.getString(preference)
userInput.setAutofillHints(View.AUTOFILL_HINT_PASSWORD, "aaps_${autoFillHintPasswordKind}")
userInput.importantForAutofill = View.IMPORTANT_FOR_AUTOFILL_YES
}
alertDialogBuilder
.setCancelable(false)
.setCustomTitle(AlertDialogHelper.buildCustomTitle(context, context.getString(labelId), R.drawable.ic_header_key))
.setPositiveButton(context.getString(R.string.ok)) { _, _ ->
val enteredPassword = userInput.text.toString()
ok?.invoke(enteredPassword)
}
.setNegativeButton(context.getString(R.string.cancel)
) { dialog, _ ->
cancel?.invoke()
dialog.cancel()
}
alertDialogBuilder.create().show()
}
}

View file

@ -5,6 +5,18 @@
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="@+id/password_prompt_extra_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/warningAccentText"
android:visibility="gone"
/>
<EditText
android:id="@+id/password_prompt_pass"
android:layout_width="match_parent"

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Keys-->
<!-- General-->
<!-- Constraints-->
<!-- Dialogs-->

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pairing">Сдвояване</string>
<!-- Keys-->
<!-- General-->
<string name="error">Грешка</string>
<string name="not_set_short">Не е зададен</string>
@ -65,6 +65,7 @@
<string name="bluetooth">Bluetooth</string>
<string name="btwatchdog_title">BT ограничения</string>
<string name="btwatchdog_summary">Изключва Bluetooth на телефона за една секунда, ако няма връзка с помпата. Това може да помогне на някои телефони, където Bluetooth блокира.</string>
<string name="pairing">Сдвояване</string>
<!-- Constraints-->
<string name="limitingbasalratio">Ограничаване на макс. базална стойност до %1$.2f Е/ч поради %2$s</string>
<string name="pumplimit">лимит на помпата</string>
@ -131,6 +132,7 @@
<string name="tddwithcarbsformat"><![CDATA[<b>%1$s:</b> ∑: <b>%2$.2fЕ</b> Бол: <b>%3$.2fЕ</b> Баз: <b>%4$.2fЕ(%5$.0f%%)</b> Въгл: <b>%6$.0fгр</b>]]></string>
<!-- Translator-->
<string name="careportal_bgcheck">Проверка на КЗ</string>
<string name="careportal_mbg">Калибрация или ръчна КЗ</string>
<string name="careportal_announcement">Известие</string>
<string name="careportal_note">Бележка</string>
<string name="careportal_question">Въпрос</string>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pairing">Párování</string>
<!-- Keys-->
<!-- General-->
<string name="error">Chyba</string>
<string name="not_set_short">Nenastaveno</string>
@ -65,6 +65,7 @@
<string name="bluetooth">Bluetooth</string>
<string name="btwatchdog_title">Hlídač BT</string>
<string name="btwatchdog_summary">Vypne na 1 sek bluetooth v telefonu, pokud se nedaří připojit k pumpě. Může to pomoci u telefonů, které mají problémy s BT</string>
<string name="pairing">Párování</string>
<!-- Constraints-->
<string name="limitingbasalratio">Max bazál omezen na %1$.2f U/h: %2$s</string>
<string name="pumplimit">limit pumpy</string>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pairing">Koppeln</string>
<!-- Keys-->
<!-- General-->
<string name="error">Fehler</string>
<string name="not_set_short">Nicht angegeben</string>
@ -65,6 +65,7 @@
<string name="bluetooth">Bluetooth</string>
<string name="btwatchdog_title">BT Watchdog</string>
<string name="btwatchdog_summary">Deaktiviert Bluetooth kurzzeitig, falls keine Verbindung zur Pumpe besteht. Dies kann für Smartphones mit Verbindungsproblemen nützlich sein.</string>
<string name="pairing">Koppeln</string>
<!-- Constraints-->
<string name="limitingbasalratio">Begrenzung der max. Basalrate auf %1$.2f IE/h wegen %2$s</string>
<string name="pumplimit">Limit der Pumpe</string>
@ -131,7 +132,7 @@
<string name="tddwithcarbsformat"><![CDATA[<b>%1$s:</b> ∑: <b>%2$.2f IE</b> Bol: <b>%3$.2f U</b> Bas: <b>%4$.2f IE(%5$.0f%%)</b> KH: <b>%6$.0f g</b>]]></string>
<!-- Translator-->
<string name="careportal_bgcheck">BZ-Test</string>
<string name="careportal_mbg">Manuelle BZ oder Kalibrierung</string>
<string name="careportal_mbg">Manueller BZ oder Kalibrierung</string>
<string name="careportal_announcement">Ankündigung</string>
<string name="careportal_note">Notiz</string>
<string name="careportal_question">Frage</string>
@ -186,6 +187,7 @@
<string name="tbb2">Tägl. Basalmenge * 2</string>
<!-- Ntp-->
<string name="timedetection">Zeiterkennung</string>
<string name="format_hour_minute">%1$dh %2$dm</string>
<!-- PumoCommon - Pump Abstract -->
<string name="pump_operation_not_supported_by_pump_driver">Aktion von Pumpe und/oder Treiber nicht unterstützt.</string>
<string name="pump_operation_not_yet_supported_by_pump">Operation NOCH NICHT von Pumpe unterstützt.</string>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Keys-->
<!-- General-->
<!-- Constraints-->
<!-- Dialogs-->

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pairing">Emparejando</string>
<!-- Keys-->
<!-- General-->
<string name="error">Error</string>
<string name="not_set_short">No configurado</string>
@ -65,6 +65,7 @@
<string name="bluetooth">Bluetooth</string>
<string name="btwatchdog_title">Vigilante de BT</string>
<string name="btwatchdog_summary">Apaga el bluetooth del móvil por un segundo si no hay conexión con la bomba. Esto ayuda con algunos móviles con problemas para establecer conexión bluetooth estable.</string>
<string name="pairing">Emparejando</string>
<!-- Constraints-->
<string name="limitingbasalratio">Limitando max basal rate a %1$.2f U/h debido a %2$s</string>
<string name="pumplimit">límite de la bomba</string>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pairing">Appairage</string>
<!-- Keys-->
<!-- General-->
<string name="error">Erreur</string>
<string name="not_set_short">Non configuré</string>
@ -65,6 +65,7 @@
<string name="bluetooth">Bluetooth</string>
<string name="btwatchdog_title">BT Watchdog</string>
<string name="btwatchdog_summary">Coupe le Bluetooth du téléphone une seconde si la connexion pompe nest pas possible. Cela peut aider pour les téléphones dont la connexion Bluetooth se bloque.</string>
<string name="pairing">Appairage</string>
<!-- Constraints-->
<string name="limitingbasalratio">Limiter le débit de basal max à %1$.2f U/h à cause de %2$s</string>
<string name="pumplimit">Limite de la pompe</string>
@ -186,7 +187,7 @@
<string name="tbb2">DTB*2</string>
<!-- Ntp-->
<string name="timedetection">Détection de temps</string>
<string name="format_hour_minute">%1$dh %2$dm</string>
<string name="format_hour_minute">%1$dh%2$dm</string>
<!-- PumoCommon - Pump Abstract -->
<string name="pump_operation_not_supported_by_pump_driver">Opération non prise en charge par la pompe et/ou le pilote.</string>
<string name="pump_operation_not_yet_supported_by_pump">Opération non ENCORE supportée par la pompe.</string>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Keys-->
<!-- General-->
<!-- Constraints-->
<!-- Dialogs-->

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Keys-->
<!-- General-->
<!-- Constraints-->
<!-- Dialogs-->

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pairing">Associazione</string>
<!-- Keys-->
<!-- General-->
<string name="error">Errore</string>
<string name="not_set_short">Non impostato</string>
@ -65,6 +65,7 @@
<string name="bluetooth">Bluetooth</string>
<string name="btwatchdog_title">BT Watchdog</string>
<string name="btwatchdog_summary">Spegne il bluetooth del telefono per qualche secondo se non è possibile alcuna connessione al micro. Questo può essere utile su alcuni telefoni.</string>
<string name="pairing">Associazione</string>
<!-- Constraints-->
<string name="limitingbasalratio">Limitazione max velocità basale a %1$.2f U/h a causa di: %2$s</string>
<string name="pumplimit">limite micro</string>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Keys-->
<!-- General-->
<!-- Constraints-->
<!-- Dialogs-->

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Keys-->
<!-- General-->
<!-- Constraints-->
<!-- Dialogs-->

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pairing">Sujungiama</string>
<!-- Keys-->
<!-- General-->
<string name="error">Klaida</string>
<string name="not_set_short">Nenustatyta</string>
@ -65,6 +65,7 @@
<string name="bluetooth">Bluetooth</string>
<string name="btwatchdog_title">BT Watchdog</string>
<string name="btwatchdog_summary">Vienai sekundei išjungia telefono bluetooth, jei ryšys su pompa nutrūksta. Gali būti veiksminga kai kuriems telefonų modeliams, turintiems BT problemų.</string>
<string name="pairing">Sujungiama</string>
<!-- Constraints-->
<string name="limitingbasalratio">Ribojamas maksimalus bazės dydis%1$.2f vv/val dėl %2$s</string>
<string name="pumplimit">pompos limitas</string>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pairing">Koppelen</string>
<!-- Keys-->
<!-- General-->
<string name="error">Fout</string>
<string name="not_set_short">Niet ingesteld</string>
@ -58,6 +58,7 @@
<string name="bluetooth">Bluetooth</string>
<string name="btwatchdog_title">BT Watchdog</string>
<string name="btwatchdog_summary">Zet de bluetooth van de telefoon even kort uit en weer aan. Dit kan op sommige gsm\'s een vastgelopen bluetooth service verhelpen.</string>
<string name="pairing">Koppelen</string>
<!-- Constraints-->
<string name="limitingbasalratio">Beperken van basaal tot max %1$.2f E/uur wegens de %2$s</string>
<string name="pumplimit">Pomp limiet</string>

View file

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Keys-->
<!-- General-->
<!-- Constraints-->
<!-- Dialogs-->
<!-- BlePreCheck-->
<!-- DateUtil-->
<!-- Protection-->
<!-- Profile-->
<!-- ProfileFunction-->
<!-- PumpType-->
<!-- APSResult-->
<!-- ProfileSwitch-->
<!-- Temptarget-->
<!-- TDD-->
<!-- Translator-->
<!-- Command-->
<!-- PumpEnactResult-->
<!-- CarbsReq-->
<!-- TDDStatsActivity-->
<!-- Ntp-->
<!-- PumoCommon - Pump Abstract -->
<!-- PumoCommon - Pump Status -->
<!-- PumpCommon - History Group -->
<!-- <string name="medtronic_pump_status_never_contacted">Never contacted</string>-->
<!-- <string name="medtronic_pump_status_waking_up">Waking up</string>-->
<!-- <string name="medtronic_pump_status_error_comm">Error with communication</string>-->
<!-- <string name="medtronic_pump_status_timeout_comm">Timeout on communication</string>-->
<!-- <string name="medtronic_pump_status_pump_unreachable">Pump unreachable</string>-->
<!-- <string name="medtronic_pump_status_invalid_config">Invalid configuration</string>-->
<!-- <string name="medtronic_pump_status_active">Active</string>-->
<!-- <string name="medtronic_pump_status_sleeping">Sleeping</string>-->
<!-- <string name="danar_history_alarm">Alarms</string>-->
<!-- <string name="danar_history_glucose">Glucose</string>-->
<!-- All(R.string.medtronic_history_group_all), //-->
<!-- Bolus(R.string.danar_history_bolus), //-->
<!-- Basal(R.string.medtronic_history_group_basal), //-->
<!-- Prime(R.string.danar_history_prime), //-->
<!-- Configuration(R.string.medtronic_history_group_configuration), //-->
<!-- Alarm(R.string.danar_history_alarm), //-->
<!-- Glucose(R.string.danar_history_glucose), //-->
<!-- Notification(R.string.medtronic_history_group_notification), //-->
<!-- Statistic(R.string.medtronic_history_group_statistic),-->
<!-- Unknown(R.string.medtronic_history_group_unknown), //-->
</resources>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pairing">Parowanie</string>
<!-- Keys-->
<!-- General-->
<string name="error">Błąd</string>
<string name="not_set_short">Nie ustawiono</string>
@ -58,6 +58,7 @@
<string name="bluetooth">Bluetooth</string>
<string name="btwatchdog_title">BT Watchdog</string>
<string name="btwatchdog_summary">Wyłącza bluetooth telefonu na jedną sekundę, jeśli nie jest możliwe połączenie z pompą. Może to pomóc w niektórych telefonach, w których blokuje się bluetooth.</string>
<string name="pairing">Parowanie</string>
<!-- Constraints-->
<string name="limitingbasalratio">Ograniczam maks. dawkę bazową do %1$.2f U/h z uwagi na %2$s</string>
<string name="pumplimit">ograniczenie pompy</string>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pairing">A emparelhar</string>
<!-- Keys-->
<!-- General-->
<string name="error">Erro</string>
<string name="not_set_short">Não definido</string>
@ -57,6 +57,7 @@
<string name="bluetooth">Bluetooth</string>
<string name="btwatchdog_title">Watchdog BT</string>
<string name="btwatchdog_summary">Desliga o bluetooth do telefone durante um segundo se nenhuma conexão com bomba for possível. Este parâmetro pode ser util em alguns telefones, onde a pilha bluetooth congela.</string>
<string name="pairing">A emparelhar</string>
<!-- Constraints-->
<string name="limitingbasalratio">A basal max está limitada a %1$.2f U/h por %2$s</string>
<string name="pumplimit">limite bomba</string>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pairing">A Emparelhar</string>
<!-- Keys-->
<!-- General-->
<string name="error">Erro</string>
<string name="not_set_short">Não definido</string>
@ -65,6 +65,7 @@
<string name="bluetooth">Bluetooth</string>
<string name="btwatchdog_title">Watchdog BT</string>
<string name="btwatchdog_summary">Desliga o bluetooth do telefone durante um segundo se nenhuma ligação com bomba for possível. Este parâmetro pode ser útil em alguns telefones, onde o bluetooth congela.</string>
<string name="pairing">A Emparelhar</string>
<!-- Constraints-->
<string name="limitingbasalratio">A basal máx está limitada a %1$.2f U/h por %2$s</string>
<string name="pumplimit">limite bomba</string>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pairing">Împerechere</string>
<!-- Keys-->
<!-- General-->
<string name="error">Eroare</string>
<string name="not_set_short">Nesetată</string>
@ -8,15 +8,22 @@
<string name="profile_set_ok">Profilul bazalei a fost modificat în pompă</string>
<string name="invalidinput">Date de intrare incorecte</string>
<string name="tempbasaldeliveryerror">Eroare la livrare bazală temporară</string>
<string name="goingtodeliver">Se vor livra %1$.2fU</string>
<string name="waitingforpump">Se așteaptă pompa</string>
<string name="connectingfor">Conectat de %1$d s</string>
<string name="bolusdelivering">Livrare %1$.2f U</string>
<string name="handshaking">Împerechere</string>
<string name="connecting">Se conectează</string>
<string name="connected">Conectat</string>
<string name="disconnected">Deconectat</string>
<string name="disconnecting">Se deconectează</string>
<string name="androidaps_start">AndroidAPS a pornit</string>
<string name="formatinsulinunits1">%1$.1f U</string>
<string name="formatinsulinunits">%1$.2f U</string>
<string name="formatsignedinsulinunits">%1$+.2f U</string>
<string name="format_carbs">%1$d g</string>
<string name="reservoirvalue">%1$.0f / %2$d U</string>
<string name="pump_basebasalrate">%1$.2f U/h</string>
<string name="format_hours">%1$.2f h</string>
<string name="format_mins">%1$d min</string>
<string name="pumpbusy">Pompa face altă acțiune</string>
@ -58,6 +65,7 @@
<string name="bluetooth">Bluetooth</string>
<string name="btwatchdog_title">BT Watchdog</string>
<string name="btwatchdog_summary">Oprește bluetooth-ul telefonului pentru o secundă dacă nu se poate conecta la pompă. Aceasta poate ajuta în cazul telefoanelor cu bluetooth incompatitibil.</string>
<string name="pairing">Împerechere</string>
<!-- Constraints-->
<string name="limitingbasalratio">Se limitează maximul ratei bazale la %1$.2f U/o datorită %2$s</string>
<string name="pumplimit">limită pompă</string>
@ -77,6 +85,8 @@
<string name="location_not_found_title">Localizarea este dezactivată</string>
<string name="location_not_found_message">Pentru a putea căuta dispozitive Bluetooth noi, trebuie să activați localizarea. AAPS nu folosește datele dumneavoastră de localizare și acestea pot fi dezactivate după stabilirea conexiunii cu pompa.</string>
<!-- DateUtil-->
<string name="minago">%1$d min în urmă</string>
<string name="hoursago">%1$.1f ore în urmă</string>
<string name="shorthour">h</string>
<string name="days">zile</string>
<string name="hours">ore</string>
@ -93,6 +103,8 @@
<string name="shortminute">min</string>
<string name="shortday">z</string>
<!-- Protection-->
<string name="wrongpassword">Parola greșită</string>
<string name="passwords_dont_match">Parolele nu corespund</string>
<!-- Profile-->
<string name="basalprofilenotaligned">Valori bazale nesincronizate cu ora: %1$s</string>
<string name="minimalbasalvaluereplaced">Valoarea bazalei a fost înlocuită cu valoarea minimă posibilă: %1$s</string>
@ -115,9 +127,13 @@
<!-- ProfileSwitch-->
<string name="zerovalueinprofile">Profil invalid: %1$s</string>
<!-- Temptarget-->
<string name="mins">%1$d min</string>
<!-- TDD-->
<string name="tddformat"><![CDATA[<b>%1$s:</b> ∑: <b>%2$.2fU</b> Bolus: <b>%3$.2fU</b> Bazală: <b>%4$.2fU(%5$.0f%%)</b>]]></string>
<string name="tddwithcarbsformat"><![CDATA[<b>%1$s:</b> ∑: <b>%2$.2fU</b> Bolus: <b>%3$.2fU</b> Bazală: <b>%4$.2fU(%5$.0f%%)</b> CH: <b>%6$.0f g</b>]]></string>
<!-- Translator-->
<string name="careportal_bgcheck">Verificare glicemie</string>
<string name="careportal_mbg">Test glicemie manual sau Calibrare</string>
<string name="careportal_announcement">Anunț</string>
<string name="careportal_note">Notă</string>
<string name="careportal_question">Întrebare</string>
@ -155,6 +171,7 @@
<string name="waitingforpumpresult">Se așteaptă rezultatul</string>
<string name="smb_shortname">SMB</string>
<!-- CarbsReq-->
<string name="carbsreq">%d g carbohidrați suplimentari necesari în %d minute</string>
<!-- TDDStatsActivity-->
<string name="stats">Statistici</string>
<string name="cumulative_tdd">TDD cumulat</string>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pairing">Сопряжение</string>
<!-- Keys-->
<!-- General-->
<string name="error">Ошибка</string>
<string name="not_set_short">Не выбрано</string>
@ -65,6 +65,7 @@
<string name="bluetooth">Bluetooth</string>
<string name="btwatchdog_title">Дежурный режим Watchdog</string>
<string name="btwatchdog_summary">Выключает bluetooth телефона на одну секунду, если подключение к помпе невозможно. Это помогает на тех телефонах, где зависает модуль bluetooth.</string>
<string name="pairing">Сопряжение</string>
<!-- Constraints-->
<string name="limitingbasalratio">Макс базальный уровень ограничен до %1$.2f ед/ч вследствие %2$s</string>
<string name="pumplimit">лимит помпы</string>
@ -132,7 +133,7 @@
<!-- Translator-->
<string name="careportal_bgcheck">Проверка ГК</string>
<string name="careportal_mbg">Ввести значение ГК или калибровку</string>
<string name="careportal_announcement">Оовещение</string>
<string name="careportal_announcement">Оповещение</string>
<string name="careportal_note">Примечание</string>
<string name="careportal_question">Вопрос</string>
<string name="careportal_exercise">Нгрузка</string>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pairing">Párovanie</string>
<!-- Keys-->
<!-- General-->
<string name="error">Chyba</string>
<string name="not_set_short">Nenastavené</string>
@ -65,6 +65,7 @@
<string name="bluetooth">Bluetooth</string>
<string name="btwatchdog_title">Strážny pes BT</string>
<string name="btwatchdog_summary">Vypne na 1 sekundu Bluetooth v telefóne, pokiaľ se nedarí pripojiť k pumpe. Môže to pomôcť pri telefónoch, ktoré majú problémy s BT.</string>
<string name="pairing">Párovanie</string>
<!-- Constraints-->
<string name="limitingbasalratio">Max bazál obmedzený na %1$.2f JI/h: %2$s</string>
<string name="pumplimit">limit pumpy</string>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Keys-->
<!-- General-->
<!-- Constraints-->
<!-- Dialogs-->

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pairing">Parkoppling</string>
<!-- Keys-->
<!-- General-->
<string name="error">Fel</string>
<string name="not_set_short">Ej vald</string>
@ -18,8 +18,8 @@
<string name="disconnected">Frånkopplad</string>
<string name="disconnecting">Kopplar från</string>
<string name="androidaps_start">AndroidAPS startad</string>
<string name="formatinsulinunits1">%1$.1f U</string>
<string name="formatinsulinunits">%1$.2f U</string>
<string name="formatinsulinunits1">%1$.1fU</string>
<string name="formatinsulinunits">%1$.2fU</string>
<string name="formatsignedinsulinunits">%1$+.2f U</string>
<string name="format_carbs">%1$dg</string>
<string name="reservoirvalue">%1$.0f / %2$d U</string>
@ -65,6 +65,7 @@
<string name="bluetooth">Bluetooth</string>
<string name="btwatchdog_title">Bluetooth-övervakare</string>
<string name="btwatchdog_summary">Startar om bluetooth på telefonen om anslutning till pumpen misslyckas. Detta hjälper på en del telefoner där bluetooth ibland hänger sig.</string>
<string name="pairing">Parkoppling</string>
<!-- Constraints-->
<string name="limitingbasalratio">Max basal: %1$.2f E/h pga %2$s</string>
<string name="pumplimit">pumpbegränsning</string>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Keys-->
<!-- General-->
<!-- Constraints-->
<!-- Dialogs-->

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Keys-->
<!-- General-->
<!-- Constraints-->
<!-- Dialogs-->

View file

@ -21,6 +21,7 @@
<color name="dialog_title_icon_tint">#FFFFFF</color>
<color name="warningAlertBackground">#FFFB8C00</color>
<color name="warningAlertHeaderText">#FF000000</color>
<color name="warningAccentText">#FFFB8C00</color>
<color name="errorAlertBackground">#FFFF5555</color>
<color name="errorAlertHeaderText">#FF000000</color>
<color name="examinedProfile">#FFFF5555</color>

View file

@ -24,7 +24,7 @@
<string name="unsupportedfirmware">Firmware del micro non supportato</string>
<string name="pumperror">Errore micro</string>
<string name="lowbattery">Livello batteria basso</string>
<string name="basalcompare">Erogazione di una velocità basale inferiore rispetto alla preimpostata</string>
<string name="basalcompare">Erogazione inferiore rispetto alla velocità basale preimpostata</string>
<string name="pumpshutdown">Arresto micro</string>
<string name="batterydischarged">Batteria del micro scarica</string>
<string name="occlusion">Occlusione</string>
@ -47,7 +47,7 @@
<string name="pairfirst">Associa il micro con il tuo telefono!</string>
<string name="approachingdailylimit">Si avvicina il limite giornaliero di insulina</string>
<string name="startingbolus">Avvio erogazione bolo</string>
<string name="waitingforestimatedbolusend">Attesa per la fine del bolo. Rimangono %1$d sec.</string>
<string name="waitingforestimatedbolusend">In attesa della fine del bolo. Rimangono %1$d sec.</string>
<string name="stoppingtempbasal">Stop basale temporanea</string>
<string name="settingextendedbolus">Impostazione bolo esteso</string>
<string name="stoppingextendedbolus">Stop bolo esteso</string>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View file

@ -16,7 +16,7 @@
<string name="medtronic_pump_encoding_4b6b_rileylink">Codifica Hardware 4b6b</string>
<string name="medtronic_custom_action_wake_and_tune">Risveglio e Sintonizzazione</string>
<string name="medtronic_custom_action_clear_bolus_block">Cancella blocco bolo</string>
<string name="medtronic_custom_action_reset_rileylink">Reset configurazione RileyLink</string>
<string name="medtronic_custom_action_reset_rileylink">Reset config.ne RileyLink</string>
<string name="medtronic_pump_battery_select">Tipo batteria (Power view)</string>
<string name="medtronic_pump_battery_no">Non selezionato (Simple view)</string>
<string name="medtronic_pump_battery_alkaline">Alcalina (Extended view)</string>

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Medtronic (MDT) - Base -->
<!-- MDT Configuration -->
<!-- MDT Errors -->
<!-- MDT History -->
<!-- <string name="medtronic_history_group_basal">Basals</string>-->
<!-- <string name="medtronic_history_group_configuration">Configurations</string>-->
<!-- <string name="medtronic_history_group_notification">Notifications</string>-->
<!-- <string name="medtronic_history_group_statistic">Statistics</string>-->
<!-- <string name="medtronic_history_group_unknown">Unknowns</string>-->
<!-- <string name="medtronic_history_group_all">All</string>-->
<!-- <string name="medtronic_cmd_profile_not_set">Remote Basal profile setting is not supported. Please modify Basal profile on your pump manually.</string> -->
<!-- medtronic_warning -->
<!-- combo_pump_connected_now -->
<!-- combo_notification_check_time_date -->
</resources>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Omnipod -->
<!-- Omnipod - Base -->
<!-- Omnipod Configuration -->
<!-- Omnipod - Fragment -->
<!-- Omnipod - Dialogs -->
<!-- Omnipod - Error -->
<!-- Omnipod - Pod Mgmt -->
<!-- Omnipod - Base -->
</resources>

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Omnipod -->
<!-- Omnipod - Base -->
<string name="description_pump_omnipod">Интеграция на помпата Omnipod, изисква RileyLink устройство (с фърмуер минимум 2.0 ) .</string>
<!-- Omnipod Configuration -->
<!-- Omnipod - Fragment -->
<string name="omnipod_reservoir_left">%1$.2f Е остават</string>
<string name="omnipod_reservoir_over50">Над 50 Е</string>
<!-- Omnipod - Dialogs -->
<string name="omnipod_frequency">Omnipod (433.91 MHz)</string>
<!-- Omnipod - Error -->
<string name="omnipod_error_illegal_init_action_type">Неправилен PodInitActionType: %1$s</string>
<string name="omnipod_driver_error_unexpected_exception_type">Непредвидена грешка. Моля, докладвайте! (тип: %1$s).</string>
<string name="omnipod_driver_error_communication_failed_unexpected_exception">Комуникацията е неуспешна: възникнала е неочаквана грешка. Моля, докладвайте!</string>
<!-- Omnipod - Pod Mgmt -->
<string name="omnipod_cmd_init_pod">Инициализация на Pod</string>
<string name="omnipod_cmd_deactivate_pod">Деактивирай под</string>
<string name="omnipod_cmd_pod_history_na">Историята на Pod не е достъпна в момента.</string>
<string name="omnipod_init_pod_wizard_step1_title">Напълни Pod</string>
<string name="omnipod_init_pod_wizard_step2_title">Пълнене</string>
<string name="omnipod_init_pod_wizard_step3_title">Прикрепете Pod</string>
<string name="omnipod_init_pod_wizard_step3_desc">\nПодгответе мястото за инфузия. Отстранете капачката на Pod и лепенката и прикрепете капсулата към мястото за инфузия.\n\nАко канюла стърчи, моля натиснете <b>Отказ</b> и изхвърлете вашия Pod.\n\nПрес <b>Следваща</b> да се вмъкне канюлата и да започне базалната доставка.</string>
<string name="omnipod_init_pod_wizard_step4_title">Вмъкване на канюла</string>
<string name="omnipod_init_pod_wizard_step4_action_header">Опитвам се да определя първоначалния базален график и да вмъкна канюлата.\n\nКогато всички елементи са проверени, можете да натиснете <b>Следващ</b>.</string>
<string name="omnipod_init_pod_wizard_pod_info_init_pod_description">\Podе активна.\n\nВашият базален график е програмиран и канюлата вмъкната.\n\nМоля, проверете дали канюлата е поставена правилно или заменете Pod, ако чувствате, че не е.</string>
<string name="omnipod_remove_pod_wizard_step1_title">Деактивирай Pod</string>
<string name="omnipod_remove_pod_wizard_step1_desc">\nНатиснете <b>Следващ</b> , за да деактивирате Pod.\n\n<b>Забележка:</b> Това ще спре всички доставки на инсулин и деактивира Pod.</string>
<string name="omnipod_remove_pod_wizard_step2_title">Деактивиране на Pod</string>
<string name="omnipod_init_pod_wizard_pod_info_remove_pod_description">Pod изключен.\n\nмоля, извадете Pod от тялото си и го хвърли.</string>
<string name="omnipod_init_pod_pair_pod">Сдвояване на под</string>
<string name="omnipod_init_pod_prime_pod">Пълнене на под</string>
<!-- Omnipod - Base -->
<string name="omnipod_alert_finish_setup_reminder_reminder">Край на напомнянето за настройка</string>
<string name="omnipod_alert_shutdown_imminent">Спирането е неизбежно</string>
<string name="omnipod_alert_low_reservoir">Минимален инсулин в резервоара</string>
<string name="omnipod_alert_unknown_alert">Непозната аларма</string>
</resources>

View file

@ -0,0 +1,153 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Omnipod -->
<!-- Omnipod - Base -->
<string name="description_pump_omnipod">Integrace pumpy pro Omnipod, vyžaduje zařízení RileyLink (s firmwarem alespoň 2.0).</string>
<!-- Omnipod Configuration -->
<string name="omnipod_config_bolus_beeps_enabled">Pípnutí při bolusu povoleno</string>
<string name="omnipod_config_basal_beeps_enabled">Pípnutí při bazálu povoleno</string>
<string name="omnipod_config_smb_beeps_enabled">Pípnutí při SMB povoleno</string>
<string name="omnipod_config_tbr_beeps_enabled">Pípnutí při TBR povoleno</string>
<string name="omnipod_config_suspend_delivery_button_enabled">Tlačítko Pozastavit doručení povoleno</string>
<string name="omnipod_config_pulse_log_button_enabled">Tlačítko Pulse Log je zapnuto</string>
<string name="omnipod_config_time_change_enabled">Letní čas / Detekce časového pásma povoleno</string>
<string name="omnipod_config_expiration_reminder_enabled">Připomenutí vypršení platnosti povoleno</string>
<string name="omnipod_config_expiration_reminder_hours_before_shutdown">Hodiny před vypnutím</string>
<string name="omnipod_config_low_reservoir_alert_enabled">Upozornění na nízký stav zásobníku povoleno</string>
<string name="omnipod_config_low_reservoir_alert_units">Počet jednotek</string>
<!-- Omnipod - Fragment -->
<string name="omnipod_moments_ago">před chvílí</string>
<string name="omnipod_pod_mgmt">Správa Podu</string>
<string name="omnipod_pod_status">Stav Podu</string>
<string name="omnipod_total_delivered_label">Celkem dodáno</string>
<string name="omnipod_total_delivered">%1$.2f U</string>
<string name="omnipod_reservoir_left">Zbývá %1$.2f U</string>
<string name="omnipod_reservoir_over50">Více než 50 U</string>
<string name="omnipod_pod_address">Adresa Podu</string>
<string name="omnipod_pod_expiry">Expirace Podu</string>
<string name="omnipod_warning">Varování</string>
<string name="omnipod_pod_status_no_active_pod">Žádný aktivní Pod</string>
<string name="omnipod_pod_status_waiting_for_pair_and_prime">Instalace probíhá (čekání na párování a plnění)</string>
<string name="omnipod_pod_status_waiting_for_cannula_insertion">Instalace probíhá (čeká se na vložení kanyly)</string>
<string name="omnipod_pod_status_running">Běží</string>
<string name="omnipod_pod_status_suspended">Pozastaveno</string>
<string name="omnipod_pod_status_pod_fault">Chyba Podu</string>
<string name="omnipod_pod_status_activation_time_exceeded">Byl překročen čas aktivace</string>
<string name="omnipod_pod_status_inactive">Neaktivní</string>
<string name="omnipod_pod_status_pod_fault_description">Chyba Podu: %1$s %2$s</string>
<string name="omnipod_pod_active_alerts">Výstrahy aktivního Podu</string>
<string name="omnipod_acknowledge_active_alerts_short">Potrvdit upozornění</string>
<!-- Omnipod - Dialogs -->
<string name="omnipod_frequency">Omnipod (433,91 MHz)</string>
<!-- Omnipod - Error -->
<string name="omnipod_error_rileylink_address_invalid">Chybná adresa RileyLinku.</string>
<string name="omnipod_error_operation_not_possible_no_configuration">Operace není možná.\n\nNejdříve je nutné nakonfigurovat Omnipod, než bude možné tuto funkci použít.</string>
<string name="omnipod_error_operation_not_possible_no_profile">Operace není možná.\n\n Je třeba několik minut počkat, dokud se AAPS nepokusí poprvé nastavit profil.</string>
<string name="omnipod_error_illegal_init_action_type">Neplatný atribut PodInitActionType: %1$s</string>
<string name="omnipod_error_pod_not_attached">Žádný aktivní Pod</string>
<string name="omnipod_driver_error_setup_action_verification_failed">Ověření příkazu se nezdařilo</string>
<string name="omnipod_driver_error_unexpected_exception_type">Došlo k neočekávané chybě. Nahlaste ji! (typ: %1$s).</string>
<string name="omnipod_driver_error_invalid_parameters">Komunikace selhala: byly přijaty neplatné vstupní parametry</string>
<string name="omnipod_driver_error_communication_failed_timeout">Komunikace selhala: časový limit vypršel</string>
<string name="omnipod_driver_error_communication_failed_unexpected_exception">Komunikace se nezdařila: došlo k neočekávané chybě. Prosím nahlašte!</string>
<string name="omnipod_driver_error_crc_mismatch">Komunikace selhala: ověření integrity zprávy se nezdařilo</string>
<string name="omnipod_driver_error_invalid_packet_type">Komunikace selhala: byly přijaty neplatné pakety z podu</string>
<string name="omnipod_driver_error_invalid_progress_state">Komunikace selhala: Pod je v chybném stavu</string>
<string name="omnipod_driver_error_invalid_response">Komunikace selhala: byla přijata neplatná odezva z Podu</string>
<string name="omnipod_driver_error_invalid_message_sequence_number">Komunikace selhala: od Podu byla přijata zpráva s neplatným pořadovým číslem</string>
<string name="omnipod_driver_error_invalid_message_address">Komunikace selhala: od Podu byla přijata zpráva s neplatnou adresou</string>
<string name="omnipod_driver_error_message_decoding_failed">Komunikace selhala: nepodařilo se dekódovat zprávu z Podu</string>
<string name="omnipod_driver_error_nonce_resync_failed">Komunikace selhala: synchronizace hodnoty Nonce se nezdařila</string>
<string name="omnipod_driver_error_nonce_out_of_sync">Komunikace selhala: hodnota Nonce nebyla synchronizována</string>
<string name="omnipod_driver_error_not_enough_data">Komunikace selhala: nedostatek dat přijatých z Podu</string>
<string name="omnipod_driver_error_pod_fault">Byla zjištěna chyba Podu (%1$03d %2$s). Deaktivujte Pod a spusťte nový</string>
<string name="omnipod_driver_error_pod_returned_error_response">Komunikace selhala: Pod vrátil chybovou odezvu</string>
<!-- Omnipod - Pod Mgmt -->
<string name="omnipod_pod_mgmt_title">Správa Podu</string>
<string name="omnipod_cmd_init_pod">Inicializovat Pod</string>
<string name="omnipod_cmd_deactivate_pod">Deaktivovat Pod</string>
<string name="omnipod_cmd_discard_pod">Vyřadit Pod</string>
<string name="omnipod_cmd_pod_history">Historie Podu</string>
<string name="omnipod_cmd_set_bolus">Nastavit bolus</string>
<string name="omnipod_cmd_cancel_bolus">Zrušit bolus</string>
<string name="omnipod_cmd_set_tbr">Nastavit dočasný bazál</string>
<string name="omnipod_cmd_cancel_tbr_by_driver">Zrušit dočasný bazál (interně ovladačem)</string>
<string name="omnipod_cmd_cancel_tbr">Zrušit dočasný bazál</string>
<string name="omnipod_cmd_set_basal_schedule">Nastavit plán bazálu</string>
<string name="omnipod_cmd_get_pod_status">Zjistit stav Podu</string>
<string name="omnipod_cmd_get_pod_info">Zjistit informace o Podu</string>
<string name="omnipod_cmd_set_time">Nastavit čas</string>
<string name="omnipod_cmd_configure_alerts">Konfigurovat výstrahy</string>
<string name="omnipod_cmd_acknowledge_alerts">Potvrdit výstrahy</string>
<string name="omnipod_cmd_suspend_delivery">Pozastavit dodávání inzulínu</string>
<string name="omnipod_cmd_resume_delivery">Obnovit dodávání inzulínu</string>
<string name="omnipod_cmd_unknown_entry">Neznámá položka</string>
<string name="omnipod_cmd_bolus_value">%1$.2f U</string>
<string name="omnipod_cmd_bolus_value_with_carbs">%1$.2f U, Sach=%2$.1f g</string>
<string name="omnipod_cmd_tbr_value">Rychlost: %1$.2f U, doba trvání: %2$d min</string>
<string name="omnipod_cmd_discard_pod_desc">Pokud stisknete <b>OK</b>, stav Podu bude vynuceně resetován a již nebudete moci komunikovat s Podem. Udělejte to pouze v případě, že s Podem již nelze komunikovat. Pokud stále můžete komunikovat s Podem, použijte volbu <b>Deaktivovat Pod</b>.\n\nPokud chcete pokračovat, ujistěte se, že Pod je sundaný z těla.</string>
<string name="omnipod_cmd_pod_history_na">Historie Podu není v daném okamžiku k dispozici.</string>
<string name="omnipod_init_pod_wizard_step1_title">Naplňte Pod</string>
<string name="omnipod_init_pod_wizard_step1_desc">\nNaplňte nový Pod dostatkem inzulínu na 3 dny.\n\nSledujte dvě pípnutí z Podu během procesu plnění. Tyto ukazují, že minimální množství 85U bylo naplněno. Ujistěte se, že stříkačka je zcela vyprázdněná a to i po vyslechnutí dvou pípnutí.\n\nPo naplnění Podu, prosím, stiskněte <b>Další</b>.\n\n<b>Poznámka:</b> prozatím nesundavejte kryt jehly.\n<b>Poznámka:</b>prosím umístěte RileyLink ve svislé pozici blízko Podu.</string>
<string name="omnipod_init_pod_wizard_step2_title">Plnění</string>
<string name="omnipod_init_pod_wizard_step3_title">Nasaďte Pod</string>
<string name="omnipod_init_pod_wizard_step3_desc">\nPřipravte infuzní místo. Odstraňte krytku jehly a náplasti a nalepte Pod.\n\nPokud se kanyla odlepí, stiskněte <b>Zrušit</b> a zahoďte Pod.\n\nStiskněte <b>Další</b> pro vložení kanyly a spuštění bazálů.</string>
<string name="omnipod_init_pod_wizard_step4_title">Vkládání kanyly</string>
<string name="omnipod_init_pod_wizard_step4_action_header">Snažím se nastavit počáteční základní bazální plán a vložit kanylu.\n\nPři zaškrtnutí všech položek můžete stisknout tlačítko <b>Další</b>.</string>
<string name="omnipod_init_pod_wizard_pod_info_init_pod_description">\nPod je nyní aktivní.\n\nVáš bazál byl naprogramován a kanyla byla vložena.\n\nOvěřte, prosím, že kanyla byla vložena správně a případně vyměňte Pod.</string>
<string name="omnipod_remove_pod_wizard_step1_title">Deaktivovat Pod</string>
<string name="omnipod_remove_pod_wizard_step1_desc">\nStiskněte <b>Další</b> pro deaktivaci Podu.\n\n<b>Poznámka:</b> Zastavíte veškerý výdej inzulínu a deaktivujete Pod.</string>
<string name="omnipod_remove_pod_wizard_step2_title">Deaktivace Podu</string>
<string name="omnipod_init_pod_wizard_pod_info_remove_pod_description">Pod deaktivován.\n\nOdstraňte Pod z těla a znehodnoťte jej.</string>
<string name="omnipod_init_pod_pair_pod">Párování Podu</string>
<string name="omnipod_init_pod_prime_pod">Plnění Podu</string>
<string name="omnipod_deactivate_pod_deactivate_pod">Deaktivovat Pod</string>
<!-- Omnipod - Base -->
<string name="omnipod_alert_finish_pairing_reminder">Upomínka dokončení párování</string>
<string name="omnipod_alert_finish_setup_reminder_reminder">Upomínka dokončení nastavení</string>
<string name="omnipod_alert_expiration">Životnost Podu brzy skončí</string>
<string name="omnipod_alert_expiration_advisory">Pod brzy vyprší</string>
<string name="omnipod_alert_shutdown_imminent">Blíží se vypnutí</string>
<string name="omnipod_alert_low_reservoir">Nízký stav zásobníku</string>
<string name="omnipod_alert_unknown_alert">Neznámá výstraha</string>
<string name="omnipod_errors">Chyby</string>
<string name="omnipod_cmd_basal_profile_not_set_is_same">Bazální profil je stejný, takže nebude znovu nastaven.</string>
<string name="omnipod_refresh">Obnovit</string>
<string name="omnipod_suspend_delivery_short">Vypnutí</string>
<string name="omnipod_uncertain_failure">Neznámá chyba</string>
<string name="omnipod_cancelled_old_tbr_failed_to_set_new">Byl zrušen starý dočasný bazál, ale nový dočasný bazál se nepodařilo nastavit</string>
<string name="omnipod_cmd_set_fake_suspended_tbr">Nastavit falešný dočasný bazál, protože Pod je pozastaven</string>
<string name="omnipod_cmd_cancel_fake_suspended_tbr">Zrušit falešný dočasný bazál který byl vytvořen, protože Pod byl pozastaven</string>
<string name="omnipod_uncertain">neznámé</string>
<string name="omnipod_expiration_alerts_updated">Nastavení výstrahy bylo v Podu aktualizováno</string>
<string name="omnipod_preference_category_rileylink">RileyLink</string>
<string name="omnipod_preference_category_other">Jiné</string>
<string name="omnipod_preference_category_alerts">Varování</string>
<string name="omnipod_preference_category_confirmation_beeps">Potvrzovací pípnutí</string>
<string name="omnipod_wizard_button_exit">Konec</string>
<string name="omnipod_wizard_button_previous">Předchozí</string>
<string name="omnipod_wizard_button_next">Další</string>
<string name="omnipod_wizard_button_finish">Konec</string>
<string name="omnipod_history_item_description">Popis</string>
<string name="omnipod_history_item_source">Zdroj</string>
<string name="omnipod_history_item_date">Datum</string>
<string name="omnipod_history_type">Typ:</string>
<plurals name="omnipod_minutes">
<item quantity="one">%1$d minuta</item>
<item quantity="few">%1$d minut</item>
<item quantity="many">%1$d minut</item>
<item quantity="other">%1$d minut</item>
</plurals>
<plurals name="omnipod_hours">
<item quantity="one">%1$d hodina</item>
<item quantity="few">%1$d hodin</item>
<item quantity="many">%1$d hodin</item>
<item quantity="other">%1$d hodin</item>
</plurals>
<plurals name="omnipod_days">
<item quantity="one">%1$d den</item>
<item quantity="few">%1$d dnů</item>
<item quantity="many">%1$d dnů</item>
<item quantity="other">%1$d dnů</item>
</plurals>
</resources>

View file

@ -0,0 +1,130 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Omnipod -->
<!-- Omnipod - Base -->
<string name="description_pump_omnipod">Um den Omnipod nutzen zu können, brauchst Du einen RileyLink (mind. Firmware 2.0).</string>
<!-- Omnipod Configuration -->
<string name="omnipod_config_bolus_beeps_enabled">Bolus-Piep aktiviert</string>
<string name="omnipod_config_basal_beeps_enabled">Basal-Piep aktiviert</string>
<string name="omnipod_config_smb_beeps_enabled">SMB-Piep aktiviert</string>
<string name="omnipod_config_tbr_beeps_enabled">TBR-Piep aktiviert</string>
<string name="omnipod_config_suspend_delivery_button_enabled">Button Abgabe aussetzen aktiviert</string>
<string name="omnipod_config_time_change_enabled">Sommerzeit/Zeitzonen-Erkennung aktiviert</string>
<string name="omnipod_config_expiration_reminder_enabled">Ablauferinnerung aktiviert</string>
<string name="omnipod_config_low_reservoir_alert_enabled">Warnung niedriger Reservoirstand aktiviert</string>
<string name="omnipod_config_low_reservoir_alert_units">Anzahl der Einheiten</string>
<!-- Omnipod - Fragment -->
<string name="omnipod_moments_ago">gerade eben</string>
<string name="omnipod_pod_mgmt">Pod mgmt</string>
<string name="omnipod_pod_status">Pod Status</string>
<string name="omnipod_total_delivered_label">Insgesamt abgegeben</string>
<string name="omnipod_total_delivered">%1$.2f IE</string>
<string name="omnipod_reservoir_left">%1$.2f IE übrig</string>
<string name="omnipod_reservoir_over50">über 50 IE</string>
<string name="omnipod_pod_address">Pod Adresse</string>
<string name="omnipod_pod_expiry">Pod läuft ab</string>
<string name="omnipod_warning">Warnung</string>
<string name="omnipod_pod_status_no_active_pod">Kein aktiver Pod</string>
<string name="omnipod_pod_status_waiting_for_pair_and_prime">Einrichtung im Gang (Warten auf Verbindung und Füllen)</string>
<string name="omnipod_pod_status_waiting_for_cannula_insertion">Einrichtung im Gang (Warten auf Setzen der Kanüle)</string>
<string name="omnipod_pod_status_running">In Betrieb</string>
<string name="omnipod_pod_status_suspended">Angehalten</string>
<string name="omnipod_pod_status_pod_fault">Pod-Fehler</string>
<string name="omnipod_pod_status_activation_time_exceeded">Aktivierungszeit überschritten</string>
<string name="omnipod_pod_status_inactive">Inaktiv</string>
<string name="omnipod_pod_status_pod_fault_description">Pod-Fehler: %1$s %2$s</string>
<string name="omnipod_pod_active_alerts">Aktive Pod-Warnungen</string>
<string name="omnipod_acknowledge_active_alerts_short">Alarm bestätigen</string>
<!-- Omnipod - Dialogs -->
<string name="omnipod_frequency">Omnipod (433.91 MHz)</string>
<!-- Omnipod - Error -->
<string name="omnipod_error_rileylink_address_invalid">RileyLink Adresse ungültig.</string>
<string name="omnipod_error_operation_not_possible_no_configuration">Aktion ist nicht möglich.\n\n Du musst zuerst den Omnipod konfigurieren, bevor Du diese Operation verwenden kannst.</string>
<string name="omnipod_error_operation_not_possible_no_profile">Aktion ist nicht möglich.\n\n Du musst ein paar Minuten warten bis AAPS versucht, das Basalprofil zum ersten Mal zu setzen.</string>
<string name="omnipod_error_illegal_init_action_type">Illegal PodInitActionType: %1$s</string>
<string name="omnipod_error_pod_not_attached">Kein aktiver Pod</string>
<string name="omnipod_driver_error_setup_action_verification_failed">Kommandoprüfung fehlgeschlagen</string>
<string name="omnipod_driver_error_unexpected_exception_type">Es ist ein unerwarteter Fehler aufgetreten. Bitte melden! (Typ: %1$s).</string>
<string name="omnipod_driver_error_invalid_parameters">Kommunikation fehlgeschlagen: Ungültige Eingabeparameter empfangen</string>
<string name="omnipod_driver_error_communication_failed_timeout">Keine Verbindung: Zeitüberschreitung</string>
<string name="omnipod_driver_error_communication_failed_unexpected_exception">Keine Verbindung: Es ist ein unerwarteter Fehler aufgetreten. Bitte melden!</string>
<string name="omnipod_driver_error_crc_mismatch">Kommunikation fehlgeschlagen: Die Überprüfung der Nachrichtenintegrität ist fehlgeschlagen</string>
<string name="omnipod_driver_error_invalid_packet_type">Kommunikation fehlgeschlagen: Es wurde ein ungültiges Paket vom Pod empfangen</string>
<string name="omnipod_driver_error_invalid_progress_state">Kommunikation fehlgeschlagen: Der Pod befindet sich in einem falschen Status</string>
<string name="omnipod_driver_error_invalid_response">Kommunikation fehlgeschlagen: Es wurde eine ungültige Antwort vom Pod empfangen</string>
<string name="omnipod_driver_error_invalid_message_sequence_number">Kommunikation fehlgeschlagen: Ungültige Zeichenfolge vom Pod empfangen</string>
<string name="omnipod_driver_error_invalid_message_address">Kommunikation fehlgeschlagen: Ungültige Adresse vom Pod empfangen</string>
<string name="omnipod_driver_error_message_decoding_failed">Kommunikation fehlgeschlagen: Nachricht vom Pod konnte nicht decodiert werden</string>
<string name="omnipod_driver_error_nonce_resync_failed">Kommunikation fehlgeschlagen: Nonce resync fehlgeschlagen</string>
<string name="omnipod_driver_error_nonce_out_of_sync">Kommunikation fehlgeschlagen: Nonce nicht synchronisiert</string>
<string name="omnipod_driver_error_not_enough_data">Kommunikation fehlgeschlagen: Nicht genügend Daten vom Pod empfangen</string>
<string name="omnipod_driver_error_pod_fault">Ein Pod-Fehler (%1$03d %2$s) wurde festgestellt. Bitte deaktiviere den Pod und starte einen neuen</string>
<string name="omnipod_driver_error_pod_returned_error_response">Kommunikation fehlgeschlagen: Fehlerhafte Antwort vom Pod</string>
<!-- Omnipod - Pod Mgmt -->
<string name="omnipod_pod_mgmt_title">Pod Management</string>
<string name="omnipod_cmd_init_pod">Init Pod</string>
<string name="omnipod_cmd_deactivate_pod">Pod deaktivieren</string>
<string name="omnipod_cmd_discard_pod">Pod ablegen</string>
<string name="omnipod_cmd_pod_history">Pod Historie</string>
<string name="omnipod_cmd_set_bolus">Mahlzeiten Bolus abgeben</string>
<string name="omnipod_cmd_cancel_bolus">Bolus abbrechen</string>
<string name="omnipod_cmd_set_tbr">Temp. Basalrate setzen</string>
<string name="omnipod_cmd_cancel_tbr_by_driver">Temporäre Basalrate abbrechen (intern über den Treiber)</string>
<string name="omnipod_cmd_cancel_tbr">Temp. Basalrate abbrechen</string>
<string name="omnipod_cmd_set_basal_schedule">Basalrate festlegen</string>
<string name="omnipod_cmd_get_pod_status">Pod-Status abrufen</string>
<string name="omnipod_cmd_get_pod_info">Pod-Info abrufen</string>
<string name="omnipod_cmd_set_time">Zeit einstellen</string>
<string name="omnipod_cmd_configure_alerts">Warnungen konfigurieren</string>
<string name="omnipod_cmd_acknowledge_alerts">Alarme bestätigen</string>
<string name="omnipod_cmd_suspend_delivery">Abgabe unterbrechen</string>
<string name="omnipod_cmd_resume_delivery">Abgabe fortsetzen</string>
<string name="omnipod_cmd_unknown_entry">Unbekannte Eingabe</string>
<string name="omnipod_cmd_bolus_value">%1$.2f IE</string>
<string name="omnipod_cmd_bolus_value_with_carbs">%1$.2f IE, CH=%2$.1f g</string>
<string name="omnipod_cmd_pod_history_na">Pod Historie derzeit nicht verfügbar.</string>
<string name="omnipod_init_pod_wizard_step1_title">Befülle den Pod</string>
<string name="omnipod_init_pod_wizard_step2_title">Befüllen</string>
<string name="omnipod_init_pod_wizard_step3_title">Befestige den Pod</string>
<string name="omnipod_init_pod_wizard_step3_desc">\nBereite die Infusionsstelle vor. Entferne den Nadelschutz des Pods und die Schutzfolie über dem Kleber. Klebe dann den Pod an die gewünschte Körperstelle.\n\nFalls die Kanüle herausragt, klicke <b>Abbrechen</b> und verwirf den Pod.\n\nKlicke <b>Weiter</b>; um die Kanüle zu setzen und die Insulinabgabe zu beginnen.</string>
<string name="omnipod_init_pod_wizard_step4_title">Kanüle setzen</string>
<string name="omnipod_init_pod_wizard_step4_action_header">Erste Basalrate und Kanüle werden nun gesetzt.\n\nWenn alle Häkchen gesetzt sind, kannst Du <b>Weiter</b> klicken.</string>
<string name="omnipod_init_pod_wizard_pod_info_init_pod_description">\nDer Pod ist jetzt aktiv.\n\nDeine Basalrate ist programmiert und die Kanüle wurde gesetzt.\n\nBitte überprüfe, ob die Kanüle korrekt gesetzt wurde und ersetze den Pod, wenn Du das Gefühl hast, dass dies nicht erfolgreich war.</string>
<string name="omnipod_remove_pod_wizard_step1_title">Pod deaktivieren</string>
<string name="omnipod_remove_pod_wizard_step1_desc">\nDrücke <b>Weiter</b> um den Pod zu deaktivieren.\n\n<b>Hinweis:</b> Dies unterbricht die gesamte Insulinabgabe und deaktiviert den Pod.</string>
<string name="omnipod_remove_pod_wizard_step2_title">Deaktiviere den Pod</string>
<string name="omnipod_init_pod_wizard_pod_info_remove_pod_description">Pod deaktiviert.\n\nBitte entferne den Pod von Deinem Körper und entsorge ihn.</string>
<string name="omnipod_init_pod_pair_pod">Pod verbinden</string>
<string name="omnipod_init_pod_prime_pod">Pod befüllen</string>
<string name="omnipod_deactivate_pod_deactivate_pod">Pod deaktivieren</string>
<!-- Omnipod - Base -->
<string name="omnipod_alert_finish_pairing_reminder">Erinnerung Kopplung beendet</string>
<string name="omnipod_alert_finish_setup_reminder_reminder">Erinnerung Setup beendet</string>
<string name="omnipod_alert_expiration">Pod läuft in Kürze ab</string>
<string name="omnipod_alert_expiration_advisory">Pod läuft in Kürze ab</string>
<string name="omnipod_alert_shutdown_imminent">Herunterfahren steht unmittelbar bevor</string>
<string name="omnipod_alert_low_reservoir">Niedriger Reservoirstand</string>
<string name="omnipod_alert_unknown_alert">Unbekannter Alarm</string>
<string name="omnipod_errors">Fehler</string>
<string name="omnipod_cmd_basal_profile_not_set_is_same">Basalprofil, unverändert wird nicht erneut eingestellt.</string>
<string name="omnipod_refresh">Aktualisieren</string>
<string name="omnipod_suspend_delivery_short">Unterbrechungen</string>
<string name="omnipod_preference_category_rileylink">RileyLink</string>
<string name="omnipod_preference_category_other">Andere</string>
<string name="omnipod_wizard_button_exit">Schließen</string>
<string name="omnipod_wizard_button_next">Weiter</string>
<string name="omnipod_history_item_description">Beschreibung</string>
<string name="omnipod_history_item_date">Datum</string>
<plurals name="omnipod_minutes">
<item quantity="one">%1$d Minute</item>
<item quantity="other">%1$d Minuten</item>
</plurals>
<plurals name="omnipod_hours">
<item quantity="one">%1$d Stunde</item>
<item quantity="other">%1$d Stunden</item>
</plurals>
<plurals name="omnipod_days">
<item quantity="one">%1$d Tag</item>
<item quantity="other">%1$d Tage</item>
</plurals>
</resources>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Omnipod -->
<!-- Omnipod - Base -->
<!-- Omnipod Configuration -->
<!-- Omnipod - Fragment -->
<!-- Omnipod - Dialogs -->
<!-- Omnipod - Error -->
<!-- Omnipod - Pod Mgmt -->
<!-- Omnipod - Base -->
</resources>

View file

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Omnipod -->
<!-- Omnipod - Base -->
<string name="description_pump_omnipod">La integración de la bomba para Omnipod requiere el dispositivo RileyLink (con al menos 2,0 firmware).</string>
<!-- Omnipod Configuration -->
<!-- Omnipod - Fragment -->
<string name="omnipod_reservoir_left">%1$.2f U restantes</string>
<string name="omnipod_reservoir_over50">Más De 50 U</string>
<!-- Omnipod - Dialogs -->
<string name="omnipod_frequency">Omnipod (433.91 MHz)</string>
<!-- Omnipod - Error -->
<string name="omnipod_error_illegal_init_action_type">Ilegal PodInitActionType: %1$s</string>
<string name="omnipod_driver_error_unexpected_exception_type">Error inesperado. Por favor, informe! (tipo: %1$s).</string>
<string name="omnipod_driver_error_communication_failed_unexpected_exception">La comunicación ha fallado: error inesperado. ¡Por favor, Informe!</string>
<!-- Omnipod - Pod Mgmt -->
<string name="omnipod_cmd_init_pod">Iniciar Pod</string>
<string name="omnipod_cmd_deactivate_pod">Desactivar Pod</string>
<string name="omnipod_cmd_pod_history_na">Historial del Pod no disponible en el momento.</string>
<string name="omnipod_init_pod_wizard_step1_title">Llenar el Pod</string>
<string name="omnipod_init_pod_wizard_step2_title">Cebado</string>
<string name="omnipod_init_pod_wizard_step3_title">Adherir el Pod</string>
<string name="omnipod_init_pod_wizard_step3_desc">\nPreparar el sitio de infusión. Retire el capuchón de la aguja del Pod y el adhesivo y aplique el Pod al sitio de perfusión.\n\nSi la cánula se queda fuera, por favor presione <b>Cancel</b> y descarte su Pod.\n\nPress <b>Next</b> para insertar la cánula y comenzar la entrega basal.</string>
<string name="omnipod_init_pod_wizard_step4_title">Insertar cánula</string>
<string name="omnipod_init_pod_wizard_step4_action_header">Intentando establecer la programación basal inicial e insertar la cánula.\n\nCuando todos los elementos están marcados, puede pulsar <b>Siguiente</b>.</string>
<string name="omnipod_init_pod_wizard_pod_info_init_pod_description">\nEl Pod ahora está activo.\n\nSu horario basal ha sido programado y la cánula ha sido insertada.\n\nPor favor, verifique que la cánula ha sido insertada correctamente y reemplace su Pod si usted siente que no lo ha hecho.</string>
<string name="omnipod_remove_pod_wizard_step1_desc">\nPulsa <b>Siguiente</b> para desactivar el Pod.\n\n<b>Nota:</b> Esto suspenderá toda la entrega insulina y desactivará el Pod.</string>
<string name="omnipod_remove_pod_wizard_step2_title">Desactivando el Pod</string>
<string name="omnipod_init_pod_wizard_pod_info_remove_pod_description">Pod desactivado.\n\nPor favor, retire el Pod de su cuerpo y desecharlo.</string>
<string name="omnipod_init_pod_pair_pod">Emparejar Pod</string>
<string name="omnipod_init_pod_prime_pod">Llenado de cánula del Pod</string>
<!-- Omnipod - Base -->
<string name="omnipod_alert_finish_setup_reminder_reminder">Recordatorio de configuración finalizado</string>
<string name="omnipod_alert_shutdown_imminent">El apagado es inminente</string>
<string name="omnipod_alert_low_reservoir">Reservorio bajo</string>
<string name="omnipod_alert_unknown_alert">Alerta desconocida</string>
</resources>

View file

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Omnipod -->
<!-- Omnipod - Base -->
<string name="description_pump_omnipod">L\'intégration de la pompe Omnipod nécessite un boitier RileyLink (avec au minimum un firmware 2.0).</string>
<!-- Omnipod Configuration -->
<!-- Omnipod - Fragment -->
<string name="omnipod_reservoir_left">%1$.2f U restantes</string>
<string name="omnipod_reservoir_over50">Plus de 50 U</string>
<!-- Omnipod - Dialogs -->
<string name="omnipod_frequency">Omnipod (433.91 MHz)</string>
<!-- Omnipod - Error -->
<string name="omnipod_error_illegal_init_action_type">type d\'action d\'init Pod non autorisée : %1$s</string>
<string name="omnipod_driver_error_unexpected_exception_type">Erreur inconnue. Veuillez signaler ! (type : %1$s).</string>
<string name="omnipod_driver_error_communication_failed_unexpected_exception">Échec de communication : Erreur inconnue. Veuillez signaler !</string>
<!-- Omnipod - Pod Mgmt -->
<string name="omnipod_cmd_init_pod">Init Pod</string>
<string name="omnipod_cmd_deactivate_pod">Désactiver Pod</string>
<string name="omnipod_cmd_pod_history_na">Historique Pod non disponible pour le moment.</string>
<string name="omnipod_init_pod_wizard_step1_title">Remplir le Pod</string>
<string name="omnipod_init_pod_wizard_step2_title">Amorçage</string>
<string name="omnipod_init_pod_wizard_step3_title">Collez le Pod</string>
<string name="omnipod_init_pod_wizard_step3_desc">\nPréparez le site d\'injection. Enlevez la protection de l\'aiguille et le support adhésif et collez le Pod sur le site d\'injection.\n\nSi la canule se colle, appuyez sur <b>Annuler</b> et jetez votre Pod.\n\nAppuyez sur <b>Suivant</b> pour insérer la canule et démarrer l\'injection de la basal.</string>
<string name="omnipod_init_pod_wizard_step4_title">Insertion canule</string>
<string name="omnipod_init_pod_wizard_step4_action_header">Tentative de définir le schéma de basal et d\'insertion de la canule.\n\nQuand tous les items sont cochés, appuyez sur <b>Suivant</b>.</string>
<string name="omnipod_init_pod_wizard_pod_info_init_pod_description">\nLe Pod est maintenant actif.\n\nVos débits de basal ont été programmés et la canule a été insérée.\n\nVeuillez verifier que la canule a été insérée correctement et remplacez votre Pod si vous pensez que ce n\'est pas le cas.</string>
<string name="omnipod_remove_pod_wizard_step1_desc">\nAppuyez sur <b>Suivant</b> pour désactiver le Pod.\n\n<b>Remarque :</b> Cela suspendra l\'injection de l\'insuline et désactivera le Pod.</string>
<string name="omnipod_remove_pod_wizard_step2_title">Désactivation du Pod</string>
<string name="omnipod_init_pod_wizard_pod_info_remove_pod_description">Pod désactivé.\n\nVeuillez enlever le Pod de votre corps et le jeter.</string>
<string name="omnipod_init_pod_pair_pod">Appairer le Pod</string>
<string name="omnipod_init_pod_prime_pod">Amorcer le Pod</string>
<!-- Omnipod - Base -->
<string name="omnipod_alert_finish_setup_reminder_reminder">Rappel fin de configuration</string>
<string name="omnipod_alert_shutdown_imminent">Arrêt imminent</string>
<string name="omnipod_alert_low_reservoir">Réservoir bas</string>
<string name="omnipod_alert_unknown_alert">Alerte inconnue</string>
</resources>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Omnipod -->
<!-- Omnipod - Base -->
<!-- Omnipod Configuration -->
<!-- Omnipod - Fragment -->
<!-- Omnipod - Dialogs -->
<!-- Omnipod - Error -->
<!-- Omnipod - Pod Mgmt -->
<!-- Omnipod - Base -->
</resources>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Omnipod -->
<!-- Omnipod - Base -->
<!-- Omnipod Configuration -->
<!-- Omnipod - Fragment -->
<!-- Omnipod - Dialogs -->
<!-- Omnipod - Error -->
<!-- Omnipod - Pod Mgmt -->
<!-- Omnipod - Base -->
</resources>

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