NSClient rafactor

This commit is contained in:
Milos Kozak 2020-01-01 23:23:16 +01:00
parent cc125986ac
commit bcc3829915
66 changed files with 1919 additions and 3046 deletions

View file

@ -78,6 +78,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
@Inject ResourceHelper resourceHelper;
@Inject SmsCommunicatorPlugin smsCommunicatorPlugin;
@Inject LoopPlugin loopPlugin;
@Inject NSSettingsStatus nsSettingsStatus;
@Override
@ -309,7 +310,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
builder.setIcon(MainApp.getIcon());
String message = "Build: " + BuildConfig.BUILDVERSION + "\n";
message += "Flavor: " + BuildConfig.FLAVOR + BuildConfig.BUILD_TYPE + "\n";
message += resourceHelper.gs(R.string.configbuilder_nightscoutversion_label) + " " + NSSettingsStatus.getInstance().nightscoutVersionName;
message += resourceHelper.gs(R.string.configbuilder_nightscoutversion_label) + " " + nsSettingsStatus.getNightscoutVersionName();
if (MainApp.engineeringMode)
message += "\n" + resourceHelper.gs(R.string.engineering_mode_enabled);
message += resourceHelper.gs(R.string.about_link_urls);

View file

@ -93,7 +93,6 @@ import info.nightscout.androidaps.plugins.source.XdripPlugin;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.receivers.DataReceiver;
import info.nightscout.androidaps.receivers.KeepAliveReceiver;
import info.nightscout.androidaps.receivers.NSAlarmReceiver;
import info.nightscout.androidaps.receivers.TimeDateOrTZChangeReceiver;
import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.utils.ActivityMonitor;
@ -118,7 +117,6 @@ public class MainApp extends DaggerApplication {
static ArrayList<PluginBase> pluginsList = null;
static DataReceiver dataReceiver = new DataReceiver();
static NSAlarmReceiver alarmReceiver = new NSAlarmReceiver();
TimeDateOrTZChangeReceiver timeDateOrTZChangeReceiver;
public static boolean devBranch;
@ -152,6 +150,7 @@ public class MainApp extends DaggerApplication {
@Inject DexcomPlugin dexcomPlugin;
@Inject EversensePlugin eversensePlugin;
@Inject GlimpPlugin glimpPlugin;
@Inject MaintenancePlugin maintenancePlugin;
@Inject MM640gPlugin mM640GPlugin;
@Inject NSClientSourcePlugin nSClientSourcePlugin;
@Inject PoctechPlugin poctechPlugin;
@ -266,7 +265,7 @@ public class MainApp extends DaggerApplication {
pluginsList.add(PersistentNotificationPlugin.getPlugin());
pluginsList.add(NSClientPlugin.getPlugin());
// if (engineeringMode) pluginsList.add(tidepoolPlugin);
pluginsList.add(MaintenancePlugin.initPlugin(this));
pluginsList.add(maintenancePlugin);
pluginsList.add(automationPlugin);
pluginsList.add(configBuilderPlugin);
@ -329,22 +328,11 @@ public class MainApp extends DaggerApplication {
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_TREATMENT));
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_CHANGED_TREATMENT));
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_REMOVED_TREATMENT));
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_FOOD));
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_CHANGED_FOOD));
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_REMOVED_FOOD));
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_SGV));
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_PROFILE));
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_STATUS));
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_MBG));
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_DEVICESTATUS));
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_CAL));
//register alarms
lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_ALARM));
lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_ANNOUNCEMENT));
lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_CLEAR_ALARM));
lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_URGENT_ALARM));
this.timeDateOrTZChangeReceiver = new TimeDateOrTZChangeReceiver();
this.timeDateOrTZChangeReceiver.registerBroadcasts(this);

View file

@ -1,30 +1,37 @@
package info.nightscout.androidaps.db;
import androidx.annotation.NonNull;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import javax.inject.Inject;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSgv;
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin;
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface;
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.DefaultValueHelper;
import info.nightscout.androidaps.utils.T;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
@DatabaseTable(tableName = DatabaseHelper.DATABASE_BGREADINGS)
public class BgReading implements DataPointWithLabelInterface {
private static Logger log = LoggerFactory.getLogger(L.GLUCOSE);
@Inject AAPSLogger aapsLogger; // TODO isn't it slow use dependency injection in such heave used object?
@Inject DefaultValueHelper defaultValueHelper;
@Inject ProfileFunction profileFunction;
@Inject ResourceHelper resourceHelper;
@DatabaseField(id = true)
public long date;
@ -51,6 +58,7 @@ public class BgReading implements DataPointWithLabelInterface {
public boolean isZTPrediction = false; // true when drawing predictions as bg points (ZT)
public BgReading() {
MainApp.instance().androidInjector().inject(this); // TODO it will be removed by new database
}
public BgReading(NSSgv sgv) {
@ -108,11 +116,11 @@ public class BgReading implements DataPointWithLabelInterface {
}
@Override
@NonNull @Override
public String toString() {
return "BgReading{" +
"date=" + date +
", date=" + new Date(date).toLocaleString() +
", date=" + DateUtil.dateAndTimeString(date) +
", value=" + value +
", direction=" + direction +
", raw=" + raw +
@ -121,8 +129,7 @@ public class BgReading implements DataPointWithLabelInterface {
public boolean isDataChanging(BgReading other) {
if (date != other.date) {
if (L.isEnabled(L.GLUCOSE))
log.error("Comparing different");
aapsLogger.debug(LTag.GLUCOSE, "Comparing different");
return false;
}
if (value != other.value)
@ -132,8 +139,7 @@ public class BgReading implements DataPointWithLabelInterface {
public boolean isEqual(BgReading other) {
if (date != other.date) {
if (L.isEnabled(L.GLUCOSE))
log.error("Comparing different");
aapsLogger.debug(LTag.GLUCOSE, "Comparing different");
return false;
}
if (value != other.value)
@ -149,8 +155,7 @@ public class BgReading implements DataPointWithLabelInterface {
public void copyFrom(BgReading other) {
if (date != other.date) {
if (L.isEnabled(L.GLUCOSE))
log.error("Copying different");
aapsLogger.error(LTag.GLUCOSE, "Copying different");
return;
}
value = other.value;
@ -182,7 +187,7 @@ public class BgReading implements DataPointWithLabelInterface {
@Override
public double getY() {
return valueToUnits(ProfileFunctions.getSystemUnits());
return valueToUnits(profileFunction.getUnits());
}
@Override
@ -215,30 +220,30 @@ public class BgReading implements DataPointWithLabelInterface {
@Override
public int getColor() {
String units = ProfileFunctions.getSystemUnits();
Double lowLine = OverviewPlugin.INSTANCE.determineLowLine();
Double highLine = OverviewPlugin.INSTANCE.determineHighLine();
int color = MainApp.gc(R.color.inrange);
String units = profileFunction.getUnits();
Double lowLine = defaultValueHelper.determineLowLine();
Double highLine = defaultValueHelper.determineHighLine();
int color = resourceHelper.gc(R.color.inrange);
if (isPrediction())
return getPredectionColor();
else if (valueToUnits(units) < lowLine)
color = MainApp.gc(R.color.low);
color = resourceHelper.gc(R.color.low);
else if (valueToUnits(units) > highLine)
color = MainApp.gc(R.color.high);
color = resourceHelper.gc(R.color.high);
return color;
}
public int getPredectionColor() {
if (isIOBPrediction)
return MainApp.gc(R.color.iob);
return resourceHelper.gc(R.color.iob);
if (isCOBPrediction)
return MainApp.gc(R.color.cob);
return resourceHelper.gc(R.color.cob);
if (isaCOBPrediction)
return 0x80FFFFFF & MainApp.gc(R.color.cob);
return 0x80FFFFFF & resourceHelper.gc(R.color.cob);
if (isUAMPrediction)
return MainApp.gc(R.color.uam);
return resourceHelper.gc(R.color.uam);
if (isZTPrediction)
return MainApp.gc(R.color.zt);
return resourceHelper.gc(R.color.zt);
return R.color.mdtp_white;
}
@ -270,8 +275,7 @@ public class BgReading implements DataPointWithLabelInterface {
else
slope = (previous.value - current.value) / (previous.date - current.date);
if (L.isEnabled(L.GLUCOSE))
log.debug("Slope is :" + slope + " delta " + (previous.value - current.value) + " date difference " + (current.date - previous.date));
aapsLogger.error(LTag.GLUCOSE, "Slope is :" + slope + " delta " + (previous.value - current.value) + " date difference " + (current.date - previous.date));
double slope_by_minute = slope * 60000;
String arrow = "NONE";
@ -291,8 +295,7 @@ public class BgReading implements DataPointWithLabelInterface {
} else if (slope_by_minute <= (40)) {
arrow = "DoubleUp";
}
if (L.isEnabled(L.GLUCOSE))
log.debug("Direction set to: " + arrow);
aapsLogger.error(LTag.GLUCOSE, "Direction set to: " + arrow);
return arrow;
}
}

View file

@ -5,9 +5,12 @@ import dagger.Component
import dagger.android.AndroidInjectionModule
import dagger.android.AndroidInjector
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.db.BgReading
import info.nightscout.androidaps.plugins.aps.openAPSMA.LoggerCallback
import info.nightscout.androidaps.plugins.constraints.objectives.objectives.*
import info.nightscout.androidaps.plugins.general.automation.actions.ActionSendSMS
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction
import info.nightscout.androidaps.plugins.treatments.Treatment
import info.nightscout.androidaps.queue.commands.CommandSetProfile
import info.nightscout.androidaps.utils.wizard.BolusWizard
import info.nightscout.androidaps.utils.wizard.QuickWizardEntry
@ -37,6 +40,11 @@ interface AppComponent : AndroidInjector<MainApp> {
fun injectObjective5(objective5: Objective5)
fun injectObjective6(objective6: Objective6)
fun injectTreatment(treatment: Treatment)
fun injectBgReading(bgReading: BgReading)
fun injectNotification(notificationWithAction: NotificationWithAction)
fun injectLoggerCallback(loggerCallback: LoggerCallback)
fun injectBolusWizard(bolusWizard: BolusWizard)
fun injectQuickWizardEntry(quickWizardEntry: QuickWizardEntry)

View file

@ -8,6 +8,7 @@ import dagger.Provides
import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.BuildConfig
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.db.BgReading
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.AAPSLoggerDebug
import info.nightscout.androidaps.logging.AAPSLoggerProduction
@ -17,6 +18,8 @@ import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctionImplementation
import info.nightscout.androidaps.plugins.constraints.objectives.objectives.*
import info.nightscout.androidaps.plugins.general.automation.actions.ActionSendSMS
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction
import info.nightscout.androidaps.plugins.treatments.Treatment
import info.nightscout.androidaps.queue.commands.CommandSetProfile
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.resources.ResourceHelperImplementation
@ -68,6 +71,12 @@ open class AppModule {
@ContributesAndroidInjector fun objective3Injector(): Objective3
@ContributesAndroidInjector fun objective5Injector(): Objective5
@ContributesAndroidInjector fun objective6Injector(): Objective6
@ContributesAndroidInjector fun bgReadingInjector(): BgReading
@ContributesAndroidInjector fun treatmentInjector(): Treatment
@ContributesAndroidInjector fun notificationWithActionInjector(): NotificationWithAction
@ContributesAndroidInjector fun loggerCallbackInjector(): LoggerCallback
@ContributesAndroidInjector fun loggerBolusWizard(): BolusWizard
@ContributesAndroidInjector fun loggerQuickWizardEntry(): QuickWizardEntry

View file

@ -31,6 +31,9 @@ import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpFragment
import info.nightscout.androidaps.plugins.source.BGSourceFragment
import info.nightscout.androidaps.plugins.treatments.TreatmentsFragment
import info.nightscout.androidaps.dialogs.WizardInfoDialog
import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment
import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog
import info.nightscout.androidaps.plugins.general.maintenance.MaintenanceFragment
import info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsBolusFragment
import info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsCareportalFragment
import info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsProfileSwitchFragment
@ -44,6 +47,7 @@ abstract class FragmentsModule {
@ContributesAndroidInjector abstract fun contributesActionsFragment(): ActionsFragment
@ContributesAndroidInjector abstract fun contributesAutomationFragment(): AutomationFragment
@ContributesAndroidInjector abstract fun contributesBGSourceFragment(): BGSourceFragment
@ContributesAndroidInjector abstract fun contributesCareportalFragment(): CareportalFragment
@ContributesAndroidInjector abstract fun contributesConfigBuilderFragment(): ConfigBuilderFragment
@ContributesAndroidInjector abstract fun contributesDanaRFragment(): DanaRFragment
@ContributesAndroidInjector abstract fun contributesLocalProfileFragment(): LocalProfileFragment
@ -53,6 +57,7 @@ abstract class FragmentsModule {
@ContributesAndroidInjector abstract fun contributesOpenAPSSMBFragment(): OpenAPSSMBFragment
@ContributesAndroidInjector abstract fun contributesOverviewFragment(): OverviewFragment
@ContributesAndroidInjector abstract fun contributesLoopFragment(): LoopFragment
@ContributesAndroidInjector abstract fun contributesMaintenanceFragment(): MaintenanceFragment
@ContributesAndroidInjector abstract fun contributesMedtronicFragment(): MedtronicFragment
@ContributesAndroidInjector abstract fun contributesNSProfileFragment(): NSProfileFragment
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorFragment(): SmsCommunicatorFragment
@ -77,6 +82,7 @@ abstract class FragmentsModule {
@ContributesAndroidInjector abstract fun contributesChooseActionDialog(): ChooseActionDialog
@ContributesAndroidInjector abstract fun contributesChooseTriggerDialog(): ChooseTriggerDialog
@ContributesAndroidInjector abstract fun contributesInsulinDialog(): InsulinDialog
@ContributesAndroidInjector abstract fun contributesNewNSTreatmentDialog(): NewNSTreatmentDialog
@ContributesAndroidInjector abstract fun contributesNtpProgressDialog(): NtpProgressDialog
@ContributesAndroidInjector abstract fun contributesObjectivesExamDialog(): ObjectivesExamDialog
@ContributesAndroidInjector abstract fun contributesProfileSwitchDialog(): ProfileSwitchDialog

View file

@ -2,6 +2,7 @@ package info.nightscout.androidaps.dependencyInjection
import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.plugins.general.nsclient.services.NSClientService
import info.nightscout.androidaps.services.DataService
@Module
@ -9,4 +10,5 @@ import info.nightscout.androidaps.services.DataService
abstract class ServicesModule {
@ContributesAndroidInjector abstract fun contributesDataService(): DataService
@ContributesAndroidInjector abstract fun contributesNSClientService(): NSClientService
}

View file

@ -35,6 +35,7 @@ class CarbsDialog : DialogFragmentWithDate() {
@Inject lateinit var mainApp: MainApp
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var constraintChecker: ConstraintChecker
@Inject lateinit var defaultValueHelper: DefaultValueHelper
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
@Inject lateinit var profileFunction: ProfileFunction
@ -143,12 +144,12 @@ class CarbsDialog : DialogFragmentWithDate() {
val carbs = overview_carbs_carbs.value.toInt()
val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(Constraint(carbs)).value()
val units = profileFunction.getUnits()
val activityTTDuration = DefaultValueHelper.determineActivityTTDuration()
val activityTT = DefaultValueHelper.determineActivityTT()
val eatingSoonTTDuration = DefaultValueHelper.determineEatingSoonTTDuration()
val eatingSoonTT = DefaultValueHelper.determineEatingSoonTT()
val hypoTTDuration = DefaultValueHelper.determineHypoTTDuration()
val hypoTT = DefaultValueHelper.determineHypoTT()
val activityTTDuration = defaultValueHelper.determineActivityTTDuration()
val activityTT = defaultValueHelper.determineActivityTT()
val eatingSoonTTDuration = defaultValueHelper.determineEatingSoonTTDuration()
val eatingSoonTT = defaultValueHelper.determineEatingSoonTT()
val hypoTTDuration = defaultValueHelper.determineHypoTTDuration()
val hypoTT = defaultValueHelper.determineHypoTT()
val actions: LinkedList<String?> = LinkedList()
val unitLabel = if (units == Constants.MMOL) resourceHelper.gs(R.string.mmol) else resourceHelper.gs(R.string.mgdl)

View file

@ -39,6 +39,7 @@ class InsulinDialog : DialogFragmentWithDate() {
@Inject lateinit var constraintChecker: ConstraintChecker
@Inject lateinit var mainApp: MainApp
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var defaultValueHelper: DefaultValueHelper
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
@ -135,8 +136,8 @@ class InsulinDialog : DialogFragmentWithDate() {
if (abs(insulinAfterConstraints - insulin) > pumpDescription.pumpType.determineCorrectBolusStepSize(insulinAfterConstraints))
actions.add(resourceHelper.gs(R.string.bolusconstraintappliedwarning, resourceHelper.gc(R.color.warning), insulin, insulinAfterConstraints))
}
val eatingSoonTTDuration = DefaultValueHelper.determineEatingSoonTTDuration()
val eatingSoonTT = DefaultValueHelper.determineEatingSoonTT()
val eatingSoonTTDuration = defaultValueHelper.determineEatingSoonTTDuration()
val eatingSoonTT = defaultValueHelper.determineEatingSoonTT()
if (eatingSoonChecked)
actions.add(resourceHelper.gs(R.string.temptargetshort) + ": " + "<font color='" + resourceHelper.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to1Decimal(eatingSoonTT) + " " + unitLabel + " (" + eatingSoonTTDuration + " " + resourceHelper.gs(R.string.unit_minute_short) + ")</font>")

View file

@ -31,6 +31,7 @@ class TempTargetDialog : DialogFragmentWithDate() {
@Inject lateinit var constraintChecker: ConstraintChecker
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var defaultValueHelper: DefaultValueHelper
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
override fun onSaveInstanceState(savedInstanceState: Bundle) {
@ -81,18 +82,18 @@ class TempTargetDialog : DialogFragmentWithDate() {
val defaultTarget: Double
when (reasonList[position]) {
resourceHelper.gs(R.string.eatingsoon) -> {
defaultDuration = DefaultValueHelper.determineEatingSoonTTDuration().toDouble()
defaultTarget = DefaultValueHelper.determineEatingSoonTT()
defaultDuration = defaultValueHelper.determineEatingSoonTTDuration().toDouble()
defaultTarget = defaultValueHelper.determineEatingSoonTT()
}
resourceHelper.gs(R.string.activity) -> {
defaultDuration = DefaultValueHelper.determineActivityTTDuration().toDouble()
defaultTarget = DefaultValueHelper.determineActivityTT()
defaultDuration = defaultValueHelper.determineActivityTTDuration().toDouble()
defaultTarget = defaultValueHelper.determineActivityTT()
}
resourceHelper.gs(R.string.hypo) -> {
defaultDuration = DefaultValueHelper.determineHypoTTDuration().toDouble()
defaultTarget = DefaultValueHelper.determineHypoTT()
defaultDuration = defaultValueHelper.determineHypoTTDuration().toDouble()
defaultTarget = defaultValueHelper.determineHypoTT()
}
resourceHelper.gs(R.string.cancel) -> {

View file

@ -1,6 +1,6 @@
package info.nightscout.androidaps.events
import android.os.Bundle
import org.json.JSONArray
/**
* Event which is published with data fetched from NightScout specific for the
@ -10,7 +10,8 @@ import android.os.Bundle
* subscriber.
*/
class EventNsFood(val mode: Int, val payload: Bundle) : Event() {
class EventNsFood(val mode: Int, val foods: JSONArray) : Event() {
companion object {
val ADD = 0
val UPDATE = 1

View file

@ -35,11 +35,11 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction;
import info.nightscout.androidaps.plugins.general.overview.OverviewFragment;
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin;
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.DefaultValueHelper;
import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.T;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
@ -53,6 +53,7 @@ public class HistoryBrowseActivity extends NoSplashAppCompatActivity {
@Inject SP sp;
@Inject ResourceHelper resourceHelper;
@Inject ProfileFunction profileFunction;
@Inject DefaultValueHelper defaultValueHelper;
@Inject IobCobStaticCalculatorPlugin iobCobStaticCalculatorPlugin;
@Inject ConfigBuilderPlugin configBuilderPlugin;
@ -235,8 +236,8 @@ public class HistoryBrowseActivity extends NoSplashAppCompatActivity {
noProfile.setVisibility(View.GONE);
}
final double lowLine = OverviewPlugin.INSTANCE.determineLowLine();
final double highLine = OverviewPlugin.INSTANCE.determineHighLine();
final double lowLine = defaultValueHelper.determineLowLine();
final double highLine = defaultValueHelper.determineHighLine();
buttonDate.setText(DateUtil.dateAndTimeString(start));
buttonZoom.setText(String.valueOf(rangeToDisplay));

View file

@ -10,8 +10,8 @@ import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.utils.SP
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import javax.inject.Singleton
@ -20,6 +20,7 @@ import kotlin.math.roundToInt
@Singleton
class VersionCheckerPlugin @Inject constructor(
private val rxBus: RxBusWrapper,
private val sp: SP,
private val resourceHelper: ResourceHelper
) : PluginBase(PluginDescription()
.mainType(PluginType.CONSTRAINTS)
@ -52,19 +53,19 @@ class VersionCheckerPlugin @Inject constructor(
private fun checkWarning() {
val now = System.currentTimeMillis()
if (!SP.contains(R.string.key_last_versionchecker_plugin_warning)) {
SP.putLong(R.string.key_last_versionchecker_plugin_warning, now)
if (!sp.contains(R.string.key_last_versionchecker_plugin_warning)) {
sp.putLong(R.string.key_last_versionchecker_plugin_warning, now)
return
}
if (isOldVersion(gracePeriod.warning.daysToMillis()) && shouldWarnAgain(now)) {
// store last notification time
SP.putLong(R.string.key_last_versionchecker_plugin_warning, now)
sp.putLong(R.string.key_last_versionchecker_plugin_warning, now)
//notify
val message = resourceHelper.gs(R.string.new_version_warning,
((now - SP.getLong(R.string.key_last_time_this_version_detected, now)) / 1L.daysToMillis().toDouble()).roundToInt(),
((now - sp.getLong(R.string.key_last_time_this_version_detected, now)) / 1L.daysToMillis().toDouble()).roundToInt(),
gracePeriod.old,
gracePeriod.veryOld
)
@ -74,7 +75,7 @@ class VersionCheckerPlugin @Inject constructor(
}
private fun shouldWarnAgain(now: Long) =
now > SP.getLong(R.string.key_last_versionchecker_plugin_warning, 0) + WARN_EVERY
now > sp.getLong(R.string.key_last_versionchecker_plugin_warning, 0) + WARN_EVERY
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> =
if (isOldVersion(gracePeriod.old.daysToMillis()))
@ -84,7 +85,7 @@ class VersionCheckerPlugin @Inject constructor(
private fun isOldVersion(gracePeriod: Long): Boolean {
val now = System.currentTimeMillis()
return now > SP.getLong(R.string.key_last_time_this_version_detected, 0) + gracePeriod
return now > sp.getLong(R.string.key_last_time_this_version_detected, 0) + gracePeriod
}
}

View file

@ -12,22 +12,22 @@ import info.nightscout.androidaps.Config
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.historyBrowser.HistoryBrowseActivity
import info.nightscout.androidaps.activities.TDDStatsActivity
import info.nightscout.androidaps.dialogs.*
import info.nightscout.androidaps.events.*
import info.nightscout.androidaps.historyBrowser.HistoryBrowseActivity
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction
import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment
import info.nightscout.androidaps.plugins.general.overview.StatusLightHandler
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.SP
import info.nightscout.androidaps.utils.SingleClickButton
import info.nightscout.androidaps.utils.extensions.plusAssign
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import info.nightscout.androidaps.utils.toVisibility
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
@ -37,11 +37,14 @@ import java.util.*
import javax.inject.Inject
class ActionsFragment : DaggerFragment() {
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var sp: SP
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var mainApp: MainApp
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var statusLightHandler: StatusLightHandler
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
private var disposable: CompositeDisposable = CompositeDisposable()
@ -113,7 +116,7 @@ class ActionsFragment : DaggerFragment() {
fragmentManager?.let { CareDialog().setOptions(CareDialog.EventType.BATTERY_CHANGE, R.string.careportal_pumpbatterychange).show(it, "Actions") }
}
SP.putBoolean(R.string.key_objectiveuseactions, true)
sp.putBoolean(R.string.key_objectiveuseactions, true)
}
@Synchronized
@ -158,7 +161,7 @@ class ActionsFragment : DaggerFragment() {
if (configBuilderPlugin.activeProfileInterface.profile != null) View.VISIBLE
else View.GONE
if (ProfileFunctions.getInstance().getProfile() == null) {
if (profileFunction.getProfile() == null) {
actions_temptarget?.visibility = View.GONE
actions_extendedbolus?.visibility = View.GONE
actions_extendedbolus_cancel?.visibility = View.GONE
@ -211,9 +214,7 @@ class ActionsFragment : DaggerFragment() {
actions_temptarget?.visibility = Config.APS.toVisibility()
actions_tddstats?.visibility = pump.pumpDescription.supportsTDDs.toVisibility()
activity?.let { activity ->
CareportalFragment.updateAge(activity, careportal_sensorage, careportal_insulinage, careportal_canulaage, careportal_pbage)
}
statusLightHandler.updateAge(careportal_sensorage, careportal_insulinage, careportal_canulaage, careportal_pbage)
checkPumpCustomActions()
}

View file

@ -1,275 +0,0 @@
package info.nightscout.androidaps.plugins.general.careportal;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.events.EventCareportalEventChange;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus;
import info.nightscout.androidaps.plugins.general.overview.OverviewFragment;
import info.nightscout.androidaps.utils.FabricPrivacy;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
public class CareportalFragment extends Fragment implements View.OnClickListener {
private static Logger log = LoggerFactory.getLogger(CareportalFragment.class);
private CompositeDisposable disposable = new CompositeDisposable();
TextView iage;
TextView cage;
TextView sage;
TextView pbage;
View statsLayout;
LinearLayout butonsLayout;
View noProfileView;
// date,bg,insulin,carbs,prebolus,duration,percent,absolute,profile,split,temptarget
public static final OptionsToShow BGCHECK = new OptionsToShow(R.id.careportal_bgcheck, R.string.careportal_bgcheck).date().bg();
public static final OptionsToShow SNACKBOLUS = new OptionsToShow(R.id.careportal_snackbolus, R.string.careportal_snackbolus).date().bg().insulin().carbs().prebolus();
public static final OptionsToShow MEALBOLUS = new OptionsToShow(R.id.careportal_mealbolus, R.string.careportal_mealbolus).date().bg().insulin().carbs().prebolus();
public static final OptionsToShow CORRECTIONBOLUS = new OptionsToShow(R.id.careportal_correctionbolus, R.string.careportal_correctionbolus).date().bg().insulin().carbs().prebolus();
public static final OptionsToShow CARBCORRECTION = new OptionsToShow(R.id.careportal_carbscorrection, R.string.careportal_carbscorrection).date().bg().carbs();
public static final OptionsToShow COMBOBOLUS = new OptionsToShow(R.id.careportal_combobolus, R.string.careportal_combobolus).date().bg().insulin().carbs().prebolus().duration().split();
public static final OptionsToShow ANNOUNCEMENT = new OptionsToShow(R.id.careportal_announcement, R.string.careportal_announcement).date().bg();
public static final OptionsToShow NOTE = new OptionsToShow(R.id.careportal_note, R.string.careportal_note).date().bg().duration();
public static final OptionsToShow QUESTION = new OptionsToShow(R.id.careportal_question, R.string.careportal_question).date().bg();
public static final OptionsToShow EXERCISE = new OptionsToShow(R.id.careportal_exercise, R.string.careportal_exercise).date().duration();
public static final OptionsToShow SITECHANGE = new OptionsToShow(R.id.careportal_pumpsitechange, R.string.careportal_pumpsitechange).date().bg();
public static final OptionsToShow SENSORSTART = new OptionsToShow(R.id.careportal_cgmsensorstart, R.string.careportal_cgmsensorstart).date().bg();
public static final OptionsToShow SENSORCHANGE = new OptionsToShow(R.id.careportal_cgmsensorinsert, R.string.careportal_cgmsensorinsert).date().bg();
public static final OptionsToShow INSULINCHANGE = new OptionsToShow(R.id.careportal_insulincartridgechange, R.string.careportal_insulincartridgechange).date().bg();
public static final OptionsToShow PUMPBATTERYCHANGE = new OptionsToShow(R.id.careportal_pumpbatterychange, R.string.careportal_pumpbatterychange).date().bg();
public static final OptionsToShow TEMPBASALSTART = new OptionsToShow(R.id.careportal_tempbasalstart, R.string.careportal_tempbasalstart).date().bg().duration().percent().absolute();
public static final OptionsToShow TEMPBASALEND = new OptionsToShow(R.id.careportal_tempbasalend, R.string.careportal_tempbasalend).date().bg();
public static final OptionsToShow PROFILESWITCH = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch).date().duration().profile();
public static final OptionsToShow OPENAPSOFFLINE = new OptionsToShow(R.id.careportal_openapsoffline, R.string.careportal_openapsoffline).date().duration();
public static final OptionsToShow TEMPTARGET = new OptionsToShow(R.id.careportal_temporarytarget, R.string.careportal_temporarytarget).date().duration().tempTarget();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.careportal_fragment, container, false);
view.findViewById(R.id.careportal_bgcheck).setOnClickListener(this);
view.findViewById(R.id.careportal_announcement).setOnClickListener(this);
view.findViewById(R.id.careportal_cgmsensorinsert).setOnClickListener(this);
view.findViewById(R.id.careportal_cgmsensorstart).setOnClickListener(this);
view.findViewById(R.id.careportal_combobolus).setOnClickListener(this);
view.findViewById(R.id.careportal_correctionbolus).setOnClickListener(this);
view.findViewById(R.id.careportal_carbscorrection).setOnClickListener(this);
view.findViewById(R.id.careportal_exercise).setOnClickListener(this);
view.findViewById(R.id.careportal_insulincartridgechange).setOnClickListener(this);
view.findViewById(R.id.careportal_pumpbatterychange).setOnClickListener(this);
view.findViewById(R.id.careportal_mealbolus).setOnClickListener(this);
view.findViewById(R.id.careportal_note).setOnClickListener(this);
view.findViewById(R.id.careportal_profileswitch).setOnClickListener(this);
view.findViewById(R.id.careportal_pumpsitechange).setOnClickListener(this);
view.findViewById(R.id.careportal_question).setOnClickListener(this);
view.findViewById(R.id.careportal_snackbolus).setOnClickListener(this);
view.findViewById(R.id.careportal_tempbasalend).setOnClickListener(this);
view.findViewById(R.id.careportal_tempbasalstart).setOnClickListener(this);
view.findViewById(R.id.careportal_openapsoffline).setOnClickListener(this);
view.findViewById(R.id.careportal_temporarytarget).setOnClickListener(this);
iage = view.findViewById(R.id.careportal_insulinage);
cage = view.findViewById(R.id.careportal_canulaage);
sage = view.findViewById(R.id.careportal_sensorage);
pbage = view.findViewById(R.id.careportal_pbage);
statsLayout = view.findViewById(R.id.careportal_stats);
noProfileView = view.findViewById(R.id.profileview_noprofile);
butonsLayout = view.findViewById(R.id.careportal_buttons);
ProfileStore profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null ? ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile() : null;
if (profileStore == null) {
noProfileView.setVisibility(View.VISIBLE);
butonsLayout.setVisibility(View.GONE);
} else {
noProfileView.setVisibility(View.GONE);
butonsLayout.setVisibility(View.VISIBLE);
}
if (Config.NSCLIENT)
statsLayout.setVisibility(View.GONE); // visible on overview
return view;
}
@Override
public synchronized void onResume() {
super.onResume();
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventCareportalEventChange.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> updateGUI(), FabricPrivacy::logException)
);
updateGUI();
}
@Override
public synchronized void onPause() {
super.onPause();
disposable.clear();
}
@Override
public void onClick(View view) {
action(view.getId(), getFragmentManager());
}
public static void action(int id, FragmentManager manager) {
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
switch (id) {
case R.id.careportal_bgcheck:
newDialog.setOptions(BGCHECK, R.string.careportal_bgcheck);
break;
case R.id.careportal_announcement:
newDialog.setOptions(ANNOUNCEMENT, R.string.careportal_announcement);
break;
case R.id.careportal_cgmsensorinsert:
newDialog.setOptions(SENSORCHANGE, R.string.careportal_cgmsensorinsert);
break;
case R.id.careportal_cgmsensorstart:
newDialog.setOptions(SENSORSTART, R.string.careportal_cgmsensorstart);
break;
case R.id.careportal_combobolus:
newDialog.setOptions(COMBOBOLUS, R.string.careportal_combobolus);
break;
case R.id.careportal_correctionbolus:
newDialog.setOptions(CORRECTIONBOLUS, R.string.careportal_correctionbolus);
break;
case R.id.careportal_carbscorrection:
newDialog.setOptions(CARBCORRECTION, R.string.careportal_carbscorrection);
break;
case R.id.careportal_exercise:
newDialog.setOptions(EXERCISE, R.string.careportal_exercise);
break;
case R.id.careportal_insulincartridgechange:
newDialog.setOptions(INSULINCHANGE, R.string.careportal_insulincartridgechange);
break;
case R.id.careportal_pumpbatterychange:
newDialog.setOptions(PUMPBATTERYCHANGE, R.string.careportal_pumpbatterychange);
break;
case R.id.careportal_mealbolus:
newDialog.setOptions(MEALBOLUS, R.string.careportal_mealbolus);
break;
case R.id.careportal_note:
newDialog.setOptions(NOTE, R.string.careportal_note);
break;
case R.id.careportal_profileswitch:
newDialog.setOptions(PROFILESWITCH, R.string.careportal_profileswitch);
break;
case R.id.careportal_pumpsitechange:
newDialog.setOptions(SITECHANGE, R.string.careportal_pumpsitechange);
break;
case R.id.careportal_question:
newDialog.setOptions(QUESTION, R.string.careportal_question);
break;
case R.id.careportal_snackbolus:
newDialog.setOptions(SNACKBOLUS, R.string.careportal_snackbolus);
break;
case R.id.careportal_tempbasalstart:
newDialog.setOptions(TEMPBASALSTART, R.string.careportal_tempbasalstart);
break;
case R.id.careportal_tempbasalend:
newDialog.setOptions(TEMPBASALEND, R.string.careportal_tempbasalend);
break;
case R.id.careportal_openapsoffline:
newDialog.setOptions(OPENAPSOFFLINE, R.string.careportal_openapsoffline);
break;
case R.id.careportal_temporarytarget:
newDialog.setOptions(TEMPTARGET, R.string.careportal_temporarytarget);
break;
default:
newDialog = null;
}
if (newDialog != null)
newDialog.show(manager, "NewNSTreatmentDialog");
}
protected void updateGUI() {
Activity activity = getActivity();
updateAge(activity, sage, iage, cage, pbage);
}
public static void updateAge(Activity activity, final TextView sage, final TextView iage, final TextView cage, final TextView pbage) {
if (activity != null) {
activity.runOnUiThread(
() -> {
CareportalEvent careportalEvent;
NSSettingsStatus nsSettings = NSSettingsStatus.getInstance();
double iageUrgent = nsSettings.getExtendedWarnValue("iage", "urgent", 96);
double iageWarn = nsSettings.getExtendedWarnValue("iage", "warn", 72);
handleAge(iage, CareportalEvent.INSULINCHANGE, iageWarn, iageUrgent);
double cageUrgent = nsSettings.getExtendedWarnValue("cage", "urgent", 72);
double cageWarn = nsSettings.getExtendedWarnValue("cage", "warn", 48);
handleAge(cage, CareportalEvent.SITECHANGE, cageWarn, cageUrgent);
double sageUrgent = nsSettings.getExtendedWarnValue("sage", "urgent", 166);
double sageWarn = nsSettings.getExtendedWarnValue("sage", "warn", 164);
handleAge(sage, CareportalEvent.SENSORCHANGE, sageWarn, sageUrgent);
double pbageUrgent = nsSettings.getExtendedWarnValue("bage", "urgent", 360);
double pbageWarn = nsSettings.getExtendedWarnValue("bage", "warn", 240);
handleAge(pbage, CareportalEvent.PUMPBATTERYCHANGE, pbageWarn, pbageUrgent);
}
);
}
}
public static int determineTextColor(CareportalEvent careportalEvent, double warnThreshold, double urgentThreshold) {
if (careportalEvent.isOlderThan(urgentThreshold)) {
return MainApp.gc(R.color.low);
} else if (careportalEvent.isOlderThan(warnThreshold)) {
return MainApp.gc(R.color.high);
} else {
return Color.WHITE;
}
}
private static TextView handleAge(final TextView age, String eventType, double warnThreshold, double urgentThreshold) {
return handleAge(age, "", eventType, warnThreshold, urgentThreshold, OverviewFragment.shorttextmode);
}
public static TextView handleAge(final TextView age, String prefix, String eventType, double warnThreshold, double urgentThreshold, boolean useShortText) {
String notavailable = useShortText ? "-" : MainApp.gs(R.string.notavailable);
if (age != null) {
CareportalEvent careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(eventType);
if (careportalEvent != null) {
age.setTextColor(CareportalFragment.determineTextColor(careportalEvent, warnThreshold, urgentThreshold));
age.setText(prefix + careportalEvent.age(useShortText));
} else {
age.setText(notavailable);
}
}
return age;
}
}

View file

@ -0,0 +1,139 @@
package info.nightscout.androidaps.plugins.general.careportal
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.FragmentManager
import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.EventCareportalEventChange
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
import info.nightscout.androidaps.plugins.general.overview.StatusLightHandler
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.resources.ResourceHelper
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.careportal_fragment.*
import kotlinx.android.synthetic.main.careportal_stats_fragment.*
import javax.inject.Inject
class CareportalFragment : DaggerFragment(), View.OnClickListener {
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var nsSettingsStatus: NSSettingsStatus
@Inject lateinit var statusLightHandler: StatusLightHandler
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
private val disposable = CompositeDisposable()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.careportal_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
careportal_bgcheck.setOnClickListener(this)
careportal_announcement.setOnClickListener(this)
careportal_cgmsensorinsert.setOnClickListener(this)
careportal_cgmsensorstart.setOnClickListener(this)
careportal_combobolus.setOnClickListener(this)
careportal_correctionbolus.setOnClickListener(this)
careportal_carbscorrection.setOnClickListener(this)
careportal_exercise.setOnClickListener(this)
careportal_insulincartridgechange.setOnClickListener(this)
careportal_pumpbatterychange.setOnClickListener(this)
careportal_mealbolus.setOnClickListener(this)
careportal_note.setOnClickListener(this)
careportal_profileswitch.setOnClickListener(this)
careportal_pumpsitechange.setOnClickListener(this)
careportal_question.setOnClickListener(this)
careportal_snackbolus.setOnClickListener(this)
careportal_tempbasalend.setOnClickListener(this)
careportal_tempbasalstart.setOnClickListener(this)
careportal_openapsoffline.setOnClickListener(this)
careportal_temporarytarget.setOnClickListener(this)
val profileStore = configBuilderPlugin.activeProfileInterface.profile
if (profileStore == null) {
profileview_noprofile.setVisibility(View.VISIBLE)
careportal_buttons.setVisibility(View.GONE)
} else {
profileview_noprofile.setVisibility(View.GONE)
careportal_buttons.setVisibility(View.VISIBLE)
}
}
@Synchronized override fun onResume() {
super.onResume()
disposable.add(rxBus
.toObservable(EventCareportalEventChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }) { FabricPrivacy.logException(it) }
)
updateGUI()
}
@Synchronized override fun onPause() {
super.onPause()
disposable.clear()
}
override fun onClick(view: View) {
val BGCHECK = OptionsToShow(R.id.careportal_bgcheck, R.string.careportal_bgcheck).date().bg()
val SNACKBOLUS = OptionsToShow(R.id.careportal_snackbolus, R.string.careportal_snackbolus).date().bg().insulin().carbs().prebolus()
val MEALBOLUS = OptionsToShow(R.id.careportal_mealbolus, R.string.careportal_mealbolus).date().bg().insulin().carbs().prebolus()
val CORRECTIONBOLUS = OptionsToShow(R.id.careportal_correctionbolus, R.string.careportal_correctionbolus).date().bg().insulin().carbs().prebolus()
val CARBCORRECTION = OptionsToShow(R.id.careportal_carbscorrection, R.string.careportal_carbscorrection).date().bg().carbs()
val COMBOBOLUS = OptionsToShow(R.id.careportal_combobolus, R.string.careportal_combobolus).date().bg().insulin().carbs().prebolus().duration().split()
val ANNOUNCEMENT = OptionsToShow(R.id.careportal_announcement, R.string.careportal_announcement).date().bg()
val NOTE = OptionsToShow(R.id.careportal_note, R.string.careportal_note).date().bg().duration()
val QUESTION = OptionsToShow(R.id.careportal_question, R.string.careportal_question).date().bg()
val EXERCISE = OptionsToShow(R.id.careportal_exercise, R.string.careportal_exercise).date().duration()
val SITECHANGE = OptionsToShow(R.id.careportal_pumpsitechange, R.string.careportal_pumpsitechange).date().bg()
val SENSORSTART = OptionsToShow(R.id.careportal_cgmsensorstart, R.string.careportal_cgmsensorstart).date().bg()
val SENSORCHANGE = OptionsToShow(R.id.careportal_cgmsensorinsert, R.string.careportal_cgmsensorinsert).date().bg()
val INSULINCHANGE = OptionsToShow(R.id.careportal_insulincartridgechange, R.string.careportal_insulincartridgechange).date().bg()
val PUMPBATTERYCHANGE = OptionsToShow(R.id.careportal_pumpbatterychange, R.string.careportal_pumpbatterychange).date().bg()
val TEMPBASALSTART = OptionsToShow(R.id.careportal_tempbasalstart, R.string.careportal_tempbasalstart).date().bg().duration().percent().absolute()
val TEMPBASALEND = OptionsToShow(R.id.careportal_tempbasalend, R.string.careportal_tempbasalend).date().bg()
val PROFILESWITCH = OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch).date().duration().profile()
val OPENAPSOFFLINE = OptionsToShow(R.id.careportal_openapsoffline, R.string.careportal_openapsoffline).date().duration()
val TEMPTARGET = OptionsToShow(R.id.careportal_temporarytarget, R.string.careportal_temporarytarget).date().duration().tempTarget()
val newDialog = NewNSTreatmentDialog()
when (view.id) {
R.id.careportal_bgcheck -> newDialog.setOptions(BGCHECK, R.string.careportal_bgcheck)
R.id.careportal_announcement -> newDialog.setOptions(ANNOUNCEMENT, R.string.careportal_announcement)
R.id.careportal_cgmsensorinsert -> newDialog.setOptions(SENSORCHANGE, R.string.careportal_cgmsensorinsert)
R.id.careportal_cgmsensorstart -> newDialog.setOptions(SENSORSTART, R.string.careportal_cgmsensorstart)
R.id.careportal_combobolus -> newDialog.setOptions(COMBOBOLUS, R.string.careportal_combobolus)
R.id.careportal_correctionbolus -> newDialog.setOptions(CORRECTIONBOLUS, R.string.careportal_correctionbolus)
R.id.careportal_carbscorrection -> newDialog.setOptions(CARBCORRECTION, R.string.careportal_carbscorrection)
R.id.careportal_exercise -> newDialog.setOptions(EXERCISE, R.string.careportal_exercise)
R.id.careportal_insulincartridgechange -> newDialog.setOptions(INSULINCHANGE, R.string.careportal_insulincartridgechange)
R.id.careportal_pumpbatterychange -> newDialog.setOptions(PUMPBATTERYCHANGE, R.string.careportal_pumpbatterychange)
R.id.careportal_mealbolus -> newDialog.setOptions(MEALBOLUS, R.string.careportal_mealbolus)
R.id.careportal_note -> newDialog.setOptions(NOTE, R.string.careportal_note)
R.id.careportal_profileswitch -> newDialog.setOptions(PROFILESWITCH, R.string.careportal_profileswitch)
R.id.careportal_pumpsitechange -> newDialog.setOptions(SITECHANGE, R.string.careportal_pumpsitechange)
R.id.careportal_question -> newDialog.setOptions(QUESTION, R.string.careportal_question)
R.id.careportal_snackbolus -> newDialog.setOptions(SNACKBOLUS, R.string.careportal_snackbolus)
R.id.careportal_tempbasalstart -> newDialog.setOptions(TEMPBASALSTART, R.string.careportal_tempbasalstart)
R.id.careportal_tempbasalend -> newDialog.setOptions(TEMPBASALEND, R.string.careportal_tempbasalend)
R.id.careportal_openapsoffline -> newDialog.setOptions(OPENAPSOFFLINE, R.string.careportal_openapsoffline)
R.id.careportal_temporarytarget -> newDialog.setOptions(TEMPTARGET, R.string.careportal_temporarytarget)
}
fragmentManager?.let {
NewNSTreatmentDialog().show(it, "CareportalFragment")
}
}
protected fun updateGUI() {
statusLightHandler.updateAge(careportal_sensorage, careportal_insulinage, careportal_canulaage, careportal_pbage)
}
}

View file

@ -19,7 +19,8 @@ import android.widget.RadioButton;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatDialogFragment;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.fragment.app.DialogFragment;
import com.google.common.collect.Lists;
@ -37,6 +38,9 @@ import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.inject.Inject;
import dagger.android.support.DaggerDialogFragment;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
@ -47,7 +51,7 @@ import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.ProfileSwitch;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction;
import info.nightscout.androidaps.plugins.general.careportal.OptionsToShow;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
@ -58,15 +62,24 @@ import info.nightscout.androidaps.utils.HardLimits;
import info.nightscout.androidaps.utils.JsonHelper;
import info.nightscout.androidaps.utils.NumberPicker;
import info.nightscout.androidaps.utils.OKDialog;
import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.SafeParse;
import info.nightscout.androidaps.utils.Translator;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
public class NewNSTreatmentDialog extends DaggerDialogFragment implements View.OnClickListener, DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener {
@Inject DefaultValueHelper defaultValueHelper;
@Inject ProfileFunction profileFunction;
@Inject ResourceHelper resourceHelper;
@Inject ConstraintChecker constraintChecker;
@Inject SP sp;
@Inject ConfigBuilderPlugin configBuilderPlugin;
@Inject TreatmentsPlugin treatmentsPlugin;
public class NewNSTreatmentDialog extends AppCompatDialogFragment implements View.OnClickListener, DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener {
private static Logger log = LoggerFactory.getLogger(NewNSTreatmentDialog.class);
private static OptionsToShow options;
private static String event;
private static @StringRes int event;
private Profile profile;
public ProfileStore profileStore;
@ -107,7 +120,7 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
public NewNSTreatmentDialog setOptions(OptionsToShow options, int event) {
this.options = options;
this.event = MainApp.gs(event);
this.event = event;
return this;
}
@ -120,7 +133,7 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (options == null) return null;
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
@ -130,28 +143,28 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
setStyle(DialogFragment.STYLE_NORMAL, getTheme());
View view = inflater.inflate(R.layout.careportal_newnstreatment_dialog, container, false);
layoutPercent = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_percent_layout);
layoutAbsolute = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_absolute_layout);
layoutPercent = view.findViewById(R.id.careportal_newnstreatment_percent_layout);
layoutAbsolute = view.findViewById(R.id.careportal_newnstreatment_absolute_layout);
layoutReuse = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_reuse_layout);
layoutReuse = view.findViewById(R.id.careportal_newnstreatment_reuse_layout);
eventTypeText = (TextView) view.findViewById(R.id.careportal_newnstreatment_eventtype);
eventTypeText = view.findViewById(R.id.careportal_newnstreatment_eventtype);
eventTypeText.setText(event);
bgUnitsView = (TextView) view.findViewById(R.id.careportal_newnstreatment_bgunits);
meterRadioButton = (RadioButton) view.findViewById(R.id.careportal_newnstreatment_meter);
sensorRadioButton = (RadioButton) view.findViewById(R.id.careportal_newnstreatment_sensor);
otherRadioButton = (RadioButton) view.findViewById(R.id.careportal_newnstreatment_other);
profileSpinner = (Spinner) view.findViewById(R.id.careportal_newnstreatment_profile);
bgUnitsView = view.findViewById(R.id.careportal_newnstreatment_bgunits);
meterRadioButton = view.findViewById(R.id.careportal_newnstreatment_meter);
sensorRadioButton = view.findViewById(R.id.careportal_newnstreatment_sensor);
otherRadioButton = view.findViewById(R.id.careportal_newnstreatment_other);
profileSpinner = view.findViewById(R.id.careportal_newnstreatment_profile);
reuseButton = (Button) view.findViewById(R.id.careportal_newnstreatment_reusebutton);
reuseButton = view.findViewById(R.id.careportal_newnstreatment_reusebutton);
notesEdit = (EditText) view.findViewById(R.id.careportal_newnstreatment_notes);
notesEdit = view.findViewById(R.id.careportal_newnstreatment_notes);
reasonSpinner = (Spinner) view.findViewById(R.id.careportal_newnstreatment_temptarget_reason);
reasonSpinner = view.findViewById(R.id.careportal_newnstreatment_temptarget_reason);
eventTime = new Date();
dateButton = (TextView) view.findViewById(R.id.careportal_newnstreatment_eventdate);
timeButton = (TextView) view.findViewById(R.id.careportal_newnstreatment_eventtime);
dateButton = view.findViewById(R.id.careportal_newnstreatment_eventdate);
timeButton = view.findViewById(R.id.careportal_newnstreatment_eventtime);
dateButton.setText(DateUtil.dateString(eventTime));
timeButton.setText(DateUtil.timeString(eventTime));
dateButton.setOnClickListener(this);
@ -161,8 +174,8 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
view.findViewById(R.id.cancel).setOnClickListener(this);
// profile
profile = ProfileFunctions.getInstance().getProfile();
profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile();
profile = profileFunction.getProfile();
profileStore = configBuilderPlugin.getActiveProfileInterface().getProfile();
if (profileStore == null) {
if (options.eventType == R.id.careportal_profileswitch) {
log.error("Profile switch called but plugin doesn't contain valid profile");
@ -175,18 +188,18 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
profileSpinner.setAdapter(adapter);
// set selected to actual profile
for (int p = 0; p < profileList.size(); p++) {
if (profileList.get(p).equals(ProfileFunctions.getInstance().getProfileName(false)))
if (profileList.get(p).equals(profileFunction.getProfileName(false)))
profileSpinner.setSelection(p);
}
}
final Double bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, ProfileFunctions.getSystemUnits());
final Double bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, profileFunction.getUnits());
// temp target
final List<String> reasonList = Lists.newArrayList(
MainApp.gs(R.string.manual),
MainApp.gs(R.string.eatingsoon),
MainApp.gs(R.string.activity),
MainApp.gs(R.string.hypo));
resourceHelper.gs(R.string.manual),
resourceHelper.gs(R.string.eatingsoon),
resourceHelper.gs(R.string.activity),
resourceHelper.gs(R.string.hypo));
ArrayAdapter<String> adapterReason = new ArrayAdapter<>(getContext(),
R.layout.spinner_centered, reasonList);
reasonSpinner.setAdapter(adapterReason);
@ -203,16 +216,15 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
}
boolean erase = false;
String units = ProfileFunctions.getSystemUnits();
if (MainApp.gs(R.string.eatingsoon).equals(reasonList.get(position))) {
defaultDuration = DefaultValueHelper.determineEatingSoonTTDuration();
defaultTarget = DefaultValueHelper.determineEatingSoonTT();
} else if (MainApp.gs(R.string.activity).equals(reasonList.get(position))) {
defaultDuration = DefaultValueHelper.determineActivityTTDuration();
defaultTarget = DefaultValueHelper.determineActivityTT();
} else if (MainApp.gs(R.string.hypo).equals(reasonList.get(position))) {
defaultDuration = DefaultValueHelper.determineHypoTTDuration();
defaultTarget = DefaultValueHelper.determineHypoTT();
if (resourceHelper.gs(R.string.eatingsoon).equals(reasonList.get(position))) {
defaultDuration = defaultValueHelper.determineEatingSoonTTDuration();
defaultTarget = defaultValueHelper.determineEatingSoonTT();
} else if (resourceHelper.gs(R.string.activity).equals(reasonList.get(position))) {
defaultDuration = defaultValueHelper.determineActivityTTDuration();
defaultTarget = defaultValueHelper.determineActivityTT();
} else if (resourceHelper.gs(R.string.hypo).equals(reasonList.get(position))) {
defaultDuration = defaultValueHelper.determineHypoTTDuration();
defaultTarget = defaultValueHelper.determineHypoTT();
} else if (editDuration.getValue() != 0) {
defaultDuration = editDuration.getValue();
} else {
@ -237,7 +249,7 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
});
// bg
bgUnitsView.setText(ProfileFunctions.getSystemUnits());
bgUnitsView.setText(profileFunction.getUnits());
TextWatcher bgTextWatcher = new TextWatcher() {
@ -256,7 +268,7 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
if (profile == null) {
editBg.setParams(bg, 0d, 500d, 0.1d, new DecimalFormat("0"), false, view.findViewById(R.id.ok), bgTextWatcher);
editTemptarget.setParams(Constants.MIN_TT_MGDL, Constants.MIN_TT_MGDL, Constants.MAX_TT_MGDL, 0.1d, new DecimalFormat("0.0"), false, view.findViewById(R.id.ok));
} else if (ProfileFunctions.getSystemUnits().equals(Constants.MMOL)) {
} else if (profileFunction.getUnits().equals(Constants.MMOL)) {
editBg.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false, view.findViewById(R.id.ok), bgTextWatcher);
editTemptarget.setParams(Constants.MIN_TT_MMOL, Constants.MIN_TT_MMOL, Constants.MAX_TT_MMOL, 0.1d, new DecimalFormat("0.0"), false, view.findViewById(R.id.ok));
} else {
@ -265,7 +277,7 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
}
sensorRadioButton.setOnCheckedChangeListener((buttonView, isChecked) -> {
Double bg1 = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, ProfileFunctions.getSystemUnits());
double bg1 = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, profileFunction.getUnits());
if (savedInstanceState != null && savedInstanceState.getDouble("editBg") != bg1) {
editBg.setValue(savedInstanceState.getDouble("editBg"));
} else {
@ -273,11 +285,11 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
}
});
Integer maxCarbs = ConstraintChecker.getInstance().getMaxCarbsAllowed().value();
Integer maxCarbs = constraintChecker.getMaxCarbsAllowed().value();
editCarbs = view.findViewById(R.id.careportal_newnstreatment_carbsinput);
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, view.findViewById(R.id.ok));
Double maxInsulin = ConstraintChecker.getInstance().getMaxBolusAllowed().value();
Double maxInsulin = constraintChecker.getMaxBolusAllowed().value();
editInsulin = view.findViewById(R.id.careportal_newnstreatment_insulininput);
editInsulin.setParams(0d, 0d, maxInsulin, 0.05d, new DecimalFormat("0.00"), false, view.findViewById(R.id.ok));
@ -306,7 +318,7 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
Integer maxPercent = 200;
if (profile != null)
maxPercent = ConstraintChecker.getInstance().getMaxBasalPercentAllowed(profile).value();
maxPercent = constraintChecker.getMaxBasalPercentAllowed(profile).value();
editPercent = view.findViewById(R.id.careportal_newnstreatment_percentinput);
editPercent.setParams(0d, -100d, (double) maxPercent, 5d, new DecimalFormat("0"), true, view.findViewById(R.id.ok), percentTextWatcher);
@ -330,7 +342,7 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
Double maxAbsolute = HardLimits.maxBasal();
if (profile != null)
maxAbsolute = ConstraintChecker.getInstance().getMaxBasalAllowed(profile).value();
maxAbsolute = constraintChecker.getMaxBasalAllowed(profile).value();
editAbsolute = view.findViewById(R.id.careportal_newnstreatment_absoluteinput);
editAbsolute.setParams(0d, 0d, maxAbsolute, 0.05d, new DecimalFormat("0.00"), true, view.findViewById(R.id.ok), absoluteTextWatcher);
@ -343,7 +355,7 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
editTimeshift = view.findViewById(R.id.careportal_newnstreatment_timeshift);
editTimeshift.setParams(0d, (double) Constants.CPP_MIN_TIMESHIFT, (double) Constants.CPP_MAX_TIMESHIFT, 1d, new DecimalFormat("0"), false, view.findViewById(R.id.ok));
ProfileSwitch ps = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(DateUtil.now());
ProfileSwitch ps = treatmentsPlugin.getProfileSwitchFromHistory(DateUtil.now());
if (ps != null && ps.isCPP) {
final int percentage = ps.percentage;
final int timeshift = ps.timeshift;
@ -452,7 +464,7 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
if ((data.size() > 0) &&
(data.get(0).date > millis - 7 * 60 * 1000L) &&
(data.get(0).date < millis + 7 * 60 * 1000L)) {
editBg.setValue(Profile.fromMgdlToUnits(data.get(0).value, ProfileFunctions.getSystemUnits()));
editBg.setValue(Profile.fromMgdlToUnits(data.get(0).value, profileFunction.getUnits()));
}
}
@ -474,8 +486,8 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
updateBGforDateTime();
}
JSONObject gatherData() {
String enteredBy = SP.getString("careportal_enteredby", "");
private JSONObject gatherData() {
String enteredBy = sp.getString("careportal_enteredby", "");
JSONObject data = new JSONObject();
try {
boolean allowZeroDuration = false;
@ -579,7 +591,7 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
data.put("preBolus", SafeParse.stringToDouble(editCarbTime.getText()));
if (!notesEdit.getText().toString().equals(""))
data.put("notes", notesEdit.getText().toString());
data.put("units", ProfileFunctions.getSystemUnits());
data.put("units", profileFunction.getUnits());
if (!enteredBy.equals("")) data.put("enteredBy", enteredBy);
if (options.eventType == R.id.careportal_combobolus) {
Double enteredInsulin = SafeParse.stringToDouble(editInsulin.getText());
@ -593,88 +605,88 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
return data;
}
String buildConfirmText(JSONObject data) {
private String buildConfirmText(JSONObject data) {
String ret = "";
// if (data.has("eventType")) {
// ret += MainApp.gs(R.string.careportal_newnstreatment_eventtype);
// ret += resourceHelper.gs(R.string.careportal_newnstreatment_eventtype);
// ret += ": ";
// ret += Translator.translate(JsonHelper.safeGetString(data, "eventType", ""));
// ret += "\n";
// }
if (data.has("glucose")) {
ret += MainApp.gs(R.string.treatments_wizard_bg_label);
ret += resourceHelper.gs(R.string.treatments_wizard_bg_label);
ret += ": ";
ret += JsonHelper.safeGetObject(data, "glucose", "");
ret += " " + ProfileFunctions.getSystemUnits() + "\n";
ret += " " + profileFunction.getUnits() + "\n";
}
if (data.has("glucoseType")) {
ret += MainApp.gs(R.string.careportal_newnstreatment_glucosetype);
ret += resourceHelper.gs(R.string.careportal_newnstreatment_glucosetype);
ret += ": ";
ret += Translator.translate(JsonHelper.safeGetString(data, "glucoseType", ""));
ret += "\n";
}
if (data.has("carbs")) {
ret += MainApp.gs(R.string.careportal_newnstreatment_carbs_label);
ret += resourceHelper.gs(R.string.careportal_newnstreatment_carbs_label);
ret += ": ";
ret += JsonHelper.safeGetObject(data, "carbs", "");
ret += " g\n";
}
if (data.has("insulin")) {
ret += MainApp.gs(R.string.careportal_newnstreatment_insulin_label);
ret += resourceHelper.gs(R.string.careportal_newnstreatment_insulin_label);
ret += ": ";
ret += JsonHelper.safeGetObject(data, "insulin", "");
ret += " U\n";
}
if (data.has("duration")) {
ret += MainApp.gs(R.string.careportal_newnstreatment_duration_label);
ret += resourceHelper.gs(R.string.careportal_newnstreatment_duration_label);
ret += ": ";
ret += JsonHelper.safeGetObject(data, "duration", "");
ret += " min\n";
}
if (data.has("percent")) {
ret += MainApp.gs(R.string.careportal_newnstreatment_percent_label);
ret += resourceHelper.gs(R.string.careportal_newnstreatment_percent_label);
ret += ": ";
ret += JsonHelper.safeGetObject(data, "percent", "");
ret += " %\n";
}
if (data.has("absolute")) {
ret += MainApp.gs(R.string.careportal_newnstreatment_absolute_label);
ret += resourceHelper.gs(R.string.careportal_newnstreatment_absolute_label);
ret += ": ";
ret += JsonHelper.safeGetObject(data, "absolute", "");
ret += " U/h\n";
}
if (data.has("preBolus")) {
ret += MainApp.gs(R.string.careportal_newnstreatment_carbtime_label);
ret += resourceHelper.gs(R.string.careportal_newnstreatment_carbtime_label);
ret += ": ";
ret += JsonHelper.safeGetObject(data, "preBolus", "");
ret += " min\n";
}
if (data.has("notes")) {
ret += MainApp.gs(R.string.careportal_newnstreatment_notes_label);
ret += resourceHelper.gs(R.string.careportal_newnstreatment_notes_label);
ret += ": ";
ret += JsonHelper.safeGetObject(data, "notes", "");
ret += "\n";
}
if (data.has("profile")) {
ret += MainApp.gs(R.string.careportal_newnstreatment_profile_label);
ret += resourceHelper.gs(R.string.careportal_newnstreatment_profile_label);
ret += ": ";
ret += JsonHelper.safeGetObject(data, "profile", "");
ret += "\n";
}
if (data.has("percentage")) {
ret += MainApp.gs(R.string.careportal_newnstreatment_percentage_label);
ret += resourceHelper.gs(R.string.careportal_newnstreatment_percentage_label);
ret += ": ";
ret += JsonHelper.safeGetObject(data, "percentage", "");
ret += " %\n";
}
if (data.has("timeshift")) {
ret += MainApp.gs(R.string.careportal_newnstreatment_timeshift_label);
ret += resourceHelper.gs(R.string.careportal_newnstreatment_timeshift_label);
ret += ": ";
ret += JsonHelper.safeGetObject(data, "timeshift", "");
ret += " h\n";
}
if (data.has("targetBottom") && data.has("targetTop")) {
ret += MainApp.gs(R.string.target_range);
ret += resourceHelper.gs(R.string.target_range);
ret += " ";
ret += JsonHelper.safeGetObject(data, "targetBottom", "");
ret += " - ";
@ -682,13 +694,13 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
ret += "\n";
}
if (data.has("created_at")) {
ret += MainApp.gs(R.string.event_time_label);
ret += resourceHelper.gs(R.string.event_time_label);
ret += ": ";
ret += eventTime.toLocaleString();
ret += DateUtil.dateAndTimeString(eventTime);
ret += "\n";
}
if (data.has("enteredBy")) {
ret += MainApp.gs(R.string.careportal_newnstreatment_enteredby_title);
ret += resourceHelper.gs(R.string.careportal_newnstreatment_enteredby_title);
ret += ": ";
ret += JsonHelper.safeGetObject(data, "enteredBy", "");
ret += "\n";
@ -699,13 +711,13 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
private void confirmNSTreatmentCreation() {
final JSONObject data = gatherData();
OKDialog.showConfirmation(getContext(), Translator.translate(JsonHelper.safeGetString(data, "eventType", MainApp.gs(R.string.overview_treatment_label))), buildConfirmText(data), () -> createNSTreatment(data));
OKDialog.showConfirmation(getContext(), Translator.translate(JsonHelper.safeGetString(data, "eventType", resourceHelper.gs(R.string.overview_treatment_label))), buildConfirmText(data), () -> createNSTreatment(data));
}
void createNSTreatment(JSONObject data) {
if (JsonHelper.safeGetString(data, "eventType", "").equals(CareportalEvent.PROFILESWITCH)) {
ProfileSwitch profileSwitch = ProfileFunctions.getInstance().prepareProfileSwitch(
ProfileSwitch profileSwitch = profileFunction.prepareProfileSwitch(
profileStore,
JsonHelper.safeGetString(data, "profile"),
JsonHelper.safeGetInt(data, "duration"),

View file

@ -1,7 +1,6 @@
package info.nightscout.androidaps.plugins.general.food;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import androidx.annotation.Nullable;
@ -27,7 +26,6 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.db.ICallback;
import info.nightscout.androidaps.events.Event;
@ -58,27 +56,11 @@ public class FoodService extends OrmLiteBaseService<DatabaseHelper> {
.observeOn(Schedulers.io())
.subscribe(event -> {
int mode = event.getMode();
Bundle payload = event.getPayload();
try {
if (payload.containsKey("food")) {
JSONObject json = new JSONObject(payload.getString("food"));
if (mode == EventNsFood.Companion.getADD() || mode == EventNsFood.Companion.getUPDATE())
this.createFoodFromJsonIfNotExists(json);
else
this.deleteNS(json);
}
if (payload.containsKey("foods")) {
JSONArray array = new JSONArray(payload.getString("foods"));
JSONArray array = event.getFoods();
if (mode == EventNsFood.Companion.getADD() || mode == EventNsFood.Companion.getUPDATE())
this.createFoodFromJsonIfNotExists(array);
else
this.deleteNS(array);
}
} catch (JSONException e) {
log.error("Unhandled Exception", e);
}
}, FabricPrivacy::logException)
);
}

View file

@ -1,60 +0,0 @@
package info.nightscout.androidaps.plugins.general.maintenance;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.general.food.FoodPlugin;
import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.utils.OKDialog;
/**
*
*/
public class MaintenanceFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.maintenance_fragment, container, false);
view.findViewById(R.id.log_send).setOnClickListener(view1 -> MaintenancePlugin.getPlugin().sendLogs());
view.findViewById(R.id.log_delete).setOnClickListener(view1 -> MaintenancePlugin.getPlugin().deleteLogs());
view.findViewById(R.id.nav_resetdb).setOnClickListener(view1 ->
OKDialog.showConfirmation(getContext(), MainApp.gs(R.string.maintenance), MainApp.gs(R.string.reset_db_confirm), () -> {
MainApp.getDbHelper().resetDatabases();
// should be handled by Plugin-Interface and
// additional service interface and plugin registry
FoodPlugin.getPlugin().getService().resetFood();
TreatmentsPlugin.getPlugin().getService().resetTreatments();
})
);
view.findViewById(R.id.nav_export).setOnClickListener(view1 -> {
// start activity for checking permissions...
ImportExportPrefs.verifyStoragePermissions(this);
ImportExportPrefs.exportSharedPreferences(this);
});
view.findViewById(R.id.nav_import).setOnClickListener(view1 -> {
// start activity for checking permissions...
ImportExportPrefs.verifyStoragePermissions(this);
ImportExportPrefs.importSharedPreferences(this);
});
view.findViewById(R.id.nav_logsettings).setOnClickListener(view1 -> {
startActivity(new Intent(getActivity(), LogSettingActivity.class));
});
return view;
}
}

View file

@ -0,0 +1,57 @@
package info.nightscout.androidaps.plugins.general.maintenance
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.plugins.general.food.FoodPlugin
import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.OKDialog
import info.nightscout.androidaps.utils.resources.ResourceHelper
import kotlinx.android.synthetic.main.maintenance_fragment.*
import javax.inject.Inject
class MaintenanceFragment : DaggerFragment() {
@Inject lateinit var maintenancePlugin: MaintenancePlugin
@Inject lateinit var mainApp: MainApp
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.maintenance_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
log_send.setOnClickListener { maintenancePlugin.sendLogs() }
log_delete.setOnClickListener { maintenancePlugin.deleteLogs() }
nav_resetdb.setOnClickListener {
activity?.let { activity ->
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.maintenance), resourceHelper.gs(R.string.reset_db_confirm), Runnable {
MainApp.getDbHelper().resetDatabases()
// should be handled by Plugin-Interface and
// additional service interface and plugin registry
FoodPlugin.getPlugin().service.resetFood()
treatmentsPlugin.service.resetTreatments()
})
}
}
nav_export.setOnClickListener {
// start activity for checking permissions...
ImportExportPrefs.verifyStoragePermissions(this)
ImportExportPrefs.exportSharedPreferences(this)
}
nav_import.setOnClickListener {
// start activity for checking permissions...
ImportExportPrefs.verifyStoragePermissions(this)
ImportExportPrefs.importSharedPreferences(this)
}
nav_logsettings.setOnClickListener { startActivity(Intent(activity, LogSettingActivity::class.java)) }
}
}

View file

@ -1,267 +0,0 @@
package info.nightscout.androidaps.plugins.general.maintenance;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import androidx.core.content.FileProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import info.nightscout.androidaps.BuildConfig;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginDescription;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus;
import info.nightscout.androidaps.utils.SP;
public class MaintenancePlugin extends PluginBase {
private static final Logger LOG = LoggerFactory.getLogger(L.CORE);
private final Context ctx;
private static MaintenancePlugin maintenancePlugin;
@Deprecated
public static MaintenancePlugin getPlugin() {
return maintenancePlugin;
}
public static MaintenancePlugin initPlugin(Context ctx) {
if (maintenancePlugin == null) {
maintenancePlugin = new MaintenancePlugin(ctx);
}
return maintenancePlugin;
}
public MaintenancePlugin() {
// required for testing
super(null);
this.ctx = null;
}
MaintenancePlugin(Context ctx) {
super(new PluginDescription()
.mainType(PluginType.GENERAL)
.fragmentClass(MaintenanceFragment.class.getName())
.alwaysVisible(false)
.alwaysEnabled(true)
.pluginName(R.string.maintenance)
.shortName(R.string.maintenance_shortname)
.preferencesId(R.xml.pref_maintenance)
.description(R.string.description_maintenance)
);
this.ctx = ctx;
}
public void sendLogs() {
String recipient = SP.getString(R.string.key_maintenance_logs_email, "logs@androidaps.org");
int amount = SP.getInt(R.string.key_maintenance_logs_amount, 2);
String logDirectory = LoggerUtils.getLogDirectory();
List<File> logs = this.getLogfiles(logDirectory, amount);
File zipDir = this.ctx.getExternalFilesDir("exports");
File zipFile = new File(zipDir, this.constructName());
LOG.debug("zipFile: {}", zipFile.getAbsolutePath());
File zip = this.zipLogs(zipFile, logs);
Uri attachementUri = FileProvider.getUriForFile(this.ctx, BuildConfig.APPLICATION_ID + ".fileprovider", zip);
Intent emailIntent = this.sendMail(attachementUri, recipient, "Log Export");
LOG.debug("sending emailIntent");
ctx.startActivity(emailIntent);
}
//todo replace this with a call on startup of the application, specifically to remove
// unnecessary garbage from the log exports
public void deleteLogs() {
String logDirectory = LoggerUtils.getLogDirectory();
File logDir = new File(logDirectory);
File[] files = logDir.listFiles((file, name) -> name.startsWith("AndroidAPS")
&& name.endsWith(".zip"));
Arrays.sort(files, (f1, f2) -> f1.getName().compareTo(f2.getName()));
List<File> delFiles = Arrays.asList(files);
int amount = SP.getInt(R.string.key_logshipper_amount, 2);
int keepIndex = amount - 1;
if (keepIndex < delFiles.size()) {
delFiles = delFiles.subList(keepIndex, delFiles.size());
for (File file : delFiles) {
file.delete();
}
}
File exportDir = new File(logDirectory, "exports");
if (exportDir.exists()) {
File[] expFiles = exportDir.listFiles();
for (File file : expFiles) {
file.delete();
}
exportDir.delete();
}
}
/**
* returns a list of log files. The number of returned logs is given via the amount
* parameter.
*
* The log files are sorted by the name descending.
*
* @param directory
* @param amount
* @return
*/
public List<File> getLogfiles(String directory, int amount) {
LOG.debug("getting {} logs from directory {}", amount, directory);
File logDir = new File(directory);
File[] files = logDir.listFiles((file, name) -> name.startsWith("AndroidAPS")
&& (name.endsWith(".log")
|| (name.endsWith(".zip") && !name.endsWith(LoggerUtils.SUFFIX))));
Arrays.sort(files, (f1, f2) -> f2.getName().compareTo(f1.getName()));
List<File> result = Arrays.asList(files);
int toIndex = amount++;
if (toIndex > result.size()) {
toIndex = result.size();
}
LOG.debug("returning sublist 0 to {}", toIndex);
return result.subList(0, toIndex);
}
public File zipLogs(File zipFile, List<File> files) {
LOG.debug("creating zip {}", zipFile.getAbsolutePath());
try {
zip(zipFile, files);
} catch (IOException e) {
LOG.error("Cannot retrieve zip", e);
}
return zipFile;
}
/**
* construct the name of zip file which is used to export logs.
*
* The name is constructed using the following scheme:
* AndroidAPS_LOG_ + Long Time + .log.zip
*
* @return
*/
public String constructName() {
return "AndroidAPS_LOG_" + new Date().getTime() + LoggerUtils.SUFFIX;
}
public void zip(File zipFile, List<File> files) throws IOException {
final int BUFFER_SIZE = 2048;
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile)));
for (File file : files) {
byte[] data = new byte[BUFFER_SIZE];
try(FileInputStream fileInputStream = new FileInputStream( file )) {
try(BufferedInputStream origin = new BufferedInputStream(fileInputStream, BUFFER_SIZE)) {
ZipEntry entry = new ZipEntry(file.getName());
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER_SIZE)) != -1) {
out.write(data, 0, count);
}
}
}
}
out.close();
}
public static Intent sendMail(Uri attachementUri, String recipient, String subject) {
StringBuilder builder =new StringBuilder();
builder.append("ADD TIME OF EVENT HERE: " + System.lineSeparator());
builder.append("ADD ISSUE DESCRIPTION OR GITHUB ISSUE REFERENCE NUMBER: " + System.lineSeparator());
builder.append("-------------------------------------------------------" + System.lineSeparator());
builder.append("(Please remember this will send only very recent logs." + System.lineSeparator());
builder.append("If you want to provide logs for event older than a few hours," + System.lineSeparator());
builder.append("you have to do it manually)" + System.lineSeparator());
builder.append("-------------------------------------------------------" + System.lineSeparator());
builder.append(MainApp.gs(R.string.app_name) + " " + BuildConfig.VERSION + System.lineSeparator());
if (Config.NSCLIENT)
builder.append("NSCLIENT" + System.lineSeparator());
builder.append("Build: " + BuildConfig.BUILDVERSION + System.lineSeparator());
builder.append("Remote: " + BuildConfig.REMOTE + System.lineSeparator());
builder.append("Flavor: " + BuildConfig.FLAVOR + BuildConfig.BUILD_TYPE + System.lineSeparator());
builder.append(MainApp.gs(R.string.configbuilder_nightscoutversion_label) + " " + NSSettingsStatus.getInstance().nightscoutVersionName + System.lineSeparator());
if (MainApp.engineeringMode)
builder.append(MainApp.gs(R.string.engineering_mode_enabled));
return sendMail(attachementUri, recipient, subject, builder.toString());
}
/**
* send a mail with the given file to the recipients with the given subject.
*
* the returned intent should be used to really send the mail using
*
* startActivity(Intent.createChooser(emailIntent , "Send email..."));
*
* @param attachementUri
* @param recipient
* @param subject
* @param body
*
* @return
*/
public static Intent sendMail(Uri attachementUri, String recipient, String subject, String body) {
LOG.debug("sending email to {} with subject {}", recipient, subject);
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("text/plain");
emailIntent.putExtra(Intent.EXTRA_EMAIL , new String[]{recipient});
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(Intent.EXTRA_TEXT, body);
LOG.debug("put path {}", attachementUri.toString());
emailIntent.putExtra(Intent.EXTRA_STREAM, attachementUri);
emailIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
return emailIntent;
}
}

View file

@ -0,0 +1,201 @@
package info.nightscout.androidaps.plugins.general.maintenance
import android.content.Intent
import android.net.Uri
import androidx.core.content.FileProvider
import info.nightscout.androidaps.BuildConfig
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
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.plugins.general.nsclient.data.NSSettingsStatus
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import java.io.*
import java.util.*
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class MaintenancePlugin @Inject constructor(
private val aapsLogger: AAPSLogger,
private val mainApp: MainApp,
private val resourceHelper: ResourceHelper,
private val sp: SP,
private val nsSettingsStatus: NSSettingsStatus
) : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL)
.fragmentClass(MaintenanceFragment::class.java.name)
.alwaysVisible(false)
.alwaysEnabled(true)
.pluginName(R.string.maintenance)
.shortName(R.string.maintenance_shortname)
.preferencesId(R.xml.pref_maintenance)
.description(R.string.description_maintenance)
) {
fun sendLogs() {
val recipient = sp.getString(R.string.key_maintenance_logs_email, "logs@androidaps.org")
val amount = sp.getInt(R.string.key_maintenance_logs_amount, 2)
val logDirectory = LoggerUtils.getLogDirectory()
val logs = getLogFiles(logDirectory, amount)
val zipDir = mainApp.getExternalFilesDir("exports")
val zipFile = File(zipDir, constructName())
aapsLogger.debug("zipFile: ${zipFile.absolutePath}")
val zip = zipLogs(zipFile, logs)
val attachmentUri = FileProvider.getUriForFile(mainApp, BuildConfig.APPLICATION_ID + ".fileprovider", zip)
val emailIntent: Intent = this.sendMail(attachmentUri, recipient, "Log Export")
aapsLogger.debug("sending emailIntent")
mainApp.startActivity(emailIntent)
}
//todo replace this with a call on startup of the application, specifically to remove
// unnecessary garbage from the log exports
fun deleteLogs() {
val logDirectory = LoggerUtils.getLogDirectory()
val logDir = File(logDirectory)
val files = logDir.listFiles { _: File?, name: String ->
(name.startsWith("AndroidAPS")
&& name.endsWith(".zip"))
}
Arrays.sort(files) { f1: File, f2: File -> f1.name.compareTo(f2.name) }
var delFiles = listOf(*files)
val amount = sp.getInt(R.string.key_logshipper_amount, 2)
val keepIndex = amount - 1
if (keepIndex < delFiles.size) {
delFiles = delFiles.subList(keepIndex, delFiles.size)
for (file in delFiles) {
file.delete()
}
}
val exportDir = File(logDirectory, "exports")
if (exportDir.exists()) {
val expFiles = exportDir.listFiles()
for (file in expFiles) {
file.delete()
}
exportDir.delete()
}
}
/**
* returns a list of log files. The number of returned logs is given via the amount
* parameter.
*
* The log files are sorted by the name descending.
*
* @param directory
* @param amount
* @return
*/
fun getLogFiles(directory: String, amount: Int): List<File> {
aapsLogger.debug("getting $amount logs from directory $directory")
val logDir = File(directory)
val files = logDir.listFiles { _: File?, name: String ->
(name.startsWith("AndroidAPS")
&& (name.endsWith(".log")
|| name.endsWith(".zip") && !name.endsWith(LoggerUtils.SUFFIX)))
}
Arrays.sort(files) { f1: File, f2: File -> f2.name.compareTo(f1.name) }
val result = listOf(*files)
var toIndex = amount + 1
if (toIndex > result.size) {
toIndex = result.size
}
aapsLogger.debug("returning sublist 0 to $toIndex")
return result.subList(0, toIndex)
}
fun zipLogs(zipFile: File, files: List<File>): File {
aapsLogger.debug("creating zip ${zipFile.absolutePath}")
try {
zip(zipFile, files)
} catch (e: IOException) {
aapsLogger.error("Cannot retrieve zip", e)
}
return zipFile
}
/**
* construct the name of zip file which is used to export logs.
*
* The name is constructed using the following scheme:
* AndroidAPS_LOG_ + Long Time + .log.zip
*
* @return
*/
private fun constructName(): String {
return "AndroidAPS_LOG_" + Date().time + LoggerUtils.SUFFIX
}
private fun zip(zipFile: File?, files: List<File>) {
val bufferSize = 2048
val out = ZipOutputStream(BufferedOutputStream(FileOutputStream(zipFile)))
for (file in files) {
val data = ByteArray(bufferSize)
FileInputStream(file).use { fileInputStream ->
BufferedInputStream(fileInputStream, bufferSize).use { origin ->
val entry = ZipEntry(file.name)
out.putNextEntry(entry)
var count: Int
while (origin.read(data, 0, bufferSize).also { count = it } != -1) {
out.write(data, 0, count)
}
}
}
}
out.close()
}
@Suppress("SameParameterValue")
private fun sendMail(attachmentUri: Uri, recipient: String, subject: String): Intent {
val builder = StringBuilder()
builder.append("ADD TIME OF EVENT HERE: " + System.lineSeparator())
builder.append("ADD ISSUE DESCRIPTION OR GITHUB ISSUE REFERENCE NUMBER: " + System.lineSeparator())
builder.append("-------------------------------------------------------" + System.lineSeparator())
builder.append("(Please remember this will send only very recent logs." + System.lineSeparator())
builder.append("If you want to provide logs for event older than a few hours," + System.lineSeparator())
builder.append("you have to do it manually)" + System.lineSeparator())
builder.append("-------------------------------------------------------" + System.lineSeparator())
builder.append(resourceHelper.gs(R.string.app_name) + " " + BuildConfig.VERSION + System.lineSeparator())
if (Config.NSCLIENT) builder.append("NSCLIENT" + System.lineSeparator())
builder.append("Build: " + BuildConfig.BUILDVERSION + System.lineSeparator())
builder.append("Remote: " + BuildConfig.REMOTE + System.lineSeparator())
builder.append("Flavor: " + BuildConfig.FLAVOR + BuildConfig.BUILD_TYPE + System.lineSeparator())
builder.append(resourceHelper.gs(R.string.configbuilder_nightscoutversion_label) + " " + nsSettingsStatus.nightscoutVersionName + System.lineSeparator())
if (MainApp.engineeringMode) builder.append(resourceHelper.gs(R.string.engineering_mode_enabled))
return sendMail(attachmentUri, recipient, subject, builder.toString())
}
/**
* send a mail with the given file to the recipients with the given subject.
*
* the returned intent should be used to really send the mail using
*
* startActivity(Intent.createChooser(emailIntent , "Send email..."));
*
* @param attachmentUri
* @param recipient
* @param subject
* @param body
*
* @return
*/
private fun sendMail(attachmentUri: Uri, recipient: String, subject: String, body: String): Intent {
aapsLogger.debug("sending email to $recipient with subject $subject")
val emailIntent = Intent(Intent.ACTION_SEND)
emailIntent.type = "text/plain"
emailIntent.putExtra(Intent.EXTRA_EMAIL, arrayOf(recipient))
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject)
emailIntent.putExtra(Intent.EXTRA_TEXT, body)
aapsLogger.debug("put path $attachmentUri")
emailIntent.putExtra(Intent.EXTRA_STREAM, attachmentUri)
emailIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
return emailIntent
}
}

View file

@ -50,7 +50,6 @@ public class NSClientPlugin extends PluginBase {
static NSClientPlugin nsClientPlugin;
@Deprecated
static public NSClientPlugin getPlugin() {
if (nsClientPlugin == null) {
nsClientPlugin = new NSClientPlugin();
@ -266,8 +265,8 @@ public class NSClientPlugin extends PluginBase {
}
AlarmAck ack = new AlarmAck();
ack.level = originalAlarm.getLevel();
ack.group = originalAlarm.getGroup();
ack.level = originalAlarm.level();
ack.group = originalAlarm.group();
ack.silenceTime = silenceTimeInMsec;
if (nsClientService != null)

View file

@ -1,36 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONObject;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.utils.SP;
/**
* Created by mike on 26.06.2016.
*/
public class BroadcastAlarm {
public static void handleAlarm(JSONObject alarm, Context context) {
Bundle bundle = new Bundle();
bundle.putString("data", alarm.toString());
Intent intent = new Intent(Intents.ACTION_ALARM);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("data", alarm.toString());
intent = new Intent(Intents.ACTION_ALARM);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
}
}
}

View file

@ -1,36 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONObject;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.utils.SP;
/**
* Created by mike on 26.06.2016.
*/
public class BroadcastAnnouncement {
public static void handleAnnouncement(JSONObject announcement, Context context) {
Bundle bundle = new Bundle();
bundle.putString("data", announcement.toString());
Intent intent = new Intent(Intents.ACTION_ANNOUNCEMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("data", announcement.toString());
intent = new Intent(Intents.ACTION_ANNOUNCEMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
}
}
}

View file

@ -1,39 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONArray;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.utils.SP;
/**
* Created by mike on 26.06.2016.
*/
public class BroadcastCals {
public static void handleNewCal(JSONArray cals, Context context, boolean isDelta) {
Bundle bundle = new Bundle();
bundle.putString("cals", cals.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_CAL);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("cals", cals.toString());
bundle.putBoolean("delta", isDelta);
intent = new Intent(Intents.ACTION_NEW_CAL);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
}
}
}

View file

@ -1,36 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONObject;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.utils.SP;
/**
* Created by mike on 26.06.2016.
*/
public class BroadcastClearAlarm {
public static void handleClearAlarm(JSONObject clearalarm, Context context) {
Bundle bundle = new Bundle();
bundle.putString("data", clearalarm.toString());
Intent intent = new Intent(Intents.ACTION_CLEAR_ALARM);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("data", clearalarm.toString());
intent = new Intent(Intents.ACTION_CLEAR_ALARM);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
}
}
}

View file

@ -1,45 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONArray;
import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.utils.SP;
public class BroadcastDeviceStatus {
public static void handleNewDeviceStatus(JSONArray statuses, Context context, boolean isDelta) {
List<JSONArray> splitted = BroadcastTreatment.splitArray(statuses);
for (JSONArray part: splitted) {
Bundle bundle = new Bundle();
bundle.putString("devicestatuses", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_DEVICESTATUS);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
}
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
splitted = BroadcastTreatment.splitArray(statuses);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("devicestatuses", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_DEVICESTATUS);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
}
}
}
}

View file

@ -1,96 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONArray;
import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.utils.SP;
/**
* Created by mike on 20.02.2016.
*/
public class BroadcastFood {
public static void handleNewFood(JSONArray foods, Context context, boolean isDelta) {
List<JSONArray> splitted = BroadcastTreatment.splitArray(foods);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("foods", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_FOOD);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
}
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("foods", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_FOOD);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
}
}
}
public static void handleChangedFood(JSONArray foods, Context context, boolean isDelta) {
List<JSONArray> splitted = BroadcastTreatment.splitArray(foods);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("foods", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_CHANGED_FOOD);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
}
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("foods", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_CHANGED_FOOD);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
}
}
}
public static void handleRemovedFood(JSONArray foods, Context context, boolean isDelta) {
Bundle bundle = new Bundle();
bundle.putString("foods", foods.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_REMOVED_FOOD);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("foods", foods.toString());
bundle.putBoolean("delta", isDelta);
intent = new Intent(Intents.ACTION_REMOVED_FOOD);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
}
}
}

View file

@ -1,39 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONArray;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.utils.SP;
/**
* Created by mike on 26.06.2016.
*/
public class BroadcastMbgs {
public static void handleNewMbg(JSONArray mbgs, Context context, boolean isDelta) {
Bundle bundle = new Bundle();
bundle.putString("mbgs", mbgs.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_MBG);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("mbgs", mbgs.toString());
bundle.putBoolean("delta", isDelta);
intent = new Intent(Intents.ACTION_NEW_MBG);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
}
}
}

View file

@ -1,40 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.utils.SP;
/**
* Created by mike on 20.02.2016.
*/
public class BroadcastProfile {
public static void handleNewTreatment(ProfileStore profile, Context context, boolean isDelta) {
Bundle bundle = new Bundle();
bundle.putString("profile", profile.getData().toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_PROFILE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("profile", profile.getData().toString());
bundle.putBoolean("delta", isDelta);
intent = new Intent(Intents.ACTION_NEW_PROFILE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
}
}
}

View file

@ -1,47 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONArray;
import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.utils.SP;
/**
* Created by mike on 22.02.2016.
*/
public class BroadcastSgvs {
public static void handleNewSgv(JSONArray sgvs, Context context, boolean isDelta) {
List<JSONArray> splitted = BroadcastTreatment.splitArray(sgvs);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("sgvs", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_SGV);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
}
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("sgvs", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_SGV);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
}
}
}
}

View file

@ -1,55 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus;
import info.nightscout.androidaps.plugins.general.nsclient.services.NSClientService;
import info.nightscout.androidaps.utils.SP;
/**
* Created by mike on 24.02.2016.
*/
public class BroadcastStatus {
private static Logger log = LoggerFactory.getLogger(L.NSCLIENT);
public static void handleNewStatus(NSSettingsStatus status, Context context, boolean isDelta) {
LocalBroadcastManager.getInstance(MainApp.instance())
.sendBroadcast(createIntent(status, isDelta));
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
context.sendBroadcast(createIntent(status, isDelta));
}
}
private static Intent createIntent(NSSettingsStatus status, boolean isDelta) {
Bundle bundle = new Bundle();
try {
bundle.putString("nsclientversionname", MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), 0).versionName);
bundle.putInt("nsclientversioncode", MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), 0).versionCode);
} catch (PackageManager.NameNotFoundException e) {
log.error("Unhandled exception", e);
}
bundle.putString("nightscoutversionname", NSClientService.nightscoutVersionName);
bundle.putInt("nightscoutversioncode", NSClientService.nightscoutVersionCode);
bundle.putString("status", status.getData().toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_STATUS);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
return intent;
}
}

View file

@ -1,153 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Intent;
import android.os.Bundle;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.utils.SP;
/**
* Created by mike on 20.02.2016.
*/
public class BroadcastTreatment {
private static Logger log = LoggerFactory.getLogger(L.NSCLIENT);
public static void handleNewTreatment(JSONObject treatment, boolean isDelta) {
Bundle bundle = new Bundle();
bundle.putString("treatment", treatment.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("treatment", treatment.toString());
bundle.putBoolean("delta", isDelta);
intent = new Intent(Intents.ACTION_NEW_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
MainApp.instance().getApplicationContext().sendBroadcast(intent);
}
}
public static void handleNewTreatment(JSONArray treatments, boolean isDelta) {
List<JSONArray> splitted = splitArray(treatments);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("treatments", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
}
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
splitted = splitArray(treatments);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("treatments", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
MainApp.instance().getApplicationContext().sendBroadcast(intent);
}
}
}
public static void handleChangedTreatment(JSONArray treatments, boolean isDelta) {
List<JSONArray> splitted = splitArray(treatments);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("treatments", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_CHANGED_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
}
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
splitted = splitArray(treatments);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("treatments", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_CHANGED_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
MainApp.instance().getApplicationContext().sendBroadcast(intent);
}
}
}
public static void handleRemovedTreatment(JSONArray treatments, boolean isDelta) {
Bundle bundle = new Bundle();
bundle.putString("treatments", treatments.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_REMOVED_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("treatments", treatments.toString());
bundle.putBoolean("delta", isDelta);
intent = new Intent(Intents.ACTION_REMOVED_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
MainApp.instance().getApplicationContext().sendBroadcast(intent);
}
}
public static List<JSONArray> splitArray(JSONArray array) {
List<JSONArray> ret = new ArrayList<>();
try {
int size = array.length();
int count = 0;
JSONArray newarr = null;
for (int i = 0; i < size; i++) {
if (count == 0) {
if (newarr != null) {
ret.add(newarr);
}
newarr = new JSONArray();
count = 20;
}
newarr.put(array.get(i));
--count;
}
if (newarr != null && newarr.length() > 0) {
ret.add(newarr);
}
} catch (JSONException e) {
log.error("Unhandled exception", e);
ret = new ArrayList<>();
ret.add(array);
}
return ret;
}
}

View file

@ -1,36 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONObject;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.utils.SP;
/**
* Created by mike on 26.06.2016.
*/
public class BroadcastUrgentAlarm {
public static void handleUrgentAlarm(JSONObject urgentalarm, Context context) {
Bundle bundle = new Bundle();
bundle.putString("data", urgentalarm.toString());
Intent intent = new Intent(Intents.ACTION_URGENT_ALARM);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("data", urgentalarm.toString());
intent = new Intent(Intents.ACTION_URGENT_ALARM);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
}
}
}

View file

@ -1,70 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.data;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.logging.L;
/**
* Created by mike on 11.06.2017.
*/
public class NSAlarm {
private static Logger log = LoggerFactory.getLogger(L.NSCLIENT);
JSONObject data;
public NSAlarm(JSONObject data) {
this.data = data;
}
public int getLevel() {
int retval = 0;
if (data.has("level")) {
try {
retval = data.getInt("level");
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
return retval;
}
public String getGroup() {
String retval = "N/A";
if (data.has("group")) {
try {
retval = data.getString("group");
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
return retval;
}
public String getTile() {
String retval = "N/A";
if (data.has("title")) {
try {
retval = data.getString("title");
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
return retval;
}
public String getMessage() {
String retval = "N/A";
if (data.has("message")) {
try {
retval = data.getString("message");
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
return retval;
}
}

View file

@ -0,0 +1,41 @@
package info.nightscout.androidaps.plugins.general.nsclient.data
import info.nightscout.androidaps.utils.JsonHelper
import org.json.JSONObject
class NSAlarm(private var data: JSONObject) {
/*
{
"level":2,
"title":"Urgent HIGH",
"message":"BG Now: 5.2 -0.1 → mmol\/L\nRaw BG: 5 mmol\/L Čistý\nBG 15m: 5 mmol\/L\nIOB: 0.00U\nCOB: 0g",
"eventName":"high",
"plugin":{"name":"simplealarms","label":"Simple Alarms","pluginType":"notification","enabled":true},
"pushoverSound":"persistent",
"debug":{"lastSGV":5.2,"thresholds":{"bgHigh":80,"bgTargetTop":75,"bgTargetBottom":72,"bgLow":70}},
"group":"default",
"key":"simplealarms_2"
}
*/
fun level(): Int =
JsonHelper.safeGetInt(data, "level", 0)
fun group(): String =
JsonHelper.safeGetString(data, "group", "N/A")
fun title(): String =
JsonHelper.safeGetString(data, "title", "N/A")
fun message(): String =
JsonHelper.safeGetString(data, "message", "N/A")
fun low() :Boolean =
JsonHelper.safeGetString(data, "eventName", "") == "low"
fun high() :Boolean =
JsonHelper.safeGetString(data, "eventName", "") == "high"
fun timeago() :Boolean =
JsonHelper.safeGetString(data, "eventName", "") == "timeago"
}

View file

@ -1,28 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.data;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.logging.L;
public class NSCal {
private static Logger log = LoggerFactory.getLogger(L.NSCLIENT);
public long date;
public double slope;
public double intercept;
public double scale = 1;
public void set(JSONObject json) {
try {
date = json.getLong("date");
slope = json.getDouble("slope");
intercept = json.getDouble("intercept");
scale = json.getDouble("scale");
} catch (JSONException e) {
log.error("Unhandled exception", e);
log.error("Data: " + json.toString());
}
}
}

View file

@ -1,28 +1,27 @@
package info.nightscout.androidaps.plugins.general.nsclient.data;
import android.content.Intent;
import android.os.Bundle;
import android.text.Html;
import android.text.Spanned;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import info.nightscout.androidaps.MainApp;
import javax.inject.Inject;
import javax.inject.Singleton;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.logging.BundleLogger;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.aps.loop.APSResult;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.Round;
import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
/**
* Created by mike on 25.06.2017.
@ -78,58 +77,50 @@ import info.nightscout.androidaps.utils.SP;
"NSCLIENT_ID": 1498406118857
}
*/
@Singleton
public class NSDeviceStatus {
private Logger log = LoggerFactory.getLogger(L.NSCLIENT);
private static NSDeviceStatus instance = null;
public static NSDeviceStatus getInstance() {
if (instance == null)
instance = new NSDeviceStatus();
return instance;
}
private final AAPSLogger aapsLogger;
private final SP sp;
private final ResourceHelper resourceHelper;
private final NSSettingsStatus nsSettingsStatus;
private JSONObject data = null;
public NSDeviceStatus() {
@Inject
public NSDeviceStatus(
AAPSLogger aapsLogger,
SP sp,
ResourceHelper resourceHelper,
NSSettingsStatus nsSettingsStatus
) {
this.aapsLogger = aapsLogger;
this.sp = sp;
this.resourceHelper = resourceHelper;
this.nsSettingsStatus = nsSettingsStatus;
}
public void handleNewData(Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle == null) return;
public void handleNewData(JSONArray devicestatuses) {
if (L.isEnabled(L.NSCLIENT))
log.debug("Got NS devicestatus: " + BundleLogger.log(bundle));
aapsLogger.debug(LTag.NSCLIENT, "Got NS devicestatus: $devicestatuses}");
for (int i = 0; i < devicestatuses.length(); i++) {
try {
if (bundle.containsKey("devicestatus")) {
JSONObject devicestatusJson = new JSONObject(bundle.getString("devicestatus"));
JSONObject devicestatusJson = devicestatuses.getJSONObject(i);
if (devicestatusJson != null) {
setData(devicestatusJson);
if (devicestatusJson.has("pump")) {
// Objectives 0
SP.putBoolean(R.string.key_ObjectivespumpStatusIsAvailableInNS, true);
sp.putBoolean(R.string.key_ObjectivespumpStatusIsAvailableInNS, true);
}
}
if (bundle.containsKey("devicestatuses")) {
String devicestatusesstring = bundle.getString("devicestatuses");
JSONArray jsonArray = new JSONArray(devicestatusesstring);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject devicestatusJson = jsonArray.getJSONObject(i);
setData(devicestatusJson);
if (devicestatusJson.has("pump")) {
// Objectives 0
SP.putBoolean(R.string.key_ObjectivespumpStatusIsAvailableInNS, true);
} catch (JSONException ignored) {
}
}
}
} catch (Exception e) {
log.error("Unhandled exception", e);
}
}
public NSDeviceStatus setData(JSONObject obj) {
this.data = obj;
updatePumpData(obj);
updatePumpData();
updateOpenApsData(obj);
updateUploaderData(obj);
return this;
@ -145,7 +136,7 @@ public class NSDeviceStatus {
}
}
} catch (JSONException e) {
log.error("Unhandled exception", e);
aapsLogger.error("Unhandled exception", e);
}
return "";
}
@ -161,7 +152,7 @@ public class NSDeviceStatus {
// ***** PUMP DATA ******
static DeviceStatusPumpData deviceStatusPumpData = null;
private DeviceStatusPumpData deviceStatusPumpData = null;
public Spanned getExtendedPumpStatus() {
if (deviceStatusPumpData != null && deviceStatusPumpData.extended != null)
@ -173,8 +164,8 @@ public class NSDeviceStatus {
//String[] ALL_STATUS_FIELDS = {"reservoir", "battery", "clock", "status", "device"};
StringBuilder string = new StringBuilder();
string.append("<span style=\"color:" + MainApp.gs(R.color.defaulttext).replace("#ff", "#") + "\">");
string.append(MainApp.gs(R.string.pump));
string.append("<span style=\"color:" + resourceHelper.gcs(R.color.defaulttext) + "\">");
string.append(resourceHelper.gs(R.string.pump));
string.append(": </span>");
if (deviceStatusPumpData == null)
@ -183,21 +174,21 @@ public class NSDeviceStatus {
// test warning level
int level = Levels.INFO;
long now = System.currentTimeMillis();
if (deviceStatusPumpData.clock + NSSettingsStatus.getInstance().extendedPumpSettings("urgentClock") * 60 * 1000L < now)
if (deviceStatusPumpData.clock + nsSettingsStatus.extendedPumpSettings("urgentClock") * 60 * 1000L < now)
level = Levels.URGENT;
else if (deviceStatusPumpData.reservoir < NSSettingsStatus.getInstance().extendedPumpSettings("urgentRes"))
else if (deviceStatusPumpData.reservoir < nsSettingsStatus.extendedPumpSettings("urgentRes"))
level = Levels.URGENT;
else if (deviceStatusPumpData.isPercent && deviceStatusPumpData.percent < NSSettingsStatus.getInstance().extendedPumpSettings("urgentBattP"))
else if (deviceStatusPumpData.isPercent && deviceStatusPumpData.percent < nsSettingsStatus.extendedPumpSettings("urgentBattP"))
level = Levels.URGENT;
else if (!deviceStatusPumpData.isPercent && deviceStatusPumpData.voltage < NSSettingsStatus.getInstance().extendedPumpSettings("urgentBattV"))
else if (!deviceStatusPumpData.isPercent && deviceStatusPumpData.voltage < nsSettingsStatus.extendedPumpSettings("urgentBattV"))
level = Levels.URGENT;
else if (deviceStatusPumpData.clock + NSSettingsStatus.getInstance().extendedPumpSettings("warnClock") * 60 * 1000L < now)
else if (deviceStatusPumpData.clock + nsSettingsStatus.extendedPumpSettings("warnClock") * 60 * 1000L < now)
level = Levels.WARN;
else if (deviceStatusPumpData.reservoir < NSSettingsStatus.getInstance().extendedPumpSettings("warnRes"))
else if (deviceStatusPumpData.reservoir < nsSettingsStatus.extendedPumpSettings("warnRes"))
level = Levels.WARN;
else if (deviceStatusPumpData.isPercent && deviceStatusPumpData.percent < NSSettingsStatus.getInstance().extendedPumpSettings("warnBattP"))
else if (deviceStatusPumpData.isPercent && deviceStatusPumpData.percent < nsSettingsStatus.extendedPumpSettings("warnBattP"))
level = Levels.WARN;
else if (!deviceStatusPumpData.isPercent && deviceStatusPumpData.voltage < NSSettingsStatus.getInstance().extendedPumpSettings("warnBattV"))
else if (!deviceStatusPumpData.isPercent && deviceStatusPumpData.voltage < nsSettingsStatus.extendedPumpSettings("warnBattV"))
level = Levels.WARN;
string.append("<span style=\"color:");
@ -205,7 +196,7 @@ public class NSDeviceStatus {
if (level == Levels.WARN) string.append("yellow\">");
if (level == Levels.URGENT) string.append("red\">");
String fields = NSSettingsStatus.getInstance().pumpExtentendedSettingsFields();
String fields = nsSettingsStatus.pumpExtendedSettingsFields();
if (fields.contains("reservoir")) {
string.append((int) deviceStatusPumpData.reservoir).append("U ");
@ -248,7 +239,7 @@ public class NSDeviceStatus {
Spanned extended = null;
}
public void updatePumpData(JSONObject object) {
private void updatePumpData() {
try {
JSONObject pump = data != null && data.has("pump") ? data.getJSONObject("pump") : new JSONObject();
@ -284,7 +275,7 @@ public class NSDeviceStatus {
deviceStatusPumpData.extended = Html.fromHtml(exteneded.toString());
}
} catch (Exception e) {
log.error("Unhandled exception", e);
aapsLogger.error("Unhandled exception", e);
}
}
@ -301,7 +292,7 @@ public class NSDeviceStatus {
public JSONObject enacted = null;
}
public void updateOpenApsData(JSONObject object) {
private void updateOpenApsData(JSONObject object) {
try {
JSONObject openaps = object.has("openaps") ? object.getJSONObject("openaps") : new JSONObject();
JSONObject suggested = openaps.has("suggested") ? openaps.getJSONObject("suggested") : new JSONObject();
@ -325,22 +316,22 @@ public class NSDeviceStatus {
deviceStatusOpenAPSData.clockEnacted = clock;
}
} catch (Exception e) {
log.error("Unhandled exception", e);
aapsLogger.error("Unhandled exception", e);
}
}
public Spanned getOpenApsStatus() {
StringBuilder string = new StringBuilder();
string.append("<span style=\"color:" + MainApp.gs(R.color.defaulttext).replace("#ff", "#") + "\">");
string.append(MainApp.gs(R.string.openaps_short));
string.append("<span style=\"color:" + resourceHelper.gcs(R.color.defaulttext) + "\">");
string.append(resourceHelper.gs(R.string.openaps_short));
string.append(": </span>");
// test warning level
int level = Levels.INFO;
long now = System.currentTimeMillis();
if (deviceStatusOpenAPSData.clockSuggested != 0 && deviceStatusOpenAPSData.clockSuggested + SP.getInt(R.string.key_nsalarm_urgent_staledatavalue, 16) * 60 * 1000L < now)
if (deviceStatusOpenAPSData.clockSuggested != 0 && deviceStatusOpenAPSData.clockSuggested + sp.getInt(R.string.key_nsalarm_urgent_staledatavalue, 16) * 60 * 1000L < now)
level = Levels.URGENT;
else if (deviceStatusOpenAPSData.clockSuggested != 0 && deviceStatusOpenAPSData.clockSuggested + SP.getInt(R.string.key_nsalarm_staledatavalue, 16) * 60 * 1000L < now)
else if (deviceStatusOpenAPSData.clockSuggested != 0 && deviceStatusOpenAPSData.clockSuggested + sp.getInt(R.string.key_nsalarm_staledatavalue, 16) * 60 * 1000L < now)
level = Levels.WARN;
string.append("<span style=\"color:");
@ -375,21 +366,21 @@ public class NSDeviceStatus {
string.append("<b>").append(DateUtil.minAgo(deviceStatusOpenAPSData.clockSuggested)).append("</b> ").append(deviceStatusOpenAPSData.suggested.getString("reason")).append("<br>");
return Html.fromHtml(string.toString());
} catch (JSONException e) {
log.error("Unhandled exception", e);
aapsLogger.error("Unhandled exception", e);
}
return Html.fromHtml("");
}
// ********* Uploader data ***********
public static HashMap<String, Uploader> uploaders = new HashMap<>();
private static HashMap<String, Uploader> uploaders = new HashMap<>();
static class Uploader {
long clock = 0L;
int battery = 0;
}
public void updateUploaderData(JSONObject object) {
private void updateUploaderData(JSONObject object) {
try {
long clock = 0L;
@ -407,7 +398,7 @@ public class NSDeviceStatus {
}
Uploader uploader = uploaders.get(device);
// check if this is new data
if (clock != 0 && battery != null && (uploader != null && clock > uploader.clock || uploader == null)) {
if (clock != 0 && battery != null && (uploader == null || clock > uploader.clock)) {
if (uploader == null)
uploader = new Uploader();
uploader.battery = battery;
@ -415,7 +406,7 @@ public class NSDeviceStatus {
uploaders.put(device, uploader);
}
} catch (Exception e) {
log.error("Unhandled exception", e);
aapsLogger.error("Unhandled exception", e);
}
}
@ -434,8 +425,8 @@ public class NSDeviceStatus {
public Spanned getUploaderStatusSpanned() {
StringBuilder string = new StringBuilder();
string.append("<span style=\"color:" + MainApp.gs(R.color.defaulttext).replace("#ff", "#") + "\">");
string.append(MainApp.gs(R.string.uploader_short));
string.append("<span style=\"color:" + resourceHelper.gcs(R.color.defaulttext) + "\">");
string.append(resourceHelper.gs(R.string.uploader_short));
string.append(": </span>");
Iterator iter = uploaders.entrySet().iterator();

View file

@ -1,446 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.data;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import androidx.annotation.Nullable;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import java.util.Objects;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.logging.BundleLogger;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin;
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
/*
{
"status": "ok",
"name": "Nightscout",
"version": "0.10.0-dev-20170423",
"versionNum": 1000,
"serverTime": "2017-06-12T07:46:56.006Z",
"apiEnabled": true,
"careportalEnabled": true,
"boluscalcEnabled": true,
"head": "96ee154",
"settings": {
"units": "mmol",
"timeFormat": 24,
"nightMode": false,
"editMode": true,
"showRawbg": "always",
"customTitle": "Bara's CGM",
"theme": "colors",
"alarmUrgentHigh": true,
"alarmUrgentHighMins": [30, 60, 90, 120],
"alarmHigh": true,
"alarmHighMins": [30, 60, 90, 120],
"alarmLow": true,
"alarmLowMins": [15, 30, 45, 60],
"alarmUrgentLow": true,
"alarmUrgentLowMins": [15, 30, 45],
"alarmUrgentMins": [30, 60, 90, 120],
"alarmWarnMins": [30, 60, 90, 120],
"alarmTimeagoWarn": true,
"alarmTimeagoWarnMins": 15,
"alarmTimeagoUrgent": true,
"alarmTimeagoUrgentMins": 30,
"language": "cs",
"scaleY": "linear",
"showPlugins": "careportal boluscalc food bwp cage sage iage iob cob basal ar2 delta direction upbat rawbg",
"showForecast": "ar2",
"focusHours": 3,
"heartbeat": 60,
"baseURL": "http:\/\/barascgm.sysop.cz:82",
"authDefaultRoles": "readable",
"thresholds": {
"bgHigh": 252,
"bgTargetTop": 180,
"bgTargetBottom": 72,
"bgLow": 71
},
"DEFAULT_FEATURES": ["bgnow", "delta", "direction", "timeago", "devicestatus", "upbat", "errorcodes", "profile"],
"alarmTypes": ["predict"],
"enable": ["careportal", "boluscalc", "food", "bwp", "cage", "sage", "iage", "iob", "cob", "basal", "ar2", "rawbg", "pushover", "bgi", "pump", "openaps", "pushover", "treatmentnotify", "bgnow", "delta", "direction", "timeago", "devicestatus", "upbat", "profile", "ar2"]
},
"extendedSettings": {
"pump": {
"fields": "reservoir battery clock",
"urgentBattP": 26,
"warnBattP": 51
},
"openaps": {
"enableAlerts": true
},
"cage": {
"alerts": true,
"display": "days",
"urgent": 96,
"warn": 72
},
"sage": {
"alerts": true,
"urgent": 336,
"warn": 168
},
"iage": {
"alerts": true,
"urgent": 150,
"warn": 120
},
"basal": {
"render": "default"
},
"profile": {
"history": true,
"multiple": true
},
"devicestatus": {
"advanced": true
}
},
"activeProfile": "2016 +30%"
}
*/
public class NSSettingsStatus {
private Logger log = LoggerFactory.getLogger(L.NSCLIENT);
private static NSSettingsStatus instance = null;
public static NSSettingsStatus getInstance() {
if (instance == null)
instance = new NSSettingsStatus();
return instance;
}
public String nightscoutVersionName = "";
private JSONObject data = null;
public NSSettingsStatus() {
}
public NSSettingsStatus setData(JSONObject obj) {
this.data = obj;
return this;
}
public void handleNewData(Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle == null) return;
if (L.isEnabled(L.NSCLIENT))
log.debug("Got NS status: " + BundleLogger.log(bundle));
if (bundle.containsKey("nsclientversioncode")) {
Integer nightscoutVersionCode = bundle.getInt("nightscoutversioncode");
nightscoutVersionName = bundle.getString("nightscoutversionname");
Integer nsClientVersionCode = bundle.getInt("nsclientversioncode");
String nsClientVersionName = bundle.getString("nsclientversionname");
if (L.isEnabled(L.NSCLIENT))
log.debug("Got versions: NSClient: " + nsClientVersionName + " Nightscout: " + nightscoutVersionName);
try {
if (nsClientVersionCode < MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), 0).versionCode) {
Notification notification = new Notification(Notification.OLD_NSCLIENT, MainApp.gs(R.string.unsupportedclientver), Notification.URGENT);
RxBus.Companion.getINSTANCE().send(new EventNewNotification(notification));
} else {
RxBus.Companion.getINSTANCE().send(new EventDismissNotification(Notification.OLD_NSCLIENT));
}
} catch (PackageManager.NameNotFoundException e) {
log.error("Unhandled exception", e);
}
if (nightscoutVersionCode < Config.SUPPORTEDNSVERSION) {
Notification notification = new Notification(Notification.OLD_NS, MainApp.gs(R.string.unsupportednsversion), Notification.NORMAL);
RxBus.Companion.getINSTANCE().send(new EventNewNotification(notification));
} else {
RxBus.Companion.getINSTANCE().send(new EventDismissNotification(Notification.OLD_NS));
}
} else {
Notification notification = new Notification(Notification.OLD_NSCLIENT, MainApp.gs(R.string.unsupportedclientver), Notification.URGENT);
RxBus.Companion.getINSTANCE().send(new EventNewNotification(notification));
}
if (bundle.containsKey("status")) {
try {
JSONObject statusJson = new JSONObject(bundle.getString("status"));
setData(statusJson);
if (L.isEnabled(L.NSCLIENT))
log.debug("Received status: " + statusJson.toString());
Double targetHigh = getThreshold("bgTargetTop");
Double targetlow = getThreshold("bgTargetBottom");
if (targetHigh != null)
OverviewPlugin.INSTANCE.setBgTargetHigh(targetHigh);
if (targetlow != null)
OverviewPlugin.INSTANCE.setBgTargetLow(targetlow);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
}
public String getName() {
return getStringOrNull("name");
}
public String getVersion() {
return getStringOrNull("version");
}
public Integer getVersionNum() {
return getIntegerOrNull("versionNum");
}
public Date getServerTime() {
return getDateOrNull("serverTime");
}
public boolean getApiEnabled() {
return getBooleanOrNull("apiEnabled");
}
public boolean getCareportalEnabled() {
return getBooleanOrNull("careportalEnabled");
}
public boolean getBoluscalcEnabled() {
return getBooleanOrNull("boluscalcEnabled");
}
public String getHead() {
return getStringOrNull("head");
}
public String getSettings() {
return getStringOrNull("settings");
}
public JSONObject getExtendedSettings() {
try {
String extended = getStringOrNull("extendedSettings");
if (extended != null)
return new JSONObject(extended);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return null;
}
// valid property is "warn" or "urgent"
// plugings "iage" "sage" "cage" "pbage"
public double getExtendedWarnValue(String plugin, String property, double defaultvalue) {
JSONObject extendedSettings = this.getExtendedSettings();
if (extendedSettings == null)
return defaultvalue;
JSONObject pluginJson = extendedSettings.optJSONObject(plugin);
if (pluginJson == null)
return defaultvalue;
return pluginJson.optDouble(property, defaultvalue);
}
public String getActiveProfile() {
return getStringOrNull("activeProfile");
}
// "bgHigh": 252,
// "bgTargetTop": 180,
// "bgTargetBottom": 72,
// "bgLow": 71
@Nullable
public Double getThreshold(String what) {
try {
if (data == null)
return null;
String settings = getSettings();
if (settings != null) {
JSONObject settingsO = new JSONObject(settings);
if (settingsO.has("thresholds")) {
JSONObject tObject = settingsO.getJSONObject("thresholds");
if (tObject.has(what)) {
return tObject.getDouble(what);
}
}
if (settingsO.has("alarmTimeagoWarnMins") && Objects.equals(what, "alarmTimeagoWarnMins")) {
return settingsO.getDouble(what);
}
}
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return null;
}
private String getStringOrNull(String key) {
String ret = null;
if (data == null) return null;
if (data.has(key)) {
try {
ret = data.getString(key);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
return ret;
}
private Integer getIntegerOrNull(String key) {
Integer ret = null;
if (data.has(key)) {
try {
ret = data.getInt(key);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
return ret;
}
private Long getLongOrNull(String key) {
Long ret = null;
if (data.has(key)) {
try {
ret = data.getLong(key);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
return ret;
}
private Date getDateOrNull(String key) {
Date ret = null;
if (data.has(key)) {
try {
ret = new Date(data.getString(key));
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
return ret;
}
private boolean getBooleanOrNull(String key) {
boolean ret = false;
if (data.has(key)) {
try {
ret = data.getBoolean(key);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
return ret;
}
// ***** PUMP STATUS ******
public JSONObject getData() {
return data;
}
/*
, warnClock: sbx.extendedSettings.warnClock || 30
, urgentClock: sbx.extendedSettings.urgentClock || 60
, warnRes: sbx.extendedSettings.warnRes || 10
, urgentRes: sbx.extendedSettings.urgentRes || 5
, warnBattV: sbx.extendedSettings.warnBattV || 1.35
, urgentBattV: sbx.extendedSettings.urgentBattV || 1.3
, warnBattP: sbx.extendedSettings.warnBattP || 30
, urgentBattP: sbx.extendedSettings.urgentBattP || 20
, enableAlerts: sbx.extendedSettings.enableAlerts || false
*/
public double extendedPumpSettings(String setting) {
try {
JSONObject pump = extentendedPumpSettings();
switch (setting) {
case "warnClock":
return pump != null && pump.has(setting) ? pump.getDouble(setting) : 30;
case "urgentClock":
return pump != null && pump.has(setting) ? pump.getDouble(setting) : 30;
case "warnRes":
return pump != null && pump.has(setting) ? pump.getDouble(setting) : 30;
case "urgentRes":
return pump != null && pump.has(setting) ? pump.getDouble(setting) : 30;
case "warnBattV":
return pump != null && pump.has(setting) ? pump.getDouble(setting) : 30;
case "urgentBattV":
return pump != null && pump.has(setting) ? pump.getDouble(setting) : 30;
case "warnBattP":
return pump != null && pump.has(setting) ? pump.getDouble(setting) : 30;
case "urgentBattP":
return pump != null && pump.has(setting) ? pump.getDouble(setting) : 30;
}
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return 0d;
}
@Nullable
public JSONObject extentendedPumpSettings() {
try {
JSONObject extended = getExtendedSettings();
if (extended == null) return null;
if (extended.has("pump")) {
JSONObject pump = extended.getJSONObject("pump");
return pump;
}
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return null;
}
public boolean pumpExtentendedSettingsEnabledAlerts() {
try {
JSONObject pump = extentendedPumpSettings();
if (pump != null && pump.has("enableAlerts")) {
return pump.getBoolean("enableAlerts");
}
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return false;
}
public String pumpExtentendedSettingsFields() {
try {
JSONObject pump = extentendedPumpSettings();
if (pump != null && pump.has("fields")) {
return pump.getString("fields");
}
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return "";
}
public boolean openAPSEnabledAlerts() {
try {
JSONObject pump = extentendedPumpSettings();
if (pump != null && pump.has("openaps")) {
return pump.getBoolean("enableAlerts");
}
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return false;
}
}

View file

@ -0,0 +1,214 @@
package info.nightscout.androidaps.plugins.general.nsclient.data
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.R
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.overview.events.EventDismissNotification
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.utils.DefaultValueHelper
import info.nightscout.androidaps.utils.JsonHelper
import info.nightscout.androidaps.utils.resources.ResourceHelper
import org.json.JSONException
import org.json.JSONObject
import javax.inject.Inject
import javax.inject.Singleton
/*
{
"status": "ok",
"name": "Nightscout",
"version": "0.10.0-dev-20170423",
"versionNum": 1000,
"serverTime": "2017-06-12T07:46:56.006Z",
"apiEnabled": true,
"careportalEnabled": true,
"boluscalcEnabled": true,
"head": "96ee154",
"settings": {
"units": "mmol",
"timeFormat": 24,
"nightMode": false,
"editMode": true,
"showRawbg": "always",
"customTitle": "Bara's CGM",
"theme": "colors",
"alarmUrgentHigh": true,
"alarmUrgentHighMins": [30, 60, 90, 120],
"alarmHigh": true,
"alarmHighMins": [30, 60, 90, 120],
"alarmLow": true,
"alarmLowMins": [15, 30, 45, 60],
"alarmUrgentLow": true,
"alarmUrgentLowMins": [15, 30, 45],
"alarmUrgentMins": [30, 60, 90, 120],
"alarmWarnMins": [30, 60, 90, 120],
"alarmTimeagoWarn": true,
"alarmTimeagoWarnMins": 15,
"alarmTimeagoUrgent": true,
"alarmTimeagoUrgentMins": 30,
"language": "cs",
"scaleY": "linear",
"showPlugins": "careportal boluscalc food bwp cage sage iage iob cob basal ar2 delta direction upbat rawbg",
"showForecast": "ar2",
"focusHours": 3,
"heartbeat": 60,
"baseURL": "http:\/\/barascgm.sysop.cz:82",
"authDefaultRoles": "readable",
"thresholds": {
"bgHigh": 252,
"bgTargetTop": 180,
"bgTargetBottom": 72,
"bgLow": 71
},
"DEFAULT_FEATURES": ["bgnow", "delta", "direction", "timeago", "devicestatus", "upbat", "errorcodes", "profile"],
"alarmTypes": ["predict"],
"enable": ["careportal", "boluscalc", "food", "bwp", "cage", "sage", "iage", "iob", "cob", "basal", "ar2", "rawbg", "pushover", "bgi", "pump", "openaps", "pushover", "treatmentnotify", "bgnow", "delta", "direction", "timeago", "devicestatus", "upbat", "profile", "ar2"]
},
"extendedSettings": {
"pump": {
"fields": "reservoir battery clock",
"urgentBattP": 26,
"warnBattP": 51
},
"openaps": {
"enableAlerts": true
},
"cage": {
"alerts": true,
"display": "days",
"urgent": 96,
"warn": 72
},
"sage": {
"alerts": true,
"urgent": 336,
"warn": 168
},
"iage": {
"alerts": true,
"urgent": 150,
"warn": 120
},
"basal": {
"render": "default"
},
"profile": {
"history": true,
"multiple": true
},
"devicestatus": {
"advanced": true
}
},
"activeProfile": "2016 +30%"
}
*/
@Singleton
class NSSettingsStatus @Inject constructor(
private val aapsLogger: AAPSLogger,
private val resourceHelper: ResourceHelper,
private val rxBus: RxBusWrapper,
private val defaultValueHelper: DefaultValueHelper
) {
var nightscoutVersionName = ""
// ***** PUMP STATUS ******
var data: JSONObject? = null
fun handleNewData(nightscoutVersionName: String, nightscoutVersionCode: Int, status: JSONObject) {
this.nightscoutVersionName = nightscoutVersionName
aapsLogger.debug(LTag.NSCLIENT, "Got versions: Nightscout: $nightscoutVersionName")
if (nightscoutVersionCode < Config.SUPPORTEDNSVERSION) {
val notification = Notification(Notification.OLD_NS, resourceHelper.gs(R.string.unsupportednsversion), Notification.NORMAL)
rxBus.send(EventNewNotification(notification))
} else {
rxBus.send(EventDismissNotification(Notification.OLD_NS))
}
data = status
aapsLogger.debug(LTag.NSCLIENT, "Received status: $status")
val targetHigh = getSettingsThreshold("bgTargetTop")
val targetlow = getSettingsThreshold("bgTargetBottom")
if (targetHigh != null) defaultValueHelper.bgTargetHigh = targetHigh
if (targetlow != null) defaultValueHelper.bgTargetLow = targetlow
}
fun getName(): String? =
JsonHelper.safeGetStringAllowNull(data, "name", null)
fun getVersion(): String? =
JsonHelper.safeGetStringAllowNull(data, "version", null)
fun getVersionNum(): Int =
JsonHelper.safeGetInt(data, "versionNum")
private fun getSettings() =
JsonHelper.safeGetJSONObject(data, "settings", null)
private fun getExtendedSettings(): JSONObject? =
JsonHelper.safeGetJSONObject(data, "extendedSettings", null)
// valid property is "warn" or "urgent"
// plugings "iage" "sage" "cage" "pbage"
fun getExtendedWarnValue(plugin: String, property: String, defaultValue: Double): Double {
val extendedSettings = getExtendedSettings() ?: return defaultValue
val pluginJson = extendedSettings.optJSONObject(plugin) ?: return defaultValue
return pluginJson.optDouble(property, defaultValue)
}
// "bgHigh": 252,
// "bgTargetTop": 180,
// "bgTargetBottom": 72,
// "bgLow": 71
fun getSettingsThreshold(what: String): Double? {
val threshold = JsonHelper.safeGetJSONObject(getSettings(), "thresholds", null)
return JsonHelper.safeGetDoubleAllowNull(threshold, what)
}
/*
, warnClock: sbx.extendedSettings.warnClock || 30
, urgentClock: sbx.extendedSettings.urgentClock || 60
, warnRes: sbx.extendedSettings.warnRes || 10
, urgentRes: sbx.extendedSettings.urgentRes || 5
, warnBattV: sbx.extendedSettings.warnBattV || 1.35
, urgentBattV: sbx.extendedSettings.urgentBattV || 1.3
, warnBattP: sbx.extendedSettings.warnBattP || 30
, urgentBattP: sbx.extendedSettings.urgentBattP || 20
, enableAlerts: sbx.extendedSettings.enableAlerts || false
*/
fun extendedPumpSettings(setting: String?): Double {
try {
val pump = extendedPumpSettings()
return when (setting) {
"warnClock" -> JsonHelper.safeGetDouble(pump, setting, 30.0)
"urgentClock" -> JsonHelper.safeGetDouble(pump, setting, 60.0)
"warnRes" -> JsonHelper.safeGetDouble(pump, setting, 10.0)
"urgentRes" -> JsonHelper.safeGetDouble(pump, setting, 5.0)
"warnBattV" -> JsonHelper.safeGetDouble(pump, setting, 1.35)
"urgentBattV" -> JsonHelper.safeGetDouble(pump, setting, 1.3)
"warnBattP" -> JsonHelper.safeGetDouble(pump, setting, 30.0)
"urgentBattP" -> JsonHelper.safeGetDouble(pump, setting, 20.0)
else -> 0.0
}
} catch (e: JSONException) {
aapsLogger.error("Unhandled exception", e)
}
return 0.0
}
private fun extendedPumpSettings(): JSONObject? =
JsonHelper.safeGetJSONObject(getExtendedSettings(), "pump", null)
fun pumpExtendedSettingsEnabledAlerts(): Boolean =
JsonHelper.safeGetBoolean(extendedPumpSettings(), "enableAlerts")
fun pumpExtendedSettingsFields(): String =
JsonHelper.safeGetString(extendedPumpSettings(), "fields", "")
fun openAPSEnabledAlerts(): Boolean {
val openaps = JsonHelper.safeGetJSONObject(getExtendedSettings(), "openaps", null)
return JsonHelper.safeGetBoolean(openaps, "enableAlerts")
}
}

View file

@ -1,15 +1,17 @@
package info.nightscout.androidaps.plugins.general.nsclient.services;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.SystemClock;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.google.common.base.Charsets;
import com.google.common.hash.Hashing;
import com.j256.ormlite.dao.CloseableIterator;
@ -23,7 +25,11 @@ import org.slf4j.LoggerFactory;
import java.net.URISyntaxException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import dagger.android.DaggerService;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
@ -31,28 +37,21 @@ import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.db.DbRequest;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventConfigBuilderChange;
import info.nightscout.androidaps.events.EventNsFood;
import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin;
import info.nightscout.androidaps.plugins.general.nsclient.UploadQueue;
import info.nightscout.androidaps.plugins.general.nsclient.acks.NSAddAck;
import info.nightscout.androidaps.plugins.general.nsclient.acks.NSAuthAck;
import info.nightscout.androidaps.plugins.general.nsclient.acks.NSUpdateAck;
import info.nightscout.androidaps.plugins.general.nsclient.broadcasts.BroadcastAlarm;
import info.nightscout.androidaps.plugins.general.nsclient.broadcasts.BroadcastAnnouncement;
import info.nightscout.androidaps.plugins.general.nsclient.broadcasts.BroadcastCals;
import info.nightscout.androidaps.plugins.general.nsclient.broadcasts.BroadcastClearAlarm;
import info.nightscout.androidaps.plugins.general.nsclient.broadcasts.BroadcastDeviceStatus;
import info.nightscout.androidaps.plugins.general.nsclient.broadcasts.BroadcastFood;
import info.nightscout.androidaps.plugins.general.nsclient.broadcasts.BroadcastMbgs;
import info.nightscout.androidaps.plugins.general.nsclient.broadcasts.BroadcastProfile;
import info.nightscout.androidaps.plugins.general.nsclient.broadcasts.BroadcastSgvs;
import info.nightscout.androidaps.plugins.general.nsclient.broadcasts.BroadcastStatus;
import info.nightscout.androidaps.plugins.general.nsclient.broadcasts.BroadcastTreatment;
import info.nightscout.androidaps.plugins.general.nsclient.broadcasts.BroadcastUrgentAlarm;
import info.nightscout.androidaps.plugins.general.nsclient.data.AlarmAck;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSAlarm;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSgv;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSTreatment;
@ -63,18 +62,29 @@ import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientU
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction;
import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.JsonHelper;
import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.T;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;
public class NSClientService extends Service {
public class NSClientService extends DaggerService {
@Inject AAPSLogger aapsLogger;
@Inject NSSettingsStatus nsSettingsStatus;
@Inject NSDeviceStatus nsDeviceStatus;
@Inject MainApp mainApp;
@Inject RxBusWrapper rxBus;
@Inject ResourceHelper resourceHelper;
@Inject SP sp;
private static Logger log = LoggerFactory.getLogger(L.NSCLIENT);
private CompositeDisposable disposable = new CompositeDisposable();
@ -99,7 +109,7 @@ public class NSClientService extends Service {
static public String nsURL = "";
private String nsAPISecret = "";
private String nsDevice = "";
private Integer nsHours = 48;
private final Integer nsHours = 48;
public long lastResendTime = 0;
@ -109,28 +119,30 @@ public class NSClientService extends Service {
public static UploadQueue uploadQueue = new UploadQueue();
private ArrayList<Long> reconnections = new ArrayList<>();
private final ArrayList<Long> reconnections = new ArrayList<>();
private int WATCHDOG_INTERVAL_MINUTES = 2;
private int WATCHDOG_RECONNECT_IN = 15;
private int WATCHDOG_MAXCONNECTIONS = 5;
public NSClientService() {
super();
if (handler == null) {
HandlerThread handlerThread = new HandlerThread(NSClientService.class.getSimpleName() + "Handler");
handlerThread.start();
handler = new Handler(handlerThread.getLooper());
}
PowerManager powerManager = (PowerManager) MainApp.instance().getApplicationContext().getSystemService(Context.POWER_SERVICE);
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AndroidAPS:NSClientService");
initialize();
}
@Override
public void onCreate() {
super.onCreate();
PowerManager powerManager = (PowerManager) mainApp.getApplicationContext().getSystemService(Context.POWER_SERVICE);
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AndroidAPS:NSClientService");
mWakeLock.acquire();
disposable.add(RxBus.Companion.getINSTANCE()
initialize();
disposable.add(rxBus
.toObservable(EventConfigBuilderChange.class)
.observeOn(Schedulers.io())
.subscribe(event -> {
@ -141,7 +153,7 @@ public class NSClientService extends Service {
}
}, FabricPrivacy::logException)
);
disposable.add(RxBus.Companion.getINSTANCE()
disposable.add(rxBus
.toObservable(EventPreferenceChange.class)
.observeOn(Schedulers.io())
.subscribe(event -> {
@ -155,7 +167,7 @@ public class NSClientService extends Service {
}
}, FabricPrivacy::logException)
);
disposable.add(RxBus.Companion.getINSTANCE()
disposable.add(rxBus
.toObservable(EventAppExit.class)
.observeOn(Schedulers.io())
.subscribe(event -> {
@ -165,7 +177,7 @@ public class NSClientService extends Service {
stopSelf();
}, FabricPrivacy::logException)
);
disposable.add(RxBus.Companion.getINSTANCE()
disposable.add(rxBus
.toObservable(EventNSClientRestart.class)
.observeOn(Schedulers.io())
.subscribe(event -> {
@ -173,20 +185,20 @@ public class NSClientService extends Service {
restart();
}, FabricPrivacy::logException)
);
disposable.add(RxBus.Companion.getINSTANCE()
disposable.add(rxBus
.toObservable(NSAuthAck.class)
.observeOn(Schedulers.io())
.subscribe(event -> processAuthAck(event), FabricPrivacy::logException)
.subscribe(this::processAuthAck, FabricPrivacy::logException)
);
disposable.add(RxBus.Companion.getINSTANCE()
disposable.add(rxBus
.toObservable(NSUpdateAck.class)
.observeOn(Schedulers.io())
.subscribe(event -> processUpdateAck(event), FabricPrivacy::logException)
.subscribe(this::processUpdateAck, FabricPrivacy::logException)
);
disposable.add(RxBus.Companion.getINSTANCE()
disposable.add(rxBus
.toObservable(NSAddAck.class)
.observeOn(Schedulers.io())
.subscribe(event -> processAddAck(event), FabricPrivacy::logException)
.subscribe(this::processAddAck, FabricPrivacy::logException)
);
}
@ -200,18 +212,18 @@ public class NSClientService extends Service {
public void processAddAck(NSAddAck ack) {
if (ack.nsClientID != null) {
uploadQueue.removeID(ack.json);
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("DBADD", "Acked " + ack.nsClientID));
rxBus.send(new EventNSClientNewLog("DBADD", "Acked " + ack.nsClientID));
} else {
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("ERROR", "DBADD Unknown response"));
rxBus.send(new EventNSClientNewLog("ERROR", "DBADD Unknown response"));
}
}
public void processUpdateAck(NSUpdateAck ack) {
if (ack.result) {
uploadQueue.removeID(ack.action, ack._id);
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("DBUPDATE/DBREMOVE", "Acked " + ack._id));
rxBus.send(new EventNSClientNewLog("DBUPDATE/DBREMOVE", "Acked " + ack._id));
} else {
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("ERROR", "DBUPDATE/DBREMOVE Unknown response"));
rxBus.send(new EventNSClientNewLog("ERROR", "DBUPDATE/DBREMOVE Unknown response"));
}
}
@ -223,19 +235,19 @@ public class NSClientService extends Service {
connectionStatus += ')';
isConnected = true;
hasWriteAuth = ack.write && ack.write_treatment;
RxBus.Companion.getINSTANCE().send(new EventNSClientStatus(connectionStatus));
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("AUTH", connectionStatus));
rxBus.send(new EventNSClientStatus(connectionStatus));
rxBus.send(new EventNSClientNewLog("AUTH", connectionStatus));
if (!ack.write) {
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("ERROR", "Write permission not granted !!!!"));
rxBus.send(new EventNSClientNewLog("ERROR", "Write permission not granted !!!!"));
}
if (!ack.write_treatment) {
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("ERROR", "Write treatment permission not granted !!!!"));
rxBus.send(new EventNSClientNewLog("ERROR", "Write treatment permission not granted !!!!"));
}
if (!hasWriteAuth) {
Notification noperm = new Notification(Notification.NSCLIENT_NO_WRITE_PERMISSION, MainApp.gs(R.string.nowritepermission), Notification.URGENT);
RxBus.Companion.getINSTANCE().send(new EventNewNotification(noperm));
Notification noperm = new Notification(Notification.NSCLIENT_NO_WRITE_PERMISSION, resourceHelper.gs(R.string.nowritepermission), Notification.URGENT);
rxBus.send(new EventNewNotification(noperm));
} else {
RxBus.Companion.getINSTANCE().send(new EventDismissNotification(Notification.NSCLIENT_NO_WRITE_PERMISSION));
rxBus.send(new EventDismissNotification(Notification.NSCLIENT_NO_WRITE_PERMISSION));
}
}
@ -264,19 +276,19 @@ public class NSClientService extends Service {
if (!nsAPISecret.equals(""))
nsAPIhashCode = Hashing.sha1().hashString(nsAPISecret, Charsets.UTF_8).toString();
RxBus.Companion.getINSTANCE().send(new EventNSClientStatus("Initializing"));
rxBus.send(new EventNSClientStatus("Initializing"));
if (!NSClientPlugin.getPlugin().isAllowed()) {
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("NSCLIENT", "not allowed"));
RxBus.Companion.getINSTANCE().send(new EventNSClientStatus("Not allowed"));
rxBus.send(new EventNSClientNewLog("NSCLIENT", "not allowed"));
rxBus.send(new EventNSClientStatus("Not allowed"));
} else if (NSClientPlugin.getPlugin().paused) {
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("NSCLIENT", "paused"));
RxBus.Companion.getINSTANCE().send(new EventNSClientStatus("Paused"));
rxBus.send(new EventNSClientNewLog("NSCLIENT", "paused"));
rxBus.send(new EventNSClientStatus("Paused"));
} else if (!nsEnabled) {
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("NSCLIENT", "disabled"));
RxBus.Companion.getINSTANCE().send(new EventNSClientStatus("Disabled"));
rxBus.send(new EventNSClientNewLog("NSCLIENT", "disabled"));
rxBus.send(new EventNSClientStatus("Disabled"));
} else if (!nsURL.equals("")) {
try {
RxBus.Companion.getINSTANCE().send(new EventNSClientStatus("Connecting ..."));
rxBus.send(new EventNSClientStatus("Connecting ..."));
IO.Options opt = new IO.Options();
opt.forceNew = true;
opt.reconnection = true;
@ -284,7 +296,7 @@ public class NSClientService extends Service {
mSocket.on(Socket.EVENT_CONNECT, onConnect);
mSocket.on(Socket.EVENT_DISCONNECT, onDisconnect);
mSocket.on(Socket.EVENT_PING, onPing);
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("NSCLIENT", "do connect"));
rxBus.send(new EventNSClientNewLog("NSCLIENT", "do connect"));
mSocket.connect();
mSocket.on("dataUpdate", onDataUpdate);
mSocket.on("announcement", onAnnouncement);
@ -292,12 +304,12 @@ public class NSClientService extends Service {
mSocket.on("urgent_alarm", onUrgentAlarm);
mSocket.on("clear_alarm", onClearAlarm);
} catch (URISyntaxException | RuntimeException e) {
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("NSCLIENT", "Wrong URL syntax"));
RxBus.Companion.getINSTANCE().send(new EventNSClientStatus("Wrong URL syntax"));
rxBus.send(new EventNSClientNewLog("NSCLIENT", "Wrong URL syntax"));
rxBus.send(new EventNSClientStatus("Wrong URL syntax"));
}
} else {
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("NSCLIENT", "No NS URL specified"));
RxBus.Companion.getINSTANCE().send(new EventNSClientStatus("Not configured"));
rxBus.send(new EventNSClientNewLog("NSCLIENT", "No NS URL specified"));
rxBus.send(new EventNSClientStatus("Not configured"));
}
}
@ -306,7 +318,7 @@ public class NSClientService extends Service {
public void call(Object... args) {
connectCounter++;
String socketId = mSocket != null ? mSocket.id() : "NULL";
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("NSCLIENT", "connect #" + connectCounter + " event. ID: " + socketId));
rxBus.send(new EventNSClientNewLog("NSCLIENT", "connect #" + connectCounter + " event. ID: " + socketId));
if (mSocket != null)
sendAuthMessage(new NSAuthAck());
watchdog();
@ -323,16 +335,16 @@ public class NSClientService extends Service {
reconnections.remove(r);
}
}
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("WATCHDOG", "connections in last " + WATCHDOG_INTERVAL_MINUTES + " mins: " + reconnections.size() + "/" + WATCHDOG_MAXCONNECTIONS));
rxBus.send(new EventNSClientNewLog("WATCHDOG", "connections in last " + WATCHDOG_INTERVAL_MINUTES + " mins: " + reconnections.size() + "/" + WATCHDOG_MAXCONNECTIONS));
if (reconnections.size() >= WATCHDOG_MAXCONNECTIONS) {
Notification n = new Notification(Notification.NSMALFUNCTION, MainApp.gs(R.string.nsmalfunction), Notification.URGENT);
RxBus.Companion.getINSTANCE().send(new EventNewNotification(n));
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("WATCHDOG", "pausing for " + WATCHDOG_RECONNECT_IN + " mins"));
Notification n = new Notification(Notification.NSMALFUNCTION, resourceHelper.gs(R.string.nsmalfunction), Notification.URGENT);
rxBus.send(new EventNewNotification(n));
rxBus.send(new EventNSClientNewLog("WATCHDOG", "pausing for " + WATCHDOG_RECONNECT_IN + " mins"));
NSClientPlugin.getPlugin().pause(true);
RxBus.Companion.getINSTANCE().send(new EventNSClientUpdateGUI());
rxBus.send(new EventNSClientUpdateGUI());
new Thread(() -> {
SystemClock.sleep(T.mins(WATCHDOG_RECONNECT_IN).msecs());
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("WATCHDOG", "reenabling NSClient"));
rxBus.send(new EventNSClientNewLog("WATCHDOG", "reenabling NSClient"));
NSClientPlugin.getPlugin().pause(false);
}).start();
}
@ -344,7 +356,7 @@ public class NSClientService extends Service {
public void call(Object... args) {
if (L.isEnabled(L.NSCLIENT))
log.debug("disconnect reason: {}", args);
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("NSCLIENT", "disconnect event"));
rxBus.send(new EventNSClientNewLog("NSCLIENT", "disconnect event"));
}
};
@ -359,7 +371,7 @@ public class NSClientService extends Service {
mSocket.off("urgent_alarm");
mSocket.off("clear_alarm");
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("NSCLIENT", "destroy"));
rxBus.send(new EventNSClientNewLog("NSCLIENT", "destroy"));
isConnected = false;
hasWriteAuth = false;
mSocket.disconnect();
@ -380,22 +392,22 @@ public class NSClientService extends Service {
log.error("Unhandled exception", e);
return;
}
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("AUTH", "requesting auth"));
rxBus.send(new EventNSClientNewLog("AUTH", "requesting auth"));
if (mSocket != null)
mSocket.emit("authorize", authMessage, ack);
}
public void readPreferences() {
nsEnabled = NSClientPlugin.getPlugin().isEnabled(PluginType.GENERAL);
nsURL = SP.getString(R.string.key_nsclientinternal_url, "");
nsAPISecret = SP.getString(R.string.key_nsclientinternal_api_secret, "");
nsDevice = SP.getString("careportal_enteredby", "");
nsURL = sp.getString(R.string.key_nsclientinternal_url, "");
nsAPISecret = sp.getString(R.string.key_nsclientinternal_api_secret, "");
nsDevice = sp.getString("careportal_enteredby", "");
}
private Emitter.Listener onPing = new Emitter.Listener() {
@Override
public void call(final Object... args) {
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("PING", "received"));
rxBus.send(new EventNSClientNewLog("PING", "received"));
// send data if there is something waiting
resend("Ping received");
}
@ -418,20 +430,11 @@ public class NSClientService extends Service {
JSONObject data;
try {
data = (JSONObject) args[0];
handleAnnouncement(data);
} catch (Exception e) {
FabricPrivacy.log("Wrong Announcement from NS: " + args[0]);
log.error("Unhandled exception", e);
return;
}
try {
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("ANNOUNCEMENT", JsonHelper.safeGetString(data, "message", "received")));
} catch (Exception e) {
FabricPrivacy.logException(e);
log.error("Unhandled exception", e);
}
BroadcastAnnouncement.handleAnnouncement(data, getApplicationContext());
if (L.isEnabled(L.NSCLIENT))
log.debug(data.toString());
}
};
@ -451,49 +454,24 @@ public class NSClientService extends Service {
*/
@Override
public void call(final Object... args) {
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("ALARM", "received"));
JSONObject data;
try {
data = (JSONObject) args[0];
handleAlarm(data);
} catch (Exception e) {
FabricPrivacy.log("Wrong alarm from NS: " + args[0]);
log.error("Unhandled exception", e);
return;
}
BroadcastAlarm.handleAlarm(data, getApplicationContext());
if (L.isEnabled(L.NSCLIENT))
log.debug(data.toString());
}
};
private Emitter.Listener onUrgentAlarm = new Emitter.Listener() {
/*
{
"level":2,
"title":"Urgent HIGH",
"message":"BG Now: 5.2 -0.1 → mmol\/L\nRaw BG: 5 mmol\/L Čistý\nBG 15m: 5 mmol\/L\nIOB: 0.00U\nCOB: 0g",
"eventName":"high",
"plugin":{"name":"simplealarms","label":"Simple Alarms","pluginType":"notification","enabled":true},
"pushoverSound":"persistent",
"debug":{"lastSGV":5.2,"thresholds":{"bgHigh":80,"bgTargetTop":75,"bgTargetBottom":72,"bgLow":70}},
"group":"default",
"key":"simplealarms_2"
}
*/
@Override
public void call(final Object... args) {
private Emitter.Listener onUrgentAlarm = args -> {
JSONObject data;
try {
data = (JSONObject) args[0];
handleUrgentAlarm(data);
} catch (Exception e) {
FabricPrivacy.log("Wrong Urgent alarm from NS: " + args[0]);
log.error("Unhandled exception", e);
return;
}
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("URGENTALARM", "received"));
BroadcastUrgentAlarm.handleUrgentAlarm(data, getApplicationContext());
if (L.isEnabled(L.NSCLIENT))
log.debug(data.toString());
}
};
@ -511,25 +489,22 @@ public class NSClientService extends Service {
JSONObject data;
try {
data = (JSONObject) args[0];
rxBus.send(new EventNSClientNewLog("CLEARALARM", "received"));
rxBus.send(new EventDismissNotification(Notification.NSALARM));
rxBus.send(new EventDismissNotification(Notification.NSURGENTALARM));
aapsLogger.debug(LTag.NSCLIENT, data.toString());
} catch (Exception e) {
FabricPrivacy.log("Wrong Urgent alarm from NS: " + args[0]);
log.error("Unhandled exception", e);
return;
}
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("CLEARALARM", "received"));
BroadcastClearAlarm.handleClearAlarm(data, getApplicationContext());
if (L.isEnabled(L.NSCLIENT))
log.debug(data.toString());
}
};
private Emitter.Listener onDataUpdate = new Emitter.Listener() {
@Override
public void call(final Object... args) {
NSClientService.handler.post(new Runnable() {
@Override
public void run() {
PowerManager powerManager = (PowerManager) MainApp.instance().getApplicationContext().getSystemService(Context.POWER_SERVICE);
NSClientService.handler.post(() -> {
PowerManager powerManager = (PowerManager) mainApp.getApplicationContext().getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"AndroidAPS:NSClientService_onDataUpdate");
wakeLock.acquire();
@ -541,7 +516,7 @@ public class NSClientService extends Service {
// delta means only increment/changes are comming
boolean isDelta = data.has("delta");
boolean isFull = !isDelta;
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("DATA", "Data packet #" + dataCounter++ + (isDelta ? " delta" : " full")));
rxBus.send(new EventNSClientNewLog("DATA", "Data packet #" + dataCounter++ + (isDelta ? " delta" : " full")));
if (data.has("profiles")) {
JSONArray profiles = data.getJSONArray("profiles");
@ -549,23 +524,23 @@ public class NSClientService extends Service {
JSONObject profile = (JSONObject) profiles.get(profiles.length() - 1);
profileStore = new ProfileStore(profile);
broadcastProfile = true;
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("PROFILE", "profile received"));
rxBus.send(new EventNSClientNewLog("PROFILE", "profile received"));
}
}
if (data.has("status")) {
JSONObject status = data.getJSONObject("status");
NSSettingsStatus nsSettingsStatus = NSSettingsStatus.getInstance().setData(status);
nsSettingsStatus.setData(status);
if (!status.has("versionNum")) {
if (status.getInt("versionNum") < Config.SUPPORTEDNSVERSION) {
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("ERROR", "Unsupported Nightscout version !!!!"));
rxBus.send(new EventNSClientNewLog("ERROR", "Unsupported Nightscout version !!!!"));
}
} else {
nightscoutVersionName = nsSettingsStatus.getVersion();
nightscoutVersionCode = nsSettingsStatus.getVersionNum();
}
BroadcastStatus.handleNewStatus(nsSettingsStatus, MainApp.instance().getApplicationContext(), isDelta);
nsSettingsStatus.handleNewData(nightscoutVersionName, nightscoutVersionCode, status);
/* Other received data to 2016/02/10
{
@ -584,13 +559,13 @@ public class NSClientService extends Service {
}
*/
} else if (!isDelta) {
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("ERROR", "Unsupported Nightscout version !!!!"));
rxBus.send(new EventNSClientNewLog("ERROR", "Unsupported Nightscout version !!!!"));
}
// If new profile received or change detected broadcast it
if (broadcastProfile && profileStore != null) {
BroadcastProfile.handleNewTreatment(profileStore, MainApp.instance().getApplicationContext(), isDelta);
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("PROFILE", "broadcasting"));
handleNewProfile(profileStore, isDelta);
rxBus.send(new EventNSClientNewLog("PROFILE", "broadcasting"));
}
if (data.has("treatments")) {
@ -599,7 +574,7 @@ public class NSClientService extends Service {
JSONArray updatedTreatments = new JSONArray();
JSONArray addedTreatments = new JSONArray();
if (treatments.length() > 0)
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("DATA", "received " + treatments.length() + " treatments"));
rxBus.send(new EventNSClientNewLog("DATA", "received " + treatments.length() + " treatments"));
for (Integer index = 0; index < treatments.length(); index++) {
JSONObject jsonTreatment = treatments.getJSONObject(index);
NSTreatment treatment = new NSTreatment(jsonTreatment);
@ -621,25 +596,25 @@ public class NSClientService extends Service {
}
}
if (removedTreatments.length() > 0) {
BroadcastTreatment.handleRemovedTreatment(removedTreatments, isDelta);
handleRemovedTreatment(removedTreatments, isDelta);
}
if (updatedTreatments.length() > 0) {
BroadcastTreatment.handleChangedTreatment(updatedTreatments, isDelta);
handleChangedTreatment(updatedTreatments, isDelta);
}
if (addedTreatments.length() > 0) {
BroadcastTreatment.handleNewTreatment(addedTreatments, isDelta);
handleNewTreatment(addedTreatments, isDelta);
}
}
if (data.has("devicestatus")) {
JSONArray devicestatuses = data.getJSONArray("devicestatus");
if (devicestatuses.length() > 0) {
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("DATA", "received " + devicestatuses.length() + " devicestatuses"));
rxBus.send(new EventNSClientNewLog("DATA", "received " + devicestatuses.length() + " devicestatuses"));
for (Integer index = 0; index < devicestatuses.length(); index++) {
JSONObject jsonStatus = devicestatuses.getJSONObject(index);
// remove from upload queue if Ack is failing
UploadQueue.removeID(jsonStatus);
}
BroadcastDeviceStatus.handleNewDeviceStatus(devicestatuses, MainApp.instance().getApplicationContext(), isDelta);
nsDeviceStatus.handleNewData(devicestatuses);
}
}
if (data.has("food")) {
@ -648,7 +623,7 @@ public class NSClientService extends Service {
JSONArray updatedFoods = new JSONArray();
JSONArray addedFoods = new JSONArray();
if (foods.length() > 0)
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("DATA", "received " + foods.length() + " foods"));
rxBus.send(new EventNSClientNewLog("DATA", "received " + foods.length() + " foods"));
for (Integer index = 0; index < foods.length(); index++) {
JSONObject jsonFood = foods.getJSONObject(index);
@ -666,44 +641,47 @@ public class NSClientService extends Service {
}
}
if (removedFoods.length() > 0) {
BroadcastFood.handleRemovedFood(removedFoods, MainApp.instance().getApplicationContext(), isDelta);
EventNsFood evt = new EventNsFood(EventNsFood.Companion.getREMOVE(), removedFoods);
rxBus.send(evt);
}
if (updatedFoods.length() > 0) {
BroadcastFood.handleChangedFood(updatedFoods, MainApp.instance().getApplicationContext(), isDelta);
EventNsFood evt = new EventNsFood(EventNsFood.Companion.getUPDATE(), updatedFoods);
rxBus.send(evt);
}
if (addedFoods.length() > 0) {
BroadcastFood.handleNewFood(addedFoods, MainApp.instance().getApplicationContext(), isDelta);
EventNsFood evt = new EventNsFood(EventNsFood.Companion.getADD(), addedFoods);
rxBus.send(evt);
}
}
if (data.has("mbgs")) {
JSONArray mbgs = data.getJSONArray("mbgs");
if (mbgs.length() > 0)
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("DATA", "received " + mbgs.length() + " mbgs"));
rxBus.send(new EventNSClientNewLog("DATA", "received " + mbgs.length() + " mbgs"));
for (Integer index = 0; index < mbgs.length(); index++) {
JSONObject jsonMbg = mbgs.getJSONObject(index);
// remove from upload queue if Ack is failing
UploadQueue.removeID(jsonMbg);
}
BroadcastMbgs.handleNewMbg(mbgs, MainApp.instance().getApplicationContext(), isDelta);
handleNewMbg(mbgs, isDelta);
}
if (data.has("cals")) {
JSONArray cals = data.getJSONArray("cals");
if (cals.length() > 0)
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("DATA", "received " + cals.length() + " cals"));
rxBus.send(new EventNSClientNewLog("DATA", "received " + cals.length() + " cals"));
// Retreive actual calibration
for (Integer index = 0; index < cals.length(); index++) {
// remove from upload queue if Ack is failing
UploadQueue.removeID(cals.optJSONObject(index));
}
BroadcastCals.handleNewCal(cals, MainApp.instance().getApplicationContext(), isDelta);
handleNewCal(cals, isDelta);
}
if (data.has("sgvs")) {
JSONArray sgvs = data.getJSONArray("sgvs");
if (sgvs.length() > 0)
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("DATA", "received " + sgvs.length() + " sgvs"));
for (Integer index = 0; index < sgvs.length(); index++) {
rxBus.send(new EventNSClientNewLog("DATA", "received " + sgvs.length() + " sgvs"));
for (int index = 0; index < sgvs.length(); index++) {
JSONObject jsonSgv = sgvs.getJSONObject(index);
// RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("DATA", "svg " + sgvs.getJSONObject(index).toString());
// rxBus.send(new EventNSClientNewLog("DATA", "svg " + sgvs.getJSONObject(index).toString());
NSSgv sgv = new NSSgv(jsonSgv);
// Handle new sgv here
// remove from upload queue if Ack is failing
@ -713,25 +691,21 @@ public class NSClientService extends Service {
if (sgv.getMills() > latestDateInReceivedData)
latestDateInReceivedData = sgv.getMills();
}
// Was that sgv more less 15 mins ago ?
boolean lessThan15MinAgo = false;
if ((System.currentTimeMillis() - latestDateInReceivedData) / (60 * 1000L) < 15L)
lessThan15MinAgo = true;
if (Notification.isAlarmForStaleData() && lessThan15MinAgo) {
RxBus.Companion.getINSTANCE().send(new EventDismissNotification(Notification.NSALARM));
// Was that sgv more less 5 mins ago ?
if ((System.currentTimeMillis() - latestDateInReceivedData) / (60 * 1000L) < 5L) {
rxBus.send(new EventDismissNotification(Notification.NSALARM));
rxBus.send(new EventDismissNotification(Notification.NSURGENTALARM));
}
BroadcastSgvs.handleNewSgv(sgvs, MainApp.instance().getApplicationContext(), isDelta);
handleNewSgv(sgvs, isDelta);
}
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("LAST", DateUtil.dateAndTimeString(latestDateInReceivedData)));
rxBus.send(new EventNSClientNewLog("LAST", DateUtil.dateAndTimeString(latestDateInReceivedData)));
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
//RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("NSCLIENT", "onDataUpdate end");
//rxBus.send(new EventNSClientNewLog("NSCLIENT", "onDataUpdate end");
} finally {
if (wakeLock.isHeld()) wakeLock.release();
}
}
});
}
};
@ -744,7 +718,7 @@ public class NSClientService extends Service {
message.put("_id", dbr._id);
message.put("data", new JSONObject(dbr.data));
mSocket.emit("dbUpdate", message, ack);
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("DBUPDATE " + dbr.collection, "Sent " + dbr._id));
rxBus.send(new EventNSClientNewLog("DBUPDATE " + dbr.collection, "Sent " + dbr._id));
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
@ -758,7 +732,7 @@ public class NSClientService extends Service {
message.put("_id", dbr._id);
message.put("data", new JSONObject(dbr.data));
mSocket.emit("dbUpdateUnset", message, ack);
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("DBUPDATEUNSET " + dbr.collection, "Sent " + dbr._id));
rxBus.send(new EventNSClientNewLog("DBUPDATEUNSET " + dbr.collection, "Sent " + dbr._id));
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
@ -771,7 +745,7 @@ public class NSClientService extends Service {
message.put("collection", dbr.collection);
message.put("_id", dbr._id);
mSocket.emit("dbRemove", message, ack);
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("DBREMOVE " + dbr.collection, "Sent " + dbr._id));
rxBus.send(new EventNSClientNewLog("DBREMOVE " + dbr.collection, "Sent " + dbr._id));
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
@ -784,7 +758,7 @@ public class NSClientService extends Service {
message.put("collection", dbr.collection);
message.put("data", new JSONObject(dbr.data));
mSocket.emit("dbAdd", message, ack);
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("DBADD " + dbr.collection, "Sent " + dbr.nsClientID));
rxBus.send(new EventNSClientNewLog("DBADD " + dbr.collection, "Sent " + dbr.nsClientID));
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
@ -793,7 +767,7 @@ public class NSClientService extends Service {
public void sendAlarmAck(AlarmAck alarmAck) {
if (!isConnected || !hasWriteAuth) return;
mSocket.emit("ack", alarmAck.level, alarmAck.group, alarmAck.silenceTime);
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("ALARMACK ", alarmAck.level + " " + alarmAck.group + " " + alarmAck.silenceTime));
rxBus.send(new EventNSClientNewLog("ALARMACK ", alarmAck.level + " " + alarmAck.group + " " + alarmAck.silenceTime));
}
public void resend(final String reason) {
@ -802,9 +776,7 @@ public class NSClientService extends Service {
if (!isConnected || !hasWriteAuth) return;
handler.post(new Runnable() {
@Override
public void run() {
handler.post(() -> {
if (mSocket == null || !mSocket.connected()) return;
if (lastResendTime > System.currentTimeMillis() - 10 * 1000L) {
@ -814,12 +786,12 @@ public class NSClientService extends Service {
}
lastResendTime = System.currentTimeMillis();
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("QUEUE", "Resend started: " + reason));
rxBus.send(new EventNSClientNewLog("QUEUE", "Resend started: " + reason));
CloseableIterator<DbRequest> iterator = null;
CloseableIterator<DbRequest> iterator;
int maxcount = 30;
try {
iterator = MainApp.getDbHelper().getDbRequestInterator();
iterator = mainApp.getDbHelper().getDbRequestInterator();
try {
while (iterator.hasNext() && maxcount > 0) {
DbRequest dbr = iterator.next();
@ -845,8 +817,7 @@ public class NSClientService extends Service {
log.error("Unhandled exception", e);
}
RxBus.Companion.getINSTANCE().send(new EventNSClientNewLog("QUEUE", "Resend ended: " + reason));
}
rxBus.send(new EventNSClientNewLog("QUEUE", "Resend ended: " + reason));
});
}
@ -854,4 +825,201 @@ public class NSClientService extends Service {
destroy();
initialize();
}
private void handleAnnouncement(JSONObject announcement) {
NSAlarm nsAlarm = new NSAlarm(announcement);
Notification notification = new NotificationWithAction(mainApp, nsAlarm);
rxBus.send(new EventNewNotification(notification));
rxBus.send(new EventNSClientNewLog("ANNOUNCEMENT", JsonHelper.safeGetString(announcement, "message", "received")));
aapsLogger.debug(LTag.NSCLIENT, announcement.toString());
}
private void handleAlarm(JSONObject alarm) {
long snoozedTo = sp.getLong(R.string.key_snoozedTo, 0L);
if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo) {
NSAlarm nsAlarm = new NSAlarm(alarm);
Notification notification = new NotificationWithAction(mainApp, nsAlarm);
rxBus.send(new EventNewNotification(notification));
}
rxBus.send(new EventNSClientNewLog("ALARM", JsonHelper.safeGetString(alarm, "message", "received")));
aapsLogger.debug(LTag.NSCLIENT, alarm.toString());
}
private void handleUrgentAlarm(JSONObject alarm) {
long snoozedTo = sp.getLong(R.string.key_snoozedTo, 0L);
if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo) {
NSAlarm nsAlarm = new NSAlarm(alarm);
Notification notification = new NotificationWithAction(mainApp, nsAlarm);
rxBus.send(new EventNewNotification(notification));
}
rxBus.send(new EventNSClientNewLog("URGENTALARM", JsonHelper.safeGetString(alarm, "message", "received")));
aapsLogger.debug(LTag.NSCLIENT, alarm.toString());
}
public void handleNewCal(JSONArray cals, boolean isDelta) {
Bundle bundle = new Bundle();
bundle.putString("cals", cals.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_CAL);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(mainApp).sendBroadcast(intent);
}
public void handleNewMbg(JSONArray mbgs, boolean isDelta) {
Bundle bundle = new Bundle();
bundle.putString("mbgs", mbgs.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_MBG);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(mainApp).sendBroadcast(intent);
}
public void handleNewProfile(ProfileStore profile, boolean isDelta) {
Bundle bundle = new Bundle();
bundle.putString("profile", profile.getData().toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_PROFILE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(mainApp).sendBroadcast(intent);
if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("profile", profile.getData().toString());
bundle.putBoolean("delta", isDelta);
intent = new Intent(Intents.ACTION_NEW_PROFILE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
mainApp.sendBroadcast(intent);
}
}
public void handleNewSgv(JSONArray sgvs, boolean isDelta) {
List<JSONArray> splitted = splitArray(sgvs);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("sgvs", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_SGV);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(mainApp).sendBroadcast(intent);
}
if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("sgvs", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_SGV);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
mainApp.sendBroadcast(intent);
}
}
}
public void handleNewTreatment(JSONArray treatments, boolean isDelta) {
List<JSONArray> splitted = splitArray(treatments);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("treatments", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(mainApp).sendBroadcast(intent);
}
if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
splitted = splitArray(treatments);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("treatments", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
mainApp.getApplicationContext().sendBroadcast(intent);
}
}
}
public void handleChangedTreatment(JSONArray treatments, boolean isDelta) {
List<JSONArray> splitted = splitArray(treatments);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("treatments", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_CHANGED_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(mainApp).sendBroadcast(intent);
}
if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
splitted = splitArray(treatments);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("treatments", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_CHANGED_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
mainApp.getApplicationContext().sendBroadcast(intent);
}
}
}
public void handleRemovedTreatment(JSONArray treatments, boolean isDelta) {
Bundle bundle = new Bundle();
bundle.putString("treatments", treatments.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_REMOVED_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(mainApp).sendBroadcast(intent);
if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("treatments", treatments.toString());
bundle.putBoolean("delta", isDelta);
intent = new Intent(Intents.ACTION_REMOVED_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
mainApp.getApplicationContext().sendBroadcast(intent);
}
}
public List<JSONArray> splitArray(JSONArray array) {
List<JSONArray> ret = new ArrayList<>();
try {
int size = array.length();
int count = 0;
JSONArray newarr = null;
for (int i = 0; i < size; i++) {
if (count == 0) {
if (newarr != null) {
ret.add(newarr);
}
newarr = new JSONArray();
count = 20;
}
newarr.put(array.get(i));
--count;
}
if (newarr != null && newarr.length() > 0) {
ret.add(newarr);
}
} catch (JSONException e) {
log.error("Unhandled exception", e);
ret = new ArrayList<>();
ret.add(array);
}
return ret;
}
}

View file

@ -51,8 +51,6 @@ import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.utils.wizard.QuickWizard;
import info.nightscout.androidaps.utils.wizard.QuickWizardEntry;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.db.ExtendedBolus;
@ -92,7 +90,6 @@ import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus;
import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity;
@ -109,7 +106,6 @@ import info.nightscout.androidaps.plugins.source.DexcomPlugin;
import info.nightscout.androidaps.plugins.source.XdripPlugin;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.wizard.BolusWizard;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.DefaultValueHelper;
@ -121,6 +117,9 @@ import info.nightscout.androidaps.utils.T;
import info.nightscout.androidaps.utils.ToastUtils;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
import info.nightscout.androidaps.utils.wizard.BolusWizard;
import info.nightscout.androidaps.utils.wizard.QuickWizard;
import info.nightscout.androidaps.utils.wizard.QuickWizardEntry;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
@ -132,8 +131,11 @@ public class OverviewFragment extends DaggerFragment implements View.OnClickList
@Inject RxBusWrapper rxBus;
@Inject MainApp mainApp;
@Inject ResourceHelper resourceHelper;
@Inject DefaultValueHelper defaultValueHelper;
@Inject ProfileFunction profileFunction;
@Inject ConstraintChecker constraintChecker;
@Inject StatusLightHandler statusLightHandler;
@Inject NSDeviceStatus nsDeviceStatus;
@Inject LoopPlugin loopPlugin;
@Inject ConfigBuilderPlugin configBuilderPlugin;
@Inject TreatmentsPlugin treatmentsPlugin;
@ -773,30 +775,30 @@ public class OverviewFragment extends DaggerFragment implements View.OnClickList
if (manager != null)
pvd.show(manager, "ProfileViewDialog");
} else if (item.getTitle().equals(resourceHelper.gs(R.string.eatingsoon))) {
double target = Profile.toMgdl(DefaultValueHelper.determineEatingSoonTT(), ProfileFunctions.getSystemUnits());
double target = Profile.toMgdl(defaultValueHelper.determineEatingSoonTT(), ProfileFunctions.getSystemUnits());
TempTarget tempTarget = new TempTarget()
.date(System.currentTimeMillis())
.duration(DefaultValueHelper.determineEatingSoonTTDuration())
.duration(defaultValueHelper.determineEatingSoonTTDuration())
.reason(resourceHelper.gs(R.string.eatingsoon))
.source(Source.USER)
.low(target)
.high(target);
treatmentsPlugin.addToHistoryTempTarget(tempTarget);
} else if (item.getTitle().equals(resourceHelper.gs(R.string.activity))) {
double target = Profile.toMgdl(DefaultValueHelper.determineActivityTT(), ProfileFunctions.getSystemUnits());
double target = Profile.toMgdl(defaultValueHelper.determineActivityTT(), ProfileFunctions.getSystemUnits());
TempTarget tempTarget = new TempTarget()
.date(now())
.duration(DefaultValueHelper.determineActivityTTDuration())
.duration(defaultValueHelper.determineActivityTTDuration())
.reason(resourceHelper.gs(R.string.activity))
.source(Source.USER)
.low(target)
.high(target);
treatmentsPlugin.addToHistoryTempTarget(tempTarget);
} else if (item.getTitle().equals(resourceHelper.gs(R.string.hypo))) {
double target = Profile.toMgdl(DefaultValueHelper.determineHypoTT(), ProfileFunctions.getSystemUnits());
double target = Profile.toMgdl(defaultValueHelper.determineHypoTT(), ProfileFunctions.getSystemUnits());
TempTarget tempTarget = new TempTarget()
.date(now())
.duration(DefaultValueHelper.determineHypoTTDuration())
.duration(defaultValueHelper.determineHypoTTDuration())
.reason(resourceHelper.gs(R.string.hypo))
.source(Source.USER)
.low(target)
@ -1028,7 +1030,7 @@ public class OverviewFragment extends DaggerFragment implements View.OnClickList
}
loopStatusLayout.setVisibility(View.VISIBLE);
CareportalFragment.updateAge(getActivity(), sage, iage, cage, pbage);
statusLightHandler.updateAge(sage, iage, cage, pbage);
BgReading actualBG = DatabaseHelper.actualBg();
BgReading lastBG = DatabaseHelper.lastBg();
@ -1039,8 +1041,8 @@ public class OverviewFragment extends DaggerFragment implements View.OnClickList
final String profileName = profileFunction.getProfileName();
final String units = ProfileFunctions.getSystemUnits();
final double lowLine = OverviewPlugin.INSTANCE.determineLowLine();
final double highLine = OverviewPlugin.INSTANCE.determineHighLine();
final double lowLine = defaultValueHelper.determineLowLine();
final double highLine = defaultValueHelper.determineHighLine();
//Start with updating the BG as it is unaffected by loop.
// **** BG value ****
@ -1334,12 +1336,11 @@ public class OverviewFragment extends DaggerFragment implements View.OnClickList
if (statuslightsLayout != null)
if (sp.getBoolean(R.string.key_show_statuslights, false)) {
StatuslightHandler handler = new StatuslightHandler();
if (sp.getBoolean(R.string.key_show_statuslights_extended, false)) {
handler.extendedStatuslight(cageView, iageView, reservoirView, sageView, batteryView);
statusLightHandler.extendedStatusLight(cageView, iageView, reservoirView, sageView, batteryView);
statuslightsLayout.setVisibility(View.VISIBLE);
} else {
handler.statuslight(cageView, iageView, reservoirView, sageView, batteryView);
statusLightHandler.statusLight(cageView, iageView, reservoirView, sageView, batteryView);
statuslightsLayout.setVisibility(View.VISIBLE);
}
} else {
@ -1357,20 +1358,20 @@ public class OverviewFragment extends DaggerFragment implements View.OnClickList
// pump status from ns
if (pumpDeviceStatusView != null) {
pumpDeviceStatusView.setText(NSDeviceStatus.getInstance().getPumpStatus());
pumpDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), resourceHelper.gs(R.string.pump), NSDeviceStatus.getInstance().getExtendedPumpStatus()));
pumpDeviceStatusView.setText(nsDeviceStatus.getPumpStatus());
pumpDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), resourceHelper.gs(R.string.pump), nsDeviceStatus.getExtendedPumpStatus()));
}
// OpenAPS status from ns
if (openapsDeviceStatusView != null) {
openapsDeviceStatusView.setText(NSDeviceStatus.getInstance().getOpenApsStatus());
openapsDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), resourceHelper.gs(R.string.openaps), NSDeviceStatus.getInstance().getExtendedOpenApsStatus()));
openapsDeviceStatusView.setText(nsDeviceStatus.getOpenApsStatus());
openapsDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), resourceHelper.gs(R.string.openaps), nsDeviceStatus.getExtendedOpenApsStatus()));
}
// Uploader status from ns
if (uploaderDeviceStatusView != null) {
uploaderDeviceStatusView.setText(NSDeviceStatus.getInstance().getUploaderStatusSpanned());
uploaderDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), resourceHelper.gs(R.string.uploader), NSDeviceStatus.getInstance().getExtendedUploaderStatus()));
uploaderDeviceStatusView.setText(nsDeviceStatus.getUploaderStatusSpanned());
uploaderDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), resourceHelper.gs(R.string.uploader), nsDeviceStatus.getExtendedUploaderStatus()));
}
// Sensitivity

View file

@ -1,8 +1,6 @@
package info.nightscout.androidaps.plugins.general.overview
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.events.EventRefreshOverview
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
@ -12,7 +10,6 @@ import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNo
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationStore
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.SP
import info.nightscout.androidaps.utils.extensions.plusAssign
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
@ -33,21 +30,8 @@ class OverviewPlugin @Inject constructor(
.preferencesId(R.xml.pref_overview)
.description(R.string.description_overview)) {
init {
INSTANCE = this
}
companion object {
@JvmStatic
@Deprecated("Get via Dagger. Will be removed once fully transitioned to Dagger")
lateinit var INSTANCE: OverviewPlugin //TODO: remove as soon as Dagger is fully set up
}
private var disposable: CompositeDisposable = CompositeDisposable()
var bgTargetLow = 80.0
var bgTargetHigh = 180.0
override fun onStart() {
super.onStart()
notificationStore.createNotificationChannel()
@ -75,18 +59,4 @@ class OverviewPlugin @Inject constructor(
disposable.clear()
super.onStop()
}
fun determineHighLine(): Double {
var highLineSetting = SP.getDouble(R.string.key_high_mark, bgTargetHigh)
if (highLineSetting < 1) highLineSetting = Constants.HIGHMARK
highLineSetting = Profile.toCurrentUnits(highLineSetting)
return highLineSetting
}
fun determineLowLine(): Double {
var lowLineSetting = SP.getDouble(R.string.key_low_mark, bgTargetLow)
if (lowLineSetting < 1) lowLineSetting = Constants.LOWMARK
lowLineSetting = Profile.toCurrentUnits(lowLineSetting)
return lowLineSetting
}
}

View file

@ -0,0 +1,172 @@
package info.nightscout.androidaps.plugins.general.overview
import android.graphics.Color
import android.view.View
import android.widget.TextView
import androidx.arch.core.util.Function
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.SetWarnColor
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class StatusLightHandler @Inject constructor(
private val nsSettingsStatus: NSSettingsStatus,
private val resourceHelper: ResourceHelper,
private val sp: SP,
private val configBuilderPlugin: ConfigBuilderPlugin
) {
/**
* applies the statusLight subview on the overview fragment
*/
fun statusLight(cageView: TextView?, iAgeView: TextView?, reservoirView: TextView?,
sageView: TextView?, batteryView: TextView?) {
val pump = configBuilderPlugin.activePump
applyStatusLight("cage", CareportalEvent.SITECHANGE, cageView, "CAN", 48, 72)
applyStatusLight("iage", CareportalEvent.INSULINCHANGE, iAgeView, "INS", 72, 96)
val reservoirLevel = if (pump!!.isInitialized) pump.reservoirLevel else (-1).toDouble()
applyStatusLightLevel(R.string.key_statuslights_res_critical, 10.0,
R.string.key_statuslights_res_warning, 80.0, reservoirView, "RES", reservoirLevel)
applyStatusLight("sage", CareportalEvent.SENSORCHANGE, sageView, "SEN", 164, 166)
if (pump.model() != PumpType.AccuChekCombo) {
val batteryLevel = if (pump.isInitialized) pump.batteryLevel.toDouble() else -1.0
applyStatusLightLevel(R.string.key_statuslights_bat_critical, 5.0,
R.string.key_statuslights_bat_warning, 22.0,
batteryView, "BAT", batteryLevel)
} else {
applyStatusLight("bage", CareportalEvent.PUMPBATTERYCHANGE, batteryView, "BAT", 504, 240)
}
}
private fun applyStatusLight(nsSettingPlugin: String?, eventName: String?, view: TextView?, text: String?,
defaultWarnThreshold: Int, defaultUrgentThreshold: Int) {
if (view != null) {
val urgent = nsSettingsStatus.getExtendedWarnValue(nsSettingPlugin!!, "urgent", defaultUrgentThreshold.toDouble())
val warn = nsSettingsStatus.getExtendedWarnValue(nsSettingPlugin, "warn", defaultWarnThreshold.toDouble())
val event = MainApp.getDbHelper().getLastCareportalEvent(eventName)
val age = event?.hoursFromStart ?: Double.MAX_VALUE
applyStatusLight(view, text, age, warn, urgent, Double.MAX_VALUE, true)
}
}
private fun applyStatusLightLevel(criticalSetting: Int, criticalDefaultValue: Double,
warnSetting: Int, warnDefaultValue: Double,
view: TextView?, text: String?, level: Double) {
if (view != null) {
val resUrgent = sp.getDouble(criticalSetting, criticalDefaultValue)
val resWarn = sp.getDouble(warnSetting, warnDefaultValue)
applyStatusLight(view, text, level, resWarn, resUrgent, -1.0, false)
}
}
private fun applyStatusLight(view: TextView, text: String?, value: Double, warnThreshold: Double,
urgentThreshold: Double, invalid: Double, checkAscending: Boolean) {
val check =
if (checkAscending) Function { threshold: Double -> value >= threshold }
else Function { threshold: Double -> value <= threshold }
if (value != invalid) {
view.text = text
when {
check.apply(urgentThreshold) -> view.setTextColor(resourceHelper.gc(R.color.ribbonCritical))
check.apply(warnThreshold) -> view.setTextColor(resourceHelper.gc(R.color.ribbonWarning))
else -> view.setTextColor(resourceHelper.gc(R.color.ribbonDefault))
}
view.visibility = View.VISIBLE
} else {
view.visibility = View.GONE
}
}
/**
* applies the extended statusLight subview on the overview fragment
*/
fun extendedStatusLight(cageView: TextView, iAgeView: TextView,
reservoirView: TextView, sageView: TextView,
batteryView: TextView) {
val pump = configBuilderPlugin.activePump
handleAge("cage", CareportalEvent.SITECHANGE, cageView, "CAN ",
48, 72)
handleAge("iage", CareportalEvent.INSULINCHANGE, iAgeView, "INS ",
72, 96)
handleLevel(R.string.key_statuslights_res_critical, 10.0,
R.string.key_statuslights_res_warning, 80.0,
reservoirView, "RES ", pump!!.reservoirLevel)
handleAge("sage", CareportalEvent.SENSORCHANGE, sageView, "SEN ",
164, 166)
if (pump.model() != PumpType.AccuChekCombo) {
handleLevel(R.string.key_statuslights_bat_critical, 26.0,
R.string.key_statuslights_bat_warning, 51.0,
batteryView, "BAT ", pump.batteryLevel.toDouble())
} else {
handleAge("bage", CareportalEvent.PUMPBATTERYCHANGE, batteryView, "BAT ",
336, 240)
}
}
private fun handleAge(nsSettingPlugin: String, eventName: String, view: TextView, text: String,
defaultUrgentThreshold: Int, defaultWarnThreshold: Int) {
val urgent = nsSettingsStatus.getExtendedWarnValue(nsSettingPlugin, "urgent", defaultUrgentThreshold.toDouble())
val warn = nsSettingsStatus.getExtendedWarnValue(nsSettingPlugin, "warn", defaultWarnThreshold.toDouble())
handleAge(view, text, eventName, warn, urgent, true)
}
private fun handleLevel(criticalSetting: Int, criticalDefaultValue: Double,
warnSetting: Int, warnDefaultValue: Double,
view: TextView?, text: String, level: Double) {
if (view != null) {
val resUrgent = sp.getDouble(criticalSetting, criticalDefaultValue)
val resWarn = sp.getDouble(warnSetting, warnDefaultValue)
@Suppress("SetTextI18n")
view.text = text + DecimalFormatter.to0Decimal(level)
SetWarnColor.setColorInverse(view, level, resWarn, resUrgent)
}
}
private fun handleAge(age: TextView?, eventType: String, warnThreshold: Double, urgentThreshold: Double) =
handleAge(age, "", eventType, warnThreshold, urgentThreshold, OverviewFragment.shorttextmode)
fun handleAge(age: TextView?, prefix: String, eventType: String, warnThreshold: Double, urgentThreshold: Double, useShortText: Boolean) {
val notavailable = if (useShortText) "-" else resourceHelper.gs(R.string.notavailable)
val careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(eventType)
if (careportalEvent != null) {
age?.setTextColor(determineTextColor(careportalEvent, warnThreshold, urgentThreshold))
age?.text = prefix + careportalEvent.age(useShortText)
} else {
age?.text = notavailable
}
}
fun updateAge(sage: TextView?, iage: TextView?, cage: TextView?, pbage: TextView?) {
val iageUrgent = nsSettingsStatus.getExtendedWarnValue("iage", "urgent", 96.0)
val iageWarn = nsSettingsStatus.getExtendedWarnValue("iage", "warn", 72.0)
handleAge(iage, CareportalEvent.INSULINCHANGE, iageWarn, iageUrgent)
val cageUrgent = nsSettingsStatus.getExtendedWarnValue("cage", "urgent", 72.0)
val cageWarn = nsSettingsStatus.getExtendedWarnValue("cage", "warn", 48.0)
handleAge(cage, CareportalEvent.SITECHANGE, cageWarn, cageUrgent)
val sageUrgent = nsSettingsStatus.getExtendedWarnValue("sage", "urgent", 166.0)
val sageWarn = nsSettingsStatus.getExtendedWarnValue("sage", "warn", 164.0)
handleAge(sage, CareportalEvent.SENSORCHANGE, sageWarn, sageUrgent)
val pbageUrgent = nsSettingsStatus.getExtendedWarnValue("bage", "urgent", 360.0)
val pbageWarn = nsSettingsStatus.getExtendedWarnValue("bage", "warn", 240.0)
handleAge(pbage, CareportalEvent.PUMPBATTERYCHANGE, pbageWarn, pbageUrgent)
}
fun determineTextColor(careportalEvent: CareportalEvent, warnThreshold: Double, urgentThreshold: Double): Int {
return if (careportalEvent.isOlderThan(urgentThreshold)) {
resourceHelper.gc(R.color.low)
} else if (careportalEvent.isOlderThan(warnThreshold)) {
resourceHelper.gc(R.color.high)
} else {
Color.WHITE
}
}
}

View file

@ -1,145 +0,0 @@
package info.nightscout.androidaps.plugins.general.overview;
import android.view.View;
import android.widget.TextView;
import androidx.arch.core.util.Function;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.SetWarnColor;
class StatuslightHandler {
/**
* applies the statuslight subview on the overview fragement
*/
void statuslight(TextView cageView, TextView iageView, TextView reservoirView,
TextView sageView, TextView batteryView) {
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
applyStatuslight("cage", CareportalEvent.SITECHANGE, cageView, "CAN", 48, 72);
applyStatuslight("iage", CareportalEvent.INSULINCHANGE, iageView, "INS", 72, 96);
double reservoirLevel = pump.isInitialized() ? pump.getReservoirLevel() : -1;
applyStatuslightLevel(R.string.key_statuslights_res_critical, 10.0,
R.string.key_statuslights_res_warning, 80.0, reservoirView, "RES", reservoirLevel);
applyStatuslight("sage", CareportalEvent.SENSORCHANGE, sageView, "SEN", 164, 166);
if (pump.model() != PumpType.AccuChekCombo) {
double batteryLevel = pump.isInitialized() ? pump.getBatteryLevel() : -1;
applyStatuslightLevel(R.string.key_statuslights_bat_critical, 5.0,
R.string.key_statuslights_bat_warning, 22.0,
batteryView, "BAT", batteryLevel);
} else {
applyStatuslight("bage", CareportalEvent.PUMPBATTERYCHANGE, batteryView, "BAT", 504, 240);
}
}
void applyStatuslight(String nsSettingPlugin, String eventName, TextView view, String text,
int defaultWarnThreshold, int defaultUrgentThreshold) {
NSSettingsStatus nsSettings = NSSettingsStatus.getInstance();
if (view != null) {
double urgent = nsSettings.getExtendedWarnValue(nsSettingPlugin, "urgent", defaultUrgentThreshold);
double warn = nsSettings.getExtendedWarnValue(nsSettingPlugin, "warn", defaultWarnThreshold);
CareportalEvent event = MainApp.getDbHelper().getLastCareportalEvent(eventName);
double age = event != null ? event.getHoursFromStart() : Double.MAX_VALUE;
applyStatuslight(view, text, age, warn, urgent, Double.MAX_VALUE, true);
}
}
void applyStatuslightLevel(int criticalSetting, double criticalDefaultValue,
int warnSetting, double warnDefaultValue,
TextView view, String text, double level) {
if (view != null) {
double resUrgent = SP.getDouble(criticalSetting, criticalDefaultValue);
double resWarn = SP.getDouble(warnSetting, warnDefaultValue);
applyStatuslight(view, text, level, resWarn, resUrgent, -1, false);
}
}
void applyStatuslight(TextView view, String text, double value, double warnThreshold,
double urgentThreshold, double invalid, boolean checkAscending) {
Function<Double, Boolean> check = checkAscending ? (Double threshold) -> value >= threshold :
(Double threshold) -> value <= threshold;
if (value != invalid) {
view.setText(text);
if (check.apply(urgentThreshold)) {
view.setTextColor(MainApp.gc(R.color.ribbonCritical));
} else if (check.apply(warnThreshold)) {
view.setTextColor(MainApp.gc(R.color.ribbonWarning));
} else {
view.setTextColor(MainApp.gc(R.color.ribbonDefault));
}
view.setVisibility(View.VISIBLE);
} else {
view.setVisibility(View.GONE);
}
}
/**
* applies the extended statuslight subview on the overview fragement
*/
void extendedStatuslight(TextView cageView, TextView iageView,
TextView reservoirView, TextView sageView,
TextView batteryView) {
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
handleAge("cage", CareportalEvent.SITECHANGE, cageView, "CAN ",
48, 72);
handleAge("iage", CareportalEvent.INSULINCHANGE, iageView, "INS ",
72, 96);
handleLevel(R.string.key_statuslights_res_critical, 10.0,
R.string.key_statuslights_res_warning, 80.0,
reservoirView, "RES ", pump.getReservoirLevel());
handleAge("sage", CareportalEvent.SENSORCHANGE, sageView, "SEN ",
164, 166);
if (pump.model() != PumpType.AccuChekCombo) {
handleLevel(R.string.key_statuslights_bat_critical, 26.0,
R.string.key_statuslights_bat_warning, 51.0,
batteryView, "BAT ", pump.getBatteryLevel());
} else {
handleAge("bage", CareportalEvent.PUMPBATTERYCHANGE, batteryView, "BAT ",
336, 240);
}
}
void handleAge(String nsSettingPlugin, String eventName, TextView view, String text,
int defaultUrgentThreshold, int defaultWarnThreshold) {
NSSettingsStatus nsSettings = new NSSettingsStatus().getInstance();
if (view != null) {
double urgent = nsSettings.getExtendedWarnValue(nsSettingPlugin, "urgent", defaultUrgentThreshold);
double warn = nsSettings.getExtendedWarnValue(nsSettingPlugin, "warn", defaultWarnThreshold);
CareportalFragment.handleAge(view, text, eventName, warn, urgent, true);
}
}
void handleLevel(int criticalSetting, double criticalDefaultValue,
int warnSetting, double warnDefaultValue,
TextView view, String text, double level) {
if (view != null) {
double resUrgent = SP.getDouble(criticalSetting, criticalDefaultValue);
double resWarn = SP.getDouble(warnSetting, warnDefaultValue);
view.setText(text + DecimalFormatter.to0Decimal(level));
SetWarnColor.setColorInverse(view, level, resWarn, resUrgent);
}
}
}

View file

@ -1,21 +1,11 @@
package info.nightscout.androidaps.plugins.general.overview.notifications;
import java.util.Date;
import androidx.annotation.NonNull;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSAlarm;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus;
import info.nightscout.androidaps.utils.SP;
// Added by Rumen for debugging
/**
* Created by mike on 03.12.2016.
*/
import info.nightscout.androidaps.utils.T;
public class Notification {
// TODO join with NotificationWithAction after change to enums
public static final int URGENT = 0;
public static final int NORMAL = 1;
public static final int LOW = 2;
@ -30,7 +20,6 @@ public class Notification {
public static final int PROFILE_NOT_SET_NOT_INITIALIZED = 5;
public static final int FAILED_UDPATE_PROFILE = 6;
public static final int BASAL_VALUE_BELOW_MINIMUM = 7;
public static final int OLD_NSCLIENT = 8;
public static final int OLD_NS = 9;
public static final int INVALID_PHONE_NUMBER = 10;
public static final int INVALID_MESSAGE_BODY = 11;
@ -81,18 +70,20 @@ public class Notification {
public int id;
public Date date;
public long date;
public String text;
public int level;
public Date validTo = new Date(0);
public long validTo = 0;
public NSAlarm nsAlarm = null;
public Integer soundId = null;
protected Runnable action = null;
protected int buttonText = 0;
public Notification() {
}
public Notification(int id, Date date, String text, int level, Date validTo) {
public Notification(int id, long date, String text, int level, long validTo) {
this.id = id;
this.date = date;
this.text = text;
@ -102,24 +93,22 @@ public class Notification {
public Notification(int id, String text, int level, int validMinutes) {
this.id = id;
this.date = new Date();
this.date = System.currentTimeMillis();
this.text = text;
this.level = level;
this.validTo = new Date(System.currentTimeMillis() + validMinutes * 60 * 1000L);
this.validTo = System.currentTimeMillis() + T.mins(validMinutes).msecs();
}
public Notification(int id, String text, int level) {
public Notification(int id, @NonNull String text, int level) {
this.id = id;
this.date = new Date();
this.date = System.currentTimeMillis();
this.text = text;
this.level = level;
this.validTo = new Date(0);
}
public Notification(int id) {
this.id = id;
this.date = new Date();
this.validTo = new Date(0);
this.date = System.currentTimeMillis();
}
public Notification text(String text) {
@ -136,102 +125,4 @@ public class Notification {
this.soundId = soundId;
return this;
}
public Notification(NSAlarm nsAlarm) {
this.date = new Date();
this.validTo = new Date(0);
this.nsAlarm = nsAlarm;
switch (nsAlarm.getLevel()) {
case 0:
this.id = NSANNOUNCEMENT;
this.level = ANNOUNCEMENT;
this.text = nsAlarm.getMessage();
this.validTo = new Date(System.currentTimeMillis() + 60 * 60 * 1000L);
break;
case 1:
this.id = NSALARM;
this.level = NORMAL;
this.text = nsAlarm.getTile();
if (isAlarmForLow() && SP.getBoolean(R.string.key_nsalarm_low, false) || isAlarmForHigh() && SP.getBoolean(R.string.key_nsalarm_high, false) || isAlarmForStaleData() && SP.getBoolean(R.string.key_nsalarm_staledata, false))
this.soundId = R.raw.alarm;
break;
case 2:
this.id = NSURGENTALARM;
this.level = URGENT;
this.text = nsAlarm.getTile();
if (isAlarmForLow() && SP.getBoolean(R.string.key_nsalarm_urgent_low, false) || isAlarmForHigh() && SP.getBoolean(R.string.key_nsalarm_urgent_high, false))
this.soundId = R.raw.urgentalarm;
break;
}
}
public boolean isEnabled() {
if (nsAlarm == null)
return true;
if (level == ANNOUNCEMENT)
return true;
if (level == NORMAL && isAlarmForLow() && SP.getBoolean(R.string.key_nsalarm_low, false) || isAlarmForHigh() && SP.getBoolean(R.string.key_nsalarm_high, false) || isAlarmForStaleData() && SP.getBoolean(R.string.key_nsalarm_staledata, false)) {
return true;
}
if (level == URGENT && isAlarmForLow() && SP.getBoolean(R.string.key_nsalarm_urgent_low, false) || isAlarmForHigh() && SP.getBoolean(R.string.key_nsalarm_urgent_high, false) || isAlarmForStaleData() && SP.getBoolean(R.string.key_nsalarm_urgent_staledata, false))
return true;
return false;
}
boolean isAlarmForLow() {
BgReading bgReading = MainApp.getDbHelper().lastBg();
if (bgReading == null)
return false;
Double threshold = NSSettingsStatus.getInstance().getThreshold("bgTargetTop");
if (threshold == null)
return false;
if (bgReading.value <= threshold)
return true;
return false;
}
boolean isAlarmForHigh() {
BgReading bgReading = MainApp.getDbHelper().lastBg();
if (bgReading == null)
return false;
Double threshold = NSSettingsStatus.getInstance().getThreshold("bgTargetBottom");
if (threshold == null)
return false;
if (bgReading.value >= threshold)
return true;
return false;
}
public static boolean isAlarmForStaleData() {
long snoozedTo = SP.getLong("snoozedTo", 0L);
if (snoozedTo != 0L) {
if (System.currentTimeMillis() < SP.getLong("snoozedTo", 0L)) {
//log.debug("Alarm is snoozed for next "+(SP.getLong("snoozedTo", 0L)-System.currentTimeMillis())/1000+" seconds");
return false;
}
}
BgReading bgReading = MainApp.getDbHelper().lastBg();
if (bgReading == null)
return false;
long bgReadingAgo = System.currentTimeMillis() - bgReading.date;
int bgReadingAgoMin = (int) (bgReadingAgo / (1000 * 60));
// Added for testing
// bgReadingAgoMin = 20;
boolean openAPSEnabledAlerts = NSSettingsStatus.getInstance().openAPSEnabledAlerts();
//log.debug("bgReadingAgoMin value is:"+bgReadingAgoMin);
//log.debug("Stale alarm snoozed to: "+(System.currentTimeMillis() - snoozedTo)/60000L);
Double threshold = NSSettingsStatus.getInstance().getThreshold("alarmTimeagoWarnMins");
//log.debug("OpenAPS Alerts enabled: "+openAPSEnabledAlerts);
// if no thresshold from Ns get it loccally
if (threshold == null) threshold = SP.getDouble(R.string.key_nsalarm_staledatavalue, 15D);
// No threshold of OpenAPS Alarm so using the one for BG
// Added OpenAPSEnabledAlerts to alarm check
if ((bgReadingAgoMin > threshold && SP.getBoolean(R.string.key_nsalarm_staledata, false)) || (bgReadingAgoMin > threshold && openAPSEnabledAlerts)) {
return true;
}
//snoozing for threshold
SP.putLong("snoozedTo", (long) (bgReading.date + (threshold * 1000 * 60L)));
//log.debug("New bg data is available Alarm is snoozed for next "+threshold*1000*60+" seconds");
return false;
}
}

View file

@ -1,116 +0,0 @@
package info.nightscout.androidaps.plugins.general.overview.notifications;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Objects;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin;
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin;
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.SP;
public class NotificationRecyclerViewAdapter extends RecyclerView.Adapter<NotificationRecyclerViewAdapter.NotificationsViewHolder> {
private static Logger log = LoggerFactory.getLogger(L.NOTIFICATION);
private List<Notification> notificationsList;
private NotificationStore notificationStore;
NotificationRecyclerViewAdapter(NotificationStore nStore, List<Notification> notificationsList) {
this.notificationsList = notificationsList;
this.notificationStore = nStore;
}
@NonNull
@Override
public NotificationsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.overview_notification_item, viewGroup, false);
return new NotificationsViewHolder(notificationStore, v);
}
@Override
public void onBindViewHolder(NotificationsViewHolder holder, int position) {
Notification notification = notificationsList.get(position);
holder.dismiss.setTag(notification);
if (notification instanceof NotificationWithAction)
holder.dismiss.setText(((NotificationWithAction) notification).buttonText);
else if (Objects.equals(notification.text, MainApp.gs(R.string.nsalarm_staledata)))
holder.dismiss.setText(R.string.snooze);
holder.text.setText(DateUtil.timeString(notification.date) + " " + notification.text);
if (notification.level == Notification.URGENT)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationUrgent));
else if (notification.level == Notification.NORMAL)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationNormal));
else if (notification.level == Notification.LOW)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationLow));
else if (notification.level == Notification.INFO)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationInfo));
else if (notification.level == Notification.ANNOUNCEMENT)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationAnnouncement));
}
@Override
public int getItemCount() {
return notificationsList.size();
}
@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
static class NotificationsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
NotificationStore notificationStore;
CardView cv;
TextView text;
Button dismiss;
NotificationsViewHolder(final NotificationStore notificationStore, View itemView) {
super(itemView);
this.notificationStore = notificationStore;
cv = itemView.findViewById(R.id.notification_cardview);
text = itemView.findViewById(R.id.notification_text);
dismiss = itemView.findViewById(R.id.notification_dismiss);
dismiss.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Notification notification = (Notification) v.getTag();
RxBus.Companion.getINSTANCE().send(new EventDismissNotification(notification.id));
if (notification.nsAlarm != null) {
NSClientPlugin.getPlugin().handleClearAlarm(notification.nsAlarm, 60 * 60 * 1000L);
}
// Adding current time to snooze if we got staleData
if (L.isEnabled(L.NOTIFICATION))
log.debug("Notification text is: " + notification.text);
if (notification.text.equals(MainApp.gs(R.string.nsalarm_staledata))) {
long msToSnooze = SP.getInt("nsalarm_staledatavalue", 15) * 60 * 1000L;
if (L.isEnabled(L.NOTIFICATION))
log.debug("snooze nsalarm_staledatavalue in minutes is " + SP.getInt("nsalarm_staledatavalue", 15) + "\n in ms is: " + msToSnooze + " currentTimeMillis is: " + System.currentTimeMillis());
notificationStore.snoozeTo(System.currentTimeMillis() + (SP.getInt("nsalarm_staledatavalue", 15) * 60 * 1000L));
}
if (notification instanceof NotificationWithAction) {
((NotificationWithAction) notification).action.run();
}
}
}
}

View file

@ -9,14 +9,22 @@ import android.graphics.BitmapFactory
import android.media.AudioManager
import android.media.RingtoneManager
import android.os.Build
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import androidx.cardview.widget.CardView
import androidx.core.app.NotificationCompat
import androidx.recyclerview.widget.RecyclerView
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
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.overview.events.EventDismissNotification
import info.nightscout.androidaps.services.AlarmSoundService
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import java.util.*
@ -30,6 +38,7 @@ import javax.inject.Singleton
class NotificationStore @Inject constructor(
private val aapsLogger: AAPSLogger,
private val sp: SP,
private val rxBus: RxBusWrapper,
private val resourceHelper: ResourceHelper,
private val mainApp: MainApp
) {
@ -94,7 +103,7 @@ class NotificationStore @Inject constructor(
var i = 0
while (i < store.size) {
val n = store[i]
if (n.validTo.time != 0L && n.validTo.time < System.currentTimeMillis()) {
if (n.validTo != 0L && n.validTo < System.currentTimeMillis()) {
store.removeAt(i)
i--
}
@ -102,20 +111,6 @@ class NotificationStore @Inject constructor(
}
}
fun snoozeTo(timeToSnooze: Long) {
aapsLogger.debug(LTag.NOTIFICATION, "Snoozing alarm until: $timeToSnooze")
sp.putLong("snoozedTo", timeToSnooze)
}
private fun unSnooze() {
if (Notification.isAlarmForStaleData()) {
val notification = Notification(Notification.NSALARM, resourceHelper.gs(R.string.nsalarm_staledata), Notification.URGENT)
sp.putLong("snoozedTo", System.currentTimeMillis())
add(notification)
aapsLogger.debug(LTag.NOTIFICATION, "Snoozed to current time and added back notification!")
}
}
private fun raiseSystemNotification(n: Notification) {
val mgr = mainApp.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val largeIcon = BitmapFactory.decodeResource(mainApp.resources, MainApp.getIcon())
@ -154,7 +149,7 @@ class NotificationStore @Inject constructor(
removeExpired()
unSnooze()
if (store.size > 0) {
val adapter = NotificationRecyclerViewAdapter(this, cloneStore())
val adapter = NotificationRecyclerViewAdapter(cloneStore())
notificationsView.adapter = adapter
notificationsView.visibility = View.VISIBLE
} else {
@ -169,4 +164,53 @@ class NotificationStore @Inject constructor(
return clone
}
private fun unSnooze() {
if (sp.getBoolean(R.string.key_nsalarm_staledata, false)) {
val notification = Notification(Notification.NSALARM, resourceHelper.gs(R.string.nsalarm_staledata), Notification.URGENT)
sp.putLong(R.string.key_snoozedTo, System.currentTimeMillis())
add(notification)
aapsLogger.debug(LTag.NOTIFICATION, "Snoozed to current time and added back notification!")
}
}
inner class NotificationRecyclerViewAdapter internal constructor(private val notificationsList: List<Notification>) : RecyclerView.Adapter<NotificationRecyclerViewAdapter.NotificationsViewHolder>() {
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): NotificationsViewHolder {
val v = LayoutInflater.from(viewGroup.context).inflate(R.layout.overview_notification_item, viewGroup, false)
return NotificationsViewHolder(v)
}
override fun onBindViewHolder(holder: NotificationsViewHolder, position: Int) {
val notification = notificationsList[position]
holder.dismiss.tag = notification
if (notification.buttonText != 0) holder.dismiss.setText(notification.buttonText)
else holder.dismiss.setText(R.string.snooze)
@Suppress("SetTextI18n")
holder.text.text = DateUtil.timeString(notification.date) + " " + notification.text
when (notification.level) {
Notification.URGENT -> holder.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationUrgent))
Notification.NORMAL -> holder.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationNormal))
Notification.LOW -> holder.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationLow))
Notification.INFO -> holder.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationInfo))
Notification.ANNOUNCEMENT -> holder.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationAnnouncement))
}
}
override fun getItemCount(): Int {
return notificationsList.size
}
inner class NotificationsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var cv: CardView = itemView.findViewById(R.id.notification_cardview)
var text: TextView = itemView.findViewById(R.id.notification_text)
var dismiss: Button = itemView.findViewById(R.id.notification_dismiss)
init {
dismiss.setOnClickListener {
val notification = it.tag as Notification
rxBus.send(EventDismissNotification(notification.id))
notification.action?.run()
}
}
}
}
}

View file

@ -1,18 +0,0 @@
package info.nightscout.androidaps.plugins.general.overview.notifications;
import androidx.annotation.IntegerRes;
public class NotificationWithAction extends Notification {
Runnable action;
int buttonText;
public NotificationWithAction(int id, String text, int level) {
super(id, text, level);
}
public void action(int buttonText, Runnable action) {
this.buttonText = buttonText;
this.action = action;
}
}

View file

@ -0,0 +1,80 @@
package info.nightscout.androidaps.plugins.general.overview.notifications
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin
import info.nightscout.androidaps.plugins.general.nsclient.data.NSAlarm
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
import info.nightscout.androidaps.utils.DefaultValueHelper
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import javax.inject.Inject
class NotificationWithAction constructor(
mainApp: MainApp
) : Notification() {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var sp: SP
@Inject lateinit var defaultValueHelper: DefaultValueHelper
@Inject lateinit var nsSettingsStatus: NSSettingsStatus
private var nsAlarm: NSAlarm? = null
init {
mainApp.androidInjector().inject(this)
}
constructor(mainApp: MainApp, id: Int, text: String, level: Int) : this(mainApp) {
this.id = id
date = System.currentTimeMillis()
this.text = text
this.level = level
}
constructor (mainApp: MainApp, nsAlarm: NSAlarm) : this(mainApp) {
this.nsAlarm = nsAlarm
date = System.currentTimeMillis()
when (nsAlarm.level()) {
0 -> {
id = NSANNOUNCEMENT
level = ANNOUNCEMENT
text = nsAlarm.message()
validTo = System.currentTimeMillis() + T.mins(60).msecs()
}
1 -> {
id = NSALARM
level = NORMAL
text = nsAlarm.title()
if (nsAlarm.low() && sp.getBoolean(R.string.key_nsalarm_low, false) || nsAlarm.high() && sp.getBoolean(R.string.key_nsalarm_high, false) || nsAlarm.timeago() && sp.getBoolean(R.string.key_nsalarm_staledata, false)) soundId = R.raw.alarm
}
2 -> {
id = NSURGENTALARM
level = URGENT
text = nsAlarm.title()
if (nsAlarm.low() && sp.getBoolean(R.string.key_nsalarm_low, false) || nsAlarm.high() && sp.getBoolean(R.string.key_nsalarm_high, false) || nsAlarm.timeago() && sp.getBoolean(R.string.key_nsalarm_staledata, false)) soundId = R.raw.urgentalarm
}
}
buttonText = R.string.snooze
action = Runnable {
NSClientPlugin.getPlugin().handleClearAlarm(nsAlarm, 60 * 60 * 1000L)
// Adding current time to snooze if we got staleData
aapsLogger.debug(LTag.NOTIFICATION, "Notification text is: $text")
val msToSnooze = sp.getInt(R.string.key_nsalarm_staledatavalue, 15) * 60 * 1000L
aapsLogger.debug(LTag.NOTIFICATION, "snooze nsalarm_staledatavalue in minutes is ${T.msecs(msToSnooze).mins()} currentTimeMillis is: ${System.currentTimeMillis()}")
sp.putLong(R.string.key_snoozedTo, System.currentTimeMillis() + msToSnooze)
}
}
fun action(buttonText: Int, action: Runnable?) {
this.buttonText = buttonText
this.action = action
}
}

View file

@ -273,7 +273,7 @@ class SmsCommunicatorPlugin @Inject constructor(
val actualBG = DatabaseHelper.actualBg()
val lastBG = DatabaseHelper.lastBg()
var reply = ""
val units = ProfileFunctions.getSystemUnits()
val units = profileFunction.getUnits()
if (actualBG != null) {
reply = resourceHelper.gs(R.string.sms_actualbg) + " " + actualBG.valueToUnitsToString(units) + ", "
} else if (lastBG != null) {
@ -746,7 +746,7 @@ class SmsCommunicatorPlugin @Inject constructor(
receivedSms.processed = true
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction() {
override fun run() {
val units = ProfileFunctions.getSystemUnits()
val units = profileFunction.getUnits()
var keyDuration = 0
var defaultTargetDuration = 0
var keyTarget = 0

View file

@ -56,6 +56,7 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorP
import info.nightscout.androidaps.plugins.treatments.Treatment;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.DefaultValueHelper;
import info.nightscout.androidaps.utils.ToastUtils;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
@ -65,8 +66,10 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
@Inject public WearPlugin wearPlugin;
@Inject public ResourceHelper resourceHelper;
@Inject public SP sp;
@Inject public ConfigBuilderPlugin configBuilderPlugin;
@Inject public ProfileFunction profileFunction;
@Inject public DefaultValueHelper defaultValueHelper;
@Inject public NSDeviceStatus nsDeviceStatus;
@Inject public ConfigBuilderPlugin configBuilderPlugin;
@Inject public LoopPlugin loopPlugin;
@Inject public IobCobCalculatorPlugin iobCobCalculatorPlugin;
@Inject public TreatmentsPlugin treatmentsPlugin;
@ -295,25 +298,10 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
private DataMap dataMapSingleBG(BgReading lastBG, GlucoseStatus glucoseStatus) {
String units = ProfileFunctions.getSystemUnits();
String units = profileFunction.getUnits();
Double lowLine = OverviewPlugin.INSTANCE.determineLowLine();
Double highLine = OverviewPlugin.INSTANCE.determineHighLine();
// convert to mg/dl
if (!units.equals(Constants.MGDL)) {
lowLine *= Constants.MMOLL_TO_MGDL;
highLine *= Constants.MMOLL_TO_MGDL;
}
if (lowLine < 1) {
lowLine = OverviewPlugin.INSTANCE.getBgTargetLow();
}
if (highLine < 1) {
highLine = OverviewPlugin.INSTANCE.getBgTargetHigh();
}
double lowLine = defaultValueHelper.determineLowLine();
double highLine = defaultValueHelper.determineHighLine();
long sgvLevel = 0L;
if (lastBG.value > highLine) {
@ -447,7 +435,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
double endBasalValue = beginBasalValue;
TemporaryBasal tb1 = treatmentsPlugin.getTempBasalFromHistory(runningTime);
TemporaryBasal tb2 = treatmentsPlugin.getTempBasalFromHistory(runningTime);
TemporaryBasal tb2 = treatmentsPlugin.getTempBasalFromHistory(runningTime); //TODO for Adrian ... what's the meaning?
double tb_before = beginBasalValue;
double tb_amount = beginBasalValue;
long tb_start = runningTime;
@ -721,7 +709,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
//batteries
int phoneBattery = getBatteryLevel(getApplicationContext());
String rigBattery = NSDeviceStatus.getInstance().getUploaderStatus().trim();
String rigBattery = nsDeviceStatus.getUploaderStatus().trim();
long openApsStatus;

View file

@ -927,7 +927,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
ruffyScripter.confirmAlert(activeAlert.warningCode);
} else if (activeAlert.errorCode != null) {
Notification notification = new Notification();
notification.date = new Date();
notification.date = DateUtil.now();
notification.id = Notification.COMBO_PUMP_ALARM;
notification.level = Notification.URGENT;
notification.text = MainApp.gs(R.string.combo_is_in_error_state, activeAlert.errorCode, activeAlert.message);
@ -1030,7 +1030,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
throw new IllegalArgumentException(activeAlert.toString());
}
Notification notification = new Notification();
notification.date = new Date();
notification.date = DateUtil.now();
notification.id = Notification.COMBO_PUMP_ALARM;
notification.level = Notification.NORMAL;
if (activeAlert.warningCode == PumpWarningCodes.CARTRIDGE_LOW) {

View file

@ -1,6 +1,8 @@
package info.nightscout.androidaps.plugins.treatments;
import android.graphics.Color;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.j256.ormlite.field.DatabaseField;
@ -9,28 +11,35 @@ import com.j256.ormlite.table.DatabaseTable;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Date;
import java.util.Objects;
import javax.inject.Inject;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Iob;
import info.nightscout.androidaps.db.DbObjectBase;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.DbObjectBase;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.interfaces.InsulinInterface;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction;
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface;
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.DefaultValueHelper;
import info.nightscout.androidaps.utils.JsonHelper;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
@DatabaseTable(tableName = Treatment.TABLE_TREATMENTS)
public class Treatment implements DataPointWithLabelInterface, DbObjectBase {
@Inject DefaultValueHelper defaultValueHelper;
@Inject ResourceHelper resourceHelper;
@Inject ProfileFunction profileFunction;
@Inject ConfigBuilderPlugin configBuilderPlugin;
public static final String TABLE_TREATMENTS = "Treatments";
@DatabaseField(id = true)
@ -64,6 +73,7 @@ public class Treatment implements DataPointWithLabelInterface, DbObjectBase {
public String boluscalc;
public Treatment() {
MainApp.instance().androidInjector().inject(this); // TODO it will be removed by new database
}
public static Treatment createFromJson(JSONObject json) throws JSONException {
@ -72,11 +82,11 @@ public class Treatment implements DataPointWithLabelInterface, DbObjectBase {
treatment.date = DateUtil.roundDateToSec(JsonHelper.safeGetLong(json, "mills"));
if (treatment.date == 0L)
return null;
treatment.carbs = JsonHelper.safeGetDouble(json,"carbs");
treatment.insulin = JsonHelper.safeGetDouble(json,"insulin");
treatment.carbs = JsonHelper.safeGetDouble(json, "carbs");
treatment.insulin = JsonHelper.safeGetDouble(json, "insulin");
treatment.pumpId = JsonHelper.safeGetLong(json, "pumpId");
treatment._id = json.getString("_id");
treatment.isSMB = JsonHelper.safeGetBoolean(json,"isSMB");
treatment.isSMB = JsonHelper.safeGetBoolean(json, "isSMB");
if (json.has("eventType")) {
treatment.mealBolus = !json.get("eventType").equals("Correction Bolus");
double carbs = treatment.carbs;
@ -93,10 +103,10 @@ public class Treatment implements DataPointWithLabelInterface, DbObjectBase {
return treatment;
}
public String toString() {
@NonNull public String toString() {
return "Treatment{" +
"date= " + date +
", date= " + new Date(date).toLocaleString() +
", date= " + DateUtil.dateAndTimeString(date) +
", isValid= " + isValid +
", isSMB= " + isSMB +
", _id= " + _id +
@ -171,7 +181,7 @@ public class Treatment implements DataPointWithLabelInterface, DbObjectBase {
public double getIc() {
JSONObject bw = getBoluscalc();
if (bw == null || !bw.has("ic")) {
Profile profile = ProfileFunctions.getInstance().getProfile(date);
Profile profile = profileFunction.getProfile(date);
return profile.getIc(date);
}
return JsonHelper.safeGetDouble(bw, "ic");
@ -224,7 +234,7 @@ public class Treatment implements DataPointWithLabelInterface, DbObjectBase {
@Override
public double getY() {
return isSMB ? OverviewPlugin.INSTANCE.determineLowLine() : yValue;
return isSMB ? defaultValueHelper.determineLowLine() : yValue;
}
@Override
@ -257,11 +267,11 @@ public class Treatment implements DataPointWithLabelInterface, DbObjectBase {
@Override
public int getColor() {
if (isSMB)
return MainApp.gc(R.color.tempbasal);
return resourceHelper.gc(R.color.tempbasal);
else if (isValid)
return Color.CYAN;
else
return MainApp.instance().getResources().getColor(android.R.color.holo_red_light);
return resourceHelper.gc(android.R.color.holo_red_light);
}
@Override
@ -275,7 +285,7 @@ public class Treatment implements DataPointWithLabelInterface, DbObjectBase {
if (!isValid)
return new Iob();
InsulinInterface insulinInterface = ConfigBuilderPlugin.getPlugin().getActiveInsulin();
InsulinInterface insulinInterface = configBuilderPlugin.getActiveInsulin();
return insulinInterface.iobCalcForTreatment(this, time, dia);
}

View file

@ -1,52 +0,0 @@
package info.nightscout.androidaps.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSAlarm;
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
import info.nightscout.androidaps.services.Intents;
public class NSAlarmReceiver extends BroadcastReceiver {
private static Logger log = LoggerFactory.getLogger(L.CORE);
@Override
public void onReceive(Context context, Intent intent) {
if (intent == null)
return;
Bundle bundle = intent.getExtras();
String data = bundle.getString("data");
JSONObject json = null;
try {
json = new JSONObject(data);
} catch (JSONException e) {
log.error("Unhandled exception", e);
return;
}
NSAlarm nsAlarm = new NSAlarm(json);
switch (intent.getAction()) {
case Intents.ACTION_ANNOUNCEMENT:
case Intents.ACTION_ALARM:
case Intents.ACTION_URGENT_ALARM:
Notification notification = new Notification(nsAlarm);
if (notification.isEnabled())
RxBus.Companion.getINSTANCE().send(new EventNewNotification(notification));
break;
case Intents.ACTION_CLEAR_ALARM:
RxBus.Companion.getINSTANCE().send(new EventDismissNotification(Notification.NSALARM));
RxBus.Companion.getINSTANCE().send(new EventDismissNotification(Notification.NSURGENTALARM));
break;
}
}
}

View file

@ -14,15 +14,12 @@ import dagger.android.DaggerIntentService;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.events.EventNsFood;
import info.nightscout.androidaps.events.EventNsTreatment;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.BundleLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSMbg;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus;
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin;
@ -89,19 +86,6 @@ public class DataService extends DaggerIntentService {
} else if (Intents.ACTION_NEW_PROFILE.equals(action)) {
// always handle Profile if NSProfile is enabled without looking at nsUploadOnly
NSProfilePlugin.getPlugin().handleNewData(intent);
} else if (Intents.ACTION_NEW_DEVICESTATUS.equals(action)) {
NSDeviceStatus.getInstance().handleNewData(intent);
} else if (Intents.ACTION_NEW_STATUS.equals(action)) {
NSSettingsStatus.getInstance().handleNewData(intent);
} else if (Intents.ACTION_NEW_FOOD.equals(action)) {
EventNsFood evt = new EventNsFood(EventNsFood.Companion.getADD(), bundles);
rxBus.send(evt);
} else if (Intents.ACTION_CHANGED_FOOD.equals(action)) {
EventNsFood evt = new EventNsFood(EventNsFood.Companion.getUPDATE(), bundles);
rxBus.send(evt);
} else if (Intents.ACTION_REMOVED_FOOD.equals(action)) {
EventNsFood evt = new EventNsFood(EventNsFood.Companion.getREMOVE(), bundles);
rxBus.send(evt);
} else if (acceptNSData &&
(Intents.ACTION_NEW_TREATMENT.equals(action) ||
Intents.ACTION_CHANGED_TREATMENT.equals(action) ||

View file

@ -7,22 +7,10 @@ public interface Intents {
String ACTION_REMOVED_TREATMENT = "info.nightscout.client.REMOVED_TREATMENT";
String ACTION_NEW_PROFILE = "info.nightscout.client.NEW_PROFILE";
String ACTION_NEW_SGV = "info.nightscout.client.NEW_SGV";
String ACTION_NEW_DEVICESTATUS = "info.nightscout.client.NEW_DEVICESTATUS";
String ACTION_NEW_FOOD = "info.nightscout.client.NEW_FOOD";
String ACTION_CHANGED_FOOD = "info.nightscout.client.CHANGED_FOOD";
String ACTION_REMOVED_FOOD = "info.nightscout.client.REMOVED_FOOD";
String ACTION_NEW_MBG = "info.nightscout.client.NEW_MBG";
String ACTION_NEW_CAL = "info.nightscout.client.NEW_CAL";
String ACTION_NEW_STATUS = "info.nightscout.client.NEW_STATUS";
String ACTION_QUEUE_STATUS = "info.nightscout.client.QUEUE_STATUS";
String ACTION_ANNOUNCEMENT = "info.nightscout.client.ANNOUNCEMENT";
String ACTION_ALARM = "info.nightscout.client.ALARM";
String ACTION_URGENT_ALARM = "info.nightscout.client.URGENT_ALARM";
String ACTION_CLEAR_ALARM = "info.nightscout.client.CLEAR_ALARM";
// xDrip -> App
String RECEIVER_PERMISSION = "com.eveningoutpost.dexdrip.permissions.RECEIVE_BG_ESTIMATE";
String ACTION_NEW_BG_ESTIMATE = "com.eveningoutpost.dexdrip.BgEstimate";
String EXTRA_BG_ESTIMATE = "com.eveningoutpost.dexdrip.Extras.BgEstimate";
String EXTRA_BG_SLOPE = "com.eveningoutpost.dexdrip.Extras.BgSlope";

View file

@ -83,7 +83,7 @@ public class AndroidPermission {
public static synchronized void notifyForSMSPermissions(Activity activity, SmsCommunicatorPlugin smsCommunicatorPlugin) {
if (smsCommunicatorPlugin.isEnabled(PluginType.GENERAL)) {
if (permissionNotGranted(activity, Manifest.permission.RECEIVE_SMS)) {
NotificationWithAction notification = new NotificationWithAction(Notification.PERMISSION_SMS, MainApp.gs(R.string.smscommunicator_missingsmspermission), Notification.URGENT);
NotificationWithAction notification = new NotificationWithAction(MainApp.instance(), Notification.PERMISSION_SMS, MainApp.gs(R.string.smscommunicator_missingsmspermission), Notification.URGENT);
notification.action(R.string.request, () -> AndroidPermission.askForPermission(activity, new String[]{Manifest.permission.RECEIVE_SMS,
Manifest.permission.SEND_SMS,
Manifest.permission.RECEIVE_MMS}, AndroidPermission.CASE_SMS));
@ -93,7 +93,7 @@ public class AndroidPermission {
// Following is a bug in Android 8
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O) {
if (permissionNotGranted(activity, Manifest.permission.READ_PHONE_STATE)) {
NotificationWithAction notification = new NotificationWithAction(Notification.PERMISSION_PHONESTATE, MainApp.gs(R.string.smscommunicator_missingphonestatepermission), Notification.URGENT);
NotificationWithAction notification = new NotificationWithAction(MainApp.instance(), Notification.PERMISSION_PHONESTATE, MainApp.gs(R.string.smscommunicator_missingphonestatepermission), Notification.URGENT);
notification.action(R.string.request, () ->
AndroidPermission.askForPermission(activity, new String[]{Manifest.permission.READ_PHONE_STATE}, AndroidPermission.CASE_PHONE_STATE));
RxBus.Companion.getINSTANCE().send(new EventNewNotification(notification));
@ -105,7 +105,7 @@ public class AndroidPermission {
public static synchronized void notifyForBatteryOptimizationPermission(Activity activity) {
if (permissionNotGranted(activity, Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)) {
NotificationWithAction notification = new NotificationWithAction(Notification.PERMISSION_BATTERY, String.format(MainApp.gs(R.string.needwhitelisting), MainApp.gs(R.string.app_name)), Notification.URGENT);
NotificationWithAction notification = new NotificationWithAction(MainApp.instance(), Notification.PERMISSION_BATTERY, String.format(MainApp.gs(R.string.needwhitelisting), MainApp.gs(R.string.app_name)), Notification.URGENT);
notification.action(R.string.request, () -> AndroidPermission.askForPermission(activity, new String[]{Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS}, AndroidPermission.CASE_BATTERY));
RxBus.Companion.getINSTANCE().send(new EventNewNotification(notification));
} else
@ -114,7 +114,7 @@ public class AndroidPermission {
public static synchronized void notifyForStoragePermission(Activity activity) {
if (permissionNotGranted(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
NotificationWithAction notification = new NotificationWithAction(Notification.PERMISSION_STORAGE, MainApp.gs(R.string.needstoragepermission), Notification.URGENT);
NotificationWithAction notification = new NotificationWithAction(MainApp.instance(), Notification.PERMISSION_STORAGE, MainApp.gs(R.string.needstoragepermission), Notification.URGENT);
notification.action(R.string.request, () -> AndroidPermission.askForPermission(activity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE}, AndroidPermission.CASE_STORAGE));
RxBus.Companion.getINSTANCE().send(new EventNewNotification(notification));
@ -124,7 +124,7 @@ public class AndroidPermission {
public static synchronized void notifyForLocationPermissions(Activity activity) {
if (permissionNotGranted(activity, Manifest.permission.ACCESS_FINE_LOCATION)) {
NotificationWithAction notification = new NotificationWithAction(Notification.PERMISSION_LOCATION, MainApp.gs(R.string.needlocationpermission), Notification.URGENT);
NotificationWithAction notification = new NotificationWithAction(MainApp.instance(), Notification.PERMISSION_LOCATION, MainApp.gs(R.string.needlocationpermission), Notification.URGENT);
notification.action(R.string.request, () -> AndroidPermission.askForPermission(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, AndroidPermission.CASE_LOCATION));
RxBus.Companion.getINSTANCE().send(new EventNewNotification(notification));
} else

View file

@ -3,16 +3,24 @@ package info.nightscout.androidaps.utils
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
import info.nightscout.androidaps.utils.sharedPreferences.SP
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class DefaultValueHelper @Inject constructor(
private val sp: SP,
private val profileFunction: ProfileFunction
) {
object DefaultValueHelper {
/**
* returns the corresponding EatingSoon TempTarget based on the given units (MMOL / MGDL)
*
* @param units
* @return
*/
fun getDefaultEatingSoonTT(units: String): Double {
private fun getDefaultEatingSoonTT(units: String): Double {
return if (Constants.MMOL == units) Constants.defaultEatingSoonTTmmol else Constants.defaultEatingSoonTTmgdl
}
@ -22,7 +30,7 @@ object DefaultValueHelper {
* @param units
* @return
*/
fun getDefaultActivityTT(units: String): Double {
private fun getDefaultActivityTT(units: String): Double {
return if (Constants.MMOL == units) Constants.defaultActivityTTmmol else Constants.defaultActivityTTmgdl
}
@ -32,7 +40,7 @@ object DefaultValueHelper {
* @param units
* @return
*/
fun getDefaultHypoTT(units: String): Double {
private fun getDefaultHypoTT(units: String): Double {
return if (Constants.MMOL == units) Constants.defaultHypoTTmmol else Constants.defaultHypoTTmgdl
}
@ -41,17 +49,15 @@ object DefaultValueHelper {
*
* @return
*/
@JvmStatic
fun determineEatingSoonTT(): Double {
val units = ProfileFunctions.getSystemUnits()
var value = SP.getDouble(R.string.key_eatingsoon_target, getDefaultEatingSoonTT(units))
val units = profileFunction.getUnits()
var value = sp.getDouble(R.string.key_eatingsoon_target, getDefaultEatingSoonTT(units))
value = Profile.toCurrentUnits(value)
return if (value > 0) value else getDefaultEatingSoonTT(units)
}
@JvmStatic
fun determineEatingSoonTTDuration(): Int {
val value = SP.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration)
val value = sp.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration)
return if (value > 0) value else Constants.defaultEatingSoonTTDuration
}
@ -60,17 +66,15 @@ object DefaultValueHelper {
*
* @return
*/
@JvmStatic
fun determineActivityTT(): Double {
val units = ProfileFunctions.getSystemUnits()
var value = SP.getDouble(R.string.key_activity_target, getDefaultActivityTT(units))
val units = profileFunction.getUnits()
var value = sp.getDouble(R.string.key_activity_target, getDefaultActivityTT(units))
value = Profile.toCurrentUnits(value)
return if (value > 0) value else getDefaultActivityTT(units)
}
@JvmStatic
fun determineActivityTTDuration(): Int {
val value = SP.getInt(R.string.key_activity_duration, Constants.defaultActivityTTDuration)
val value = sp.getInt(R.string.key_activity_duration, Constants.defaultActivityTTDuration)
return if (value > 0) value else Constants.defaultActivityTTDuration
}
@ -79,17 +83,32 @@ object DefaultValueHelper {
*
* @return
*/
@JvmStatic
fun determineHypoTT(): Double {
val units = ProfileFunctions.getSystemUnits()
var value = SP.getDouble(R.string.key_hypo_target, getDefaultHypoTT(units))
val units = profileFunction.getUnits()
var value = sp.getDouble(R.string.key_hypo_target, getDefaultHypoTT(units))
value = Profile.toCurrentUnits(value)
return if (value > 0) value else getDefaultHypoTT(units)
}
@JvmStatic
fun determineHypoTTDuration(): Int {
val value = SP.getInt(R.string.key_hypo_duration, Constants.defaultHypoTTDuration)
val value = sp.getInt(R.string.key_hypo_duration, Constants.defaultHypoTTDuration)
return if (value > 0) value else Constants.defaultHypoTTDuration
}
var bgTargetLow = 80.0
var bgTargetHigh = 180.0
fun determineHighLine(): Double {
var highLineSetting = sp.getDouble(R.string.key_high_mark, bgTargetHigh)
if (highLineSetting < 1) highLineSetting = Constants.HIGHMARK
highLineSetting = Profile.toCurrentUnits(highLineSetting)
return highLineSetting
}
fun determineLowLine(): Double {
var lowLineSetting = sp.getDouble(R.string.key_low_mark, bgTargetLow)
if (lowLineSetting < 1) lowLineSetting = Constants.LOWMARK
lowLineSetting = Profile.toCurrentUnits(lowLineSetting)
return lowLineSetting
}
}

View file

@ -1,9 +1,31 @@
package info.nightscout.androidaps.utils
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
object JsonHelper {
@JvmStatic
fun createJSONObject(s : String?) : JSONObject? {
var result : JSONObject? = null
try {
result = JSONObject(s)
} catch (ignored: JSONException) {
}
return result
}
@JvmStatic
fun createJSONArray(s : String?) : JSONArray? {
var result : JSONArray? = null
try {
result = JSONArray(s)
} catch (ignored: JSONException) {
}
return result
}
@JvmStatic
fun safeGetObject(json: JSONObject?, fieldName: String, defaultValue: Any): Any {
var result = defaultValue
@ -76,6 +98,18 @@ object JsonHelper {
return result
}
@JvmStatic
fun safeGetDoubleAllowNull(json: JSONObject?, fieldName: String): Double? {
var result: Double? = null
if (json != null && json.has(fieldName)) {
try {
result = json.getDouble(fieldName)
} catch (ignored: JSONException) {
}
}
return result
}
@JvmStatic
fun safeGetDouble(json: JSONObject?, fieldName: String, defaultValue: Double): Double {
var result = defaultValue

View file

@ -9,4 +9,5 @@ interface ResourceHelper {
fun gs(@StringRes id: Int, vararg args: Any?): String
fun gq(@PluralsRes id: Int, quantity: Int, vararg args: Any?): String
fun gc(@ColorRes id: Int): Int
fun gcs(@ColorRes id: Int): String
}

View file

@ -1,5 +1,6 @@
package info.nightscout.androidaps.utils.resources
import android.annotation.SuppressLint
import androidx.annotation.ColorRes
import androidx.annotation.PluralsRes
import androidx.annotation.StringRes
@ -20,4 +21,8 @@ class ResourceHelperImplementation @Inject constructor(private val mainApp: Main
mainApp.resources.getQuantityString(id, quantity, *args)
override fun gc(@ColorRes id: Int): Int = ContextCompat.getColor(mainApp, id)
@SuppressLint("ResourceType")
override fun gcs(@ColorRes id: Int): String =
gs(id).replace("#ff", "#")
}

View file

@ -16,12 +16,6 @@
android:layout_height="wrap_content"
android:orientation="vertical">
<include
android:id="@+id/careportal_stats"
layout="@layout/careportal_stats_fragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/profileview_noprofile"
android:layout_width="match_parent"

View file

@ -194,9 +194,7 @@
<string name="enableloop">Enable loop</string>
<string name="openloop_newsuggestion">New suggestion available</string>
<string name="unsupportedclientver">Unsupported version of NSClient</string>
<string name="unsupportednsversion">Unsupported version of Nightscout</string>
<string name="nsclientnotinstalled">NSClient not installed. Record lost!</string>
<string name="loopdisabled">LOOP DISABLED BY CONSTRAINTS</string>
<string name="treatments_wizard_basaliob_label">Basal IOB</string>
<string name="bolusconstraintapplied">Bolus constraint applied</string>
@ -1690,5 +1688,6 @@
<string name="key_xdripstatus_detailediob" translatable="false">xdripstatus_detailediob</string>
<string name="key_xdripstatus_showbgi" translatable="false">xdripstatus_showbgi</string>
<string name="key_wear_detailed_delta" translatable="false">wear_detailed_delta</string>
<string name="key_snoozedTo" translatable="false">snoozedTo</string>
</resources>

View file

@ -16,12 +16,12 @@ public class MaintenancePluginTest {
public void getLogfilesTest() {
String logDirectory = "src/test/res/logger";
List<File> logs = sut.getLogfiles(logDirectory, 2);
List<File> logs = sut.getLogFiles(logDirectory, 2);
assertEquals(2, logs.size());
assertEquals("AndroidAPS.log", logs.get(0).getName());
assertEquals("AndroidAPS.2018-01-03_01-01-00.1.zip", logs.get(1).getName());
logs = sut.getLogfiles(logDirectory, 10);
logs = sut.getLogFiles(logDirectory, 10);
assertEquals(4, logs.size());
}
@ -29,7 +29,7 @@ public class MaintenancePluginTest {
@Test
public void zipLogsTest() {
String logDirectory = "src/test/res/logger";
List<File> logs = sut.getLogfiles(logDirectory, 2);
List<File> logs = sut.getLogFiles(logDirectory, 2);
String name = "AndroidAPS.log.zip";