commit
f343d88ca7
|
@ -43,6 +43,7 @@ android {
|
||||||
applicationId "info.nightscout.androidaps"
|
applicationId "info.nightscout.androidaps"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 23
|
targetSdkVersion 23
|
||||||
|
multiDexEnabled true
|
||||||
versionCode 1500
|
versionCode 1500
|
||||||
version "1.54-dev"
|
version "1.54-dev"
|
||||||
buildConfigField "String", "VERSION", '"' + version + '"'
|
buildConfigField "String", "VERSION", '"' + version + '"'
|
||||||
|
|
BIN
app/libs/rhino-1.7.7.2.jar
Normal file
BIN
app/libs/rhino-1.7.7.2.jar
Normal file
Binary file not shown.
12
app/src/main/assets/OpenAPSAMA/loggerhelper.js
Normal file
12
app/src/main/assets/OpenAPSAMA/loggerhelper.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
var console = { };
|
||||||
|
console.error = function error(){
|
||||||
|
for (var i = 0, len = arguments.length; i < len; i++) {
|
||||||
|
console2.log(arguments[i]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log = function log(){
|
||||||
|
for (var i = 0, len = arguments.length; i < len; i++) {
|
||||||
|
console2.log(arguments[i]);
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,16 +1,22 @@
|
||||||
package info.nightscout.androidaps.plugins.OpenAPSAMA;
|
package info.nightscout.androidaps.plugins.OpenAPSAMA;
|
||||||
|
|
||||||
import com.eclipsesource.v8.JavaVoidCallback;
|
import org.json.JSONArray;
|
||||||
import com.eclipsesource.v8.V8;
|
|
||||||
import com.eclipsesource.v8.V8Array;
|
|
||||||
import com.eclipsesource.v8.V8Object;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
import org.mozilla.javascript.Callable;
|
||||||
|
import org.mozilla.javascript.Context;
|
||||||
|
import org.mozilla.javascript.Function;
|
||||||
|
import org.mozilla.javascript.NativeJSON;
|
||||||
|
import org.mozilla.javascript.NativeObject;
|
||||||
|
import org.mozilla.javascript.RhinoException;
|
||||||
|
import org.mozilla.javascript.Scriptable;
|
||||||
|
import org.mozilla.javascript.ScriptableObject;
|
||||||
|
import org.mozilla.javascript.Undefined;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Config;
|
import info.nightscout.androidaps.Config;
|
||||||
|
@ -24,6 +30,7 @@ import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
|
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
|
import info.nightscout.androidaps.plugins.OpenAPSMA.LoggerCallback;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
|
||||||
public class DetermineBasalAdapterAMAJS {
|
public class DetermineBasalAdapterAMAJS {
|
||||||
|
@ -31,20 +38,13 @@ public class DetermineBasalAdapterAMAJS {
|
||||||
|
|
||||||
|
|
||||||
private ScriptReader mScriptReader = null;
|
private ScriptReader mScriptReader = null;
|
||||||
V8 mV8rt;
|
|
||||||
private V8Object mProfile;
|
|
||||||
private V8Object mGlucoseStatus;
|
|
||||||
private V8Array mIobData;
|
|
||||||
private V8Object mMealData;
|
|
||||||
private V8Object mCurrentTemp;
|
|
||||||
private V8Object mAutosensData = null;
|
|
||||||
|
|
||||||
private final String PARAM_currentTemp = "currentTemp";
|
private JSONObject mProfile;
|
||||||
private final String PARAM_iobData = "iobData";
|
private JSONObject mGlucoseStatus;
|
||||||
private final String PARAM_glucoseStatus = "glucose_status";
|
private JSONArray mIobData;
|
||||||
private final String PARAM_profile = "profile";
|
private JSONObject mMealData;
|
||||||
private final String PARAM_meal_data = "meal_data";
|
private JSONObject mCurrentTemp;
|
||||||
private final String PARAM_autosens_data = "autosens_data";
|
private JSONObject mAutosensData = null;
|
||||||
|
|
||||||
private String storedCurrentTemp = null;
|
private String storedCurrentTemp = null;
|
||||||
private String storedIobData = null;
|
private String storedIobData = null;
|
||||||
|
@ -55,58 +55,101 @@ public class DetermineBasalAdapterAMAJS {
|
||||||
|
|
||||||
private String scriptDebug = "";
|
private String scriptDebug = "";
|
||||||
|
|
||||||
/**
|
|
||||||
* Main code
|
|
||||||
*/
|
|
||||||
|
|
||||||
public DetermineBasalAdapterAMAJS(ScriptReader scriptReader) throws IOException {
|
public DetermineBasalAdapterAMAJS(ScriptReader scriptReader) throws IOException {
|
||||||
mV8rt = V8.createV8Runtime();
|
|
||||||
mScriptReader = scriptReader;
|
mScriptReader = scriptReader;
|
||||||
|
|
||||||
initLogCallback();
|
|
||||||
initProcessExitCallback();
|
|
||||||
initModuleParent();
|
|
||||||
loadScript();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DetermineBasalResultAMA invoke() {
|
public DetermineBasalResultAMA invoke() {
|
||||||
|
|
||||||
|
|
||||||
log.debug(">>> Invoking detemine_basal <<<");
|
log.debug(">>> Invoking detemine_basal <<<");
|
||||||
log.debug("Glucose status: " + (storedGlucoseStatus = mV8rt.executeStringScript("JSON.stringify(" + PARAM_glucoseStatus + ");")));
|
log.debug("Glucose status: " + (storedGlucoseStatus = mGlucoseStatus.toString()));
|
||||||
log.debug("IOB data: " + (storedIobData = mV8rt.executeStringScript("JSON.stringify(" + PARAM_iobData + ");")));
|
log.debug("IOB data: " + (storedIobData = mIobData.toString()));
|
||||||
log.debug("Current temp: " + (storedCurrentTemp = mV8rt.executeStringScript("JSON.stringify(" + PARAM_currentTemp + ");")));
|
log.debug("Current temp: " + (storedCurrentTemp = mCurrentTemp.toString()));
|
||||||
log.debug("Profile: " + (storedProfile = mV8rt.executeStringScript("JSON.stringify(" + PARAM_profile + ");")));
|
log.debug("Profile: " + (storedProfile = mProfile.toString()));
|
||||||
log.debug("Meal data: " + (storedMeal_data = mV8rt.executeStringScript("JSON.stringify(" + PARAM_meal_data + ");")));
|
log.debug("Meal data: " + (storedMeal_data = mMealData.toString()));
|
||||||
if (mAutosensData != null)
|
if (mAutosensData != null)
|
||||||
log.debug("Autosens data: " + (storedAutosens_data = mV8rt.executeStringScript("JSON.stringify(" + PARAM_autosens_data + ");")));
|
log.debug("Autosens data: " + (storedAutosens_data = mAutosensData.toString()));
|
||||||
else
|
else
|
||||||
log.debug("Autosens data: " + (storedAutosens_data = "undefined"));
|
log.debug("Autosens data: " + (storedAutosens_data = "undefined"));
|
||||||
|
|
||||||
mV8rt.executeVoidScript(
|
DetermineBasalResultAMA determineBasalResultAMA = null;
|
||||||
"var rT = determine_basal(" +
|
|
||||||
PARAM_glucoseStatus + ", " +
|
|
||||||
PARAM_currentTemp + ", " +
|
|
||||||
PARAM_iobData + ", " +
|
|
||||||
PARAM_profile + ", " +
|
|
||||||
PARAM_autosens_data + ", " +
|
|
||||||
PARAM_meal_data + ", " +
|
|
||||||
"tempBasalFunctions" +
|
|
||||||
");");
|
|
||||||
|
|
||||||
|
Context rhino = Context.enter();
|
||||||
|
Scriptable scope = rhino.initStandardObjects();
|
||||||
|
// Turn off optimization to make Rhino Android compatible
|
||||||
|
rhino.setOptimizationLevel(-1);
|
||||||
|
|
||||||
String ret = mV8rt.executeStringScript("JSON.stringify(rT);");
|
|
||||||
log.debug("Result: " + ret);
|
|
||||||
|
|
||||||
V8Object v8ObjectReuslt = mV8rt.getObject("rT");
|
|
||||||
|
|
||||||
DetermineBasalResultAMA result = null;
|
|
||||||
try {
|
try {
|
||||||
result = new DetermineBasalResultAMA(v8ObjectReuslt, new JSONObject(ret));
|
|
||||||
} catch (JSONException e) {
|
//register logger callback for console.log and console.error
|
||||||
log.error("Unhandled exception", e);
|
ScriptableObject.defineClass(scope, LoggerCallback.class);
|
||||||
|
Scriptable myLogger = rhino.newObject(scope, "LoggerCallback", null);
|
||||||
|
scope.put("console2", scope, myLogger);
|
||||||
|
rhino.evaluateString(scope, readFile("OpenAPSAMA/loggerhelper.js"), "JavaScript", 0, null);
|
||||||
|
|
||||||
|
//set module parent
|
||||||
|
rhino.evaluateString(scope, "var module = {\"parent\":Boolean(1)};", "JavaScript", 0, null);
|
||||||
|
rhino.evaluateString(scope, "var round_basal = function round_basal(basal, profile) { return basal; };", "JavaScript", 0, null);
|
||||||
|
rhino.evaluateString(scope, "require = function() {return round_basal;};", "JavaScript", 0, null);
|
||||||
|
|
||||||
|
//generate functions "determine_basal" and "setTempBasal"
|
||||||
|
rhino.evaluateString(scope, readFile("OpenAPSAMA/determine-basal.js"), "JavaScript", 0, null);
|
||||||
|
rhino.evaluateString(scope, readFile("OpenAPSAMA/basal-set-temp.js"), "setTempBasal.js", 0, null);
|
||||||
|
Object determineBasalObj = scope.get("determine_basal", scope);
|
||||||
|
Object setTempBasalFunctionsObj = scope.get("tempBasalFunctions", scope);
|
||||||
|
|
||||||
|
//call determine-basal
|
||||||
|
if (determineBasalObj instanceof Function && setTempBasalFunctionsObj instanceof NativeObject) {
|
||||||
|
Function determineBasalJS = (Function) determineBasalObj;
|
||||||
|
|
||||||
|
//prepare parameters
|
||||||
|
Object[] params = new Object[]{
|
||||||
|
makeParam(mGlucoseStatus, rhino, scope),
|
||||||
|
makeParam(mCurrentTemp, rhino, scope),
|
||||||
|
makeParamArray(mIobData, rhino, scope),
|
||||||
|
makeParam(mProfile, rhino, scope),
|
||||||
|
makeParam(mAutosensData, rhino, scope),
|
||||||
|
makeParam(mMealData, rhino, scope),
|
||||||
|
setTempBasalFunctionsObj};
|
||||||
|
|
||||||
|
NativeObject jsResult = (NativeObject) determineBasalJS.call(rhino, scope, scope, params);
|
||||||
|
scriptDebug = LoggerCallback.getScriptDebug();
|
||||||
|
|
||||||
|
// Parse the jsResult object to a JSON-String
|
||||||
|
String result = NativeJSON.stringify(rhino, scope, jsResult, null, null).toString();
|
||||||
|
if (Config.logAPSResult)
|
||||||
|
log.debug("Result: " + result);
|
||||||
|
try {
|
||||||
|
determineBasalResultAMA = new DetermineBasalResultAMA(jsResult, new JSONObject(result));
|
||||||
|
} catch (JSONException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.debug("Problem loading JS Functions");
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.debug("IOException");
|
||||||
|
} catch (RhinoException e) {
|
||||||
|
log.error("RhinoException: (" + e.lineNumber() + "," + e.columnNumber() + ") " + e.toString());
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
log.error(e.toString());
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
log.error(e.toString());
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
log.error(e.toString());
|
||||||
|
} finally {
|
||||||
|
Context.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
storedGlucoseStatus = mGlucoseStatus.toString();
|
||||||
|
storedIobData = mIobData.toString();
|
||||||
|
storedCurrentTemp = mCurrentTemp.toString();
|
||||||
|
storedProfile = mProfile.toString();
|
||||||
|
storedMeal_data = mMealData.toString();
|
||||||
|
|
||||||
|
return determineBasalResultAMA;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String getGlucoseStatusParam() {
|
String getGlucoseStatusParam() {
|
||||||
|
@ -137,60 +180,6 @@ public class DetermineBasalAdapterAMAJS {
|
||||||
return scriptDebug;
|
return scriptDebug;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadScript() throws IOException {
|
|
||||||
mV8rt.executeVoidScript("var round_basal = function round_basal(basal, profile) { return basal; };");
|
|
||||||
mV8rt.executeVoidScript("require = function() {return round_basal;};");
|
|
||||||
|
|
||||||
mV8rt.executeVoidScript(readFile("OpenAPSAMA/basal-set-temp.js"), "OpenAPSAMA/basal-set-temp.js ", 0);
|
|
||||||
mV8rt.executeVoidScript("var tempBasalFunctions = module.exports;");
|
|
||||||
|
|
||||||
mV8rt.executeVoidScript(
|
|
||||||
readFile("OpenAPSAMA/determine-basal.js"),
|
|
||||||
"OpenAPSAMA/determine-basal.js",
|
|
||||||
0);
|
|
||||||
mV8rt.executeVoidScript("var determine_basal = module.exports;");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initModuleParent() {
|
|
||||||
mV8rt.executeVoidScript("var module = {\"parent\":Boolean(1)};");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initProcessExitCallback() {
|
|
||||||
JavaVoidCallback callbackProccessExit = new JavaVoidCallback() {
|
|
||||||
@Override
|
|
||||||
public void invoke(V8Object arg0, V8Array parameters) {
|
|
||||||
if (parameters.length() > 0) {
|
|
||||||
Object arg1 = parameters.get(0);
|
|
||||||
log.error("ProccessExit " + arg1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
mV8rt.registerJavaMethod(callbackProccessExit, "proccessExit");
|
|
||||||
mV8rt.executeVoidScript("var process = {\"exit\": function () { proccessExit(); } };");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initLogCallback() {
|
|
||||||
JavaVoidCallback callbackLog = new JavaVoidCallback() {
|
|
||||||
@Override
|
|
||||||
public void invoke(V8Object arg0, V8Array parameters) {
|
|
||||||
int i = 0;
|
|
||||||
String s = "";
|
|
||||||
while (i < parameters.length()) {
|
|
||||||
Object arg = parameters.get(i);
|
|
||||||
s += arg + " ";
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
if (!s.equals("") && Config.logAPSResult) {
|
|
||||||
log.debug("Script debug: " + s);
|
|
||||||
scriptDebug += s + "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
mV8rt.registerJavaMethod(callbackLog, "log");
|
|
||||||
mV8rt.executeVoidScript("var console = {\"log\":log, \"error\":log};");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setData(Profile profile,
|
public void setData(Profile profile,
|
||||||
double maxIob,
|
double maxIob,
|
||||||
double maxBasal,
|
double maxBasal,
|
||||||
|
@ -203,89 +192,94 @@ public class DetermineBasalAdapterAMAJS {
|
||||||
MealData mealData,
|
MealData mealData,
|
||||||
double autosensDataRatio,
|
double autosensDataRatio,
|
||||||
boolean tempTargetSet,
|
boolean tempTargetSet,
|
||||||
double min_5m_carbimpact) {
|
double min_5m_carbimpact) throws JSONException {
|
||||||
|
|
||||||
String units = profile.getUnits();
|
String units = profile.getUnits();
|
||||||
|
|
||||||
mProfile = new V8Object(mV8rt);
|
mProfile = new JSONObject();
|
||||||
mProfile.add("max_iob", maxIob);
|
mProfile.put("max_iob", maxIob);
|
||||||
mProfile.add("dia", Math.min(profile.getDia(), 3d));
|
mProfile.put("dia", Math.min(profile.getDia(), 3d));
|
||||||
mProfile.add("type", "current");
|
mProfile.put("type", "current");
|
||||||
mProfile.add("max_daily_basal", profile.getMaxDailyBasal());
|
mProfile.put("max_daily_basal", profile.getMaxDailyBasal());
|
||||||
mProfile.add("max_basal", maxBasal);
|
mProfile.put("max_basal", maxBasal);
|
||||||
mProfile.add("min_bg", minBg);
|
mProfile.put("min_bg", minBg);
|
||||||
mProfile.add("max_bg", maxBg);
|
mProfile.put("max_bg", maxBg);
|
||||||
mProfile.add("target_bg", targetBg);
|
mProfile.put("target_bg", targetBg);
|
||||||
mProfile.add("carb_ratio", profile.getIc());
|
mProfile.put("carb_ratio", profile.getIc());
|
||||||
mProfile.add("sens", Profile.toMgdl(profile.getIsf().doubleValue(), units));
|
mProfile.put("sens", Profile.toMgdl(profile.getIsf().doubleValue(), units));
|
||||||
mProfile.add("max_daily_safety_multiplier", SP.getInt("openapsama_max_daily_safety_multiplier", 3));
|
mProfile.put("max_daily_safety_multiplier", SP.getInt("openapsama_max_daily_safety_multiplier", 3));
|
||||||
mProfile.add("current_basal_safety_multiplier", SP.getInt("openapsama_current_basal_safety_multiplier", 4));
|
mProfile.put("current_basal_safety_multiplier", SP.getInt("openapsama_current_basal_safety_multiplier", 4));
|
||||||
mProfile.add("skip_neutral_temps", true);
|
mProfile.put("skip_neutral_temps", true);
|
||||||
mProfile.add("current_basal", pump.getBaseBasalRate());
|
mProfile.put("current_basal", pump.getBaseBasalRate());
|
||||||
mProfile.add("temptargetSet", tempTargetSet);
|
mProfile.put("temptargetSet", tempTargetSet);
|
||||||
mProfile.add("autosens_adjust_targets", SP.getBoolean("openapsama_autosens_adjusttargets", true));
|
mProfile.put("autosens_adjust_targets", SP.getBoolean("openapsama_autosens_adjusttargets", true));
|
||||||
mProfile.add("min_5m_carbimpact", SP.getDouble("openapsama_min_5m_carbimpact", 3d));
|
mProfile.put("min_5m_carbimpact", SP.getDouble("openapsama_min_5m_carbimpact", 3d));
|
||||||
|
|
||||||
if (units.equals(Constants.MMOL)) {
|
if (units.equals(Constants.MMOL)) {
|
||||||
mProfile.add("out_units", "mmol/L");
|
mProfile.put("out_units", "mmol/L");
|
||||||
}
|
}
|
||||||
|
|
||||||
mV8rt.add(PARAM_profile, mProfile);
|
|
||||||
|
|
||||||
mCurrentTemp = new V8Object(mV8rt);
|
mCurrentTemp = new JSONObject();
|
||||||
mCurrentTemp.add("temp", "absolute");
|
mCurrentTemp.put("temp", "absolute");
|
||||||
mCurrentTemp.add("duration", MainApp.getConfigBuilder().getTempBasalRemainingMinutesFromHistory());
|
mCurrentTemp.put("duration", MainApp.getConfigBuilder().getTempBasalRemainingMinutesFromHistory());
|
||||||
mCurrentTemp.add("rate", MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory());
|
mCurrentTemp.put("rate", MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory());
|
||||||
|
|
||||||
// as we have non default temps longer than 30 mintues
|
// as we have non default temps longer than 30 mintues
|
||||||
TemporaryBasal tempBasal = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
|
TemporaryBasal tempBasal = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
|
||||||
if (tempBasal != null) {
|
if (tempBasal != null) {
|
||||||
mCurrentTemp.add("minutesrunning", tempBasal.getRealDuration());
|
mCurrentTemp.put("minutesrunning", tempBasal.getRealDuration());
|
||||||
}
|
}
|
||||||
|
|
||||||
mV8rt.add(PARAM_currentTemp, mCurrentTemp);
|
mIobData = IobCobCalculatorPlugin.convertToJSONArray(iobArray);
|
||||||
|
|
||||||
mIobData = mV8rt.executeArrayScript(IobCobCalculatorPlugin.convertToJSONArray(iobArray).toString());
|
mGlucoseStatus = new JSONObject();
|
||||||
mV8rt.add(PARAM_iobData, mIobData);
|
mGlucoseStatus.put("glucose", glucoseStatus.glucose);
|
||||||
|
|
||||||
mGlucoseStatus = new V8Object(mV8rt);
|
|
||||||
mGlucoseStatus.add("glucose", glucoseStatus.glucose);
|
|
||||||
|
|
||||||
if (SP.getBoolean("always_use_shortavg", false)) {
|
if (SP.getBoolean("always_use_shortavg", false)) {
|
||||||
mGlucoseStatus.add("delta", glucoseStatus.short_avgdelta);
|
mGlucoseStatus.put("delta", glucoseStatus.short_avgdelta);
|
||||||
} else {
|
} else {
|
||||||
mGlucoseStatus.add("delta", glucoseStatus.delta);
|
mGlucoseStatus.put("delta", glucoseStatus.delta);
|
||||||
}
|
}
|
||||||
mGlucoseStatus.add("short_avgdelta", glucoseStatus.short_avgdelta);
|
mGlucoseStatus.put("short_avgdelta", glucoseStatus.short_avgdelta);
|
||||||
mGlucoseStatus.add("long_avgdelta", glucoseStatus.long_avgdelta);
|
mGlucoseStatus.put("long_avgdelta", glucoseStatus.long_avgdelta);
|
||||||
mV8rt.add(PARAM_glucoseStatus, mGlucoseStatus);
|
|
||||||
|
|
||||||
mMealData = new V8Object(mV8rt);
|
mMealData = new JSONObject();
|
||||||
mMealData.add("carbs", mealData.carbs);
|
mMealData.put("carbs", mealData.carbs);
|
||||||
mMealData.add("boluses", mealData.boluses);
|
mMealData.put("boluses", mealData.boluses);
|
||||||
mMealData.add("mealCOB", mealData.mealCOB);
|
mMealData.put("mealCOB", mealData.mealCOB);
|
||||||
mV8rt.add(PARAM_meal_data, mMealData);
|
|
||||||
|
|
||||||
if (MainApp.getConfigBuilder().isAMAModeEnabled()) {
|
if (MainApp.getConfigBuilder().isAMAModeEnabled()) {
|
||||||
mAutosensData = new V8Object(mV8rt);
|
mAutosensData = new JSONObject();
|
||||||
mAutosensData.add("ratio", autosensDataRatio);
|
mAutosensData.put("ratio", autosensDataRatio);
|
||||||
mV8rt.add(PARAM_autosens_data, mAutosensData);
|
|
||||||
} else {
|
} else {
|
||||||
mV8rt.addUndefined(PARAM_autosens_data);
|
mAutosensData = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void release() {
|
public Object makeParam(JSONObject jsonObject, Context rhino, Scriptable scope) {
|
||||||
mProfile.release();
|
|
||||||
mCurrentTemp.release();
|
if(jsonObject == null) return Undefined.instance;
|
||||||
mIobData.release();
|
|
||||||
mMealData.release();
|
Object param = NativeJSON.parse(rhino, scope, jsonObject.toString(), new Callable() {
|
||||||
mGlucoseStatus.release();
|
@Override
|
||||||
if (mAutosensData != null) {
|
public Object call(Context context, Scriptable scriptable, Scriptable scriptable1, Object[] objects) {
|
||||||
mAutosensData.release();
|
return objects[1];
|
||||||
}
|
}
|
||||||
mV8rt.release();
|
});
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object makeParamArray(JSONArray jsonArray, Context rhino, Scriptable scope) {
|
||||||
|
//Object param = NativeJSON.parse(rhino, scope, "{myarray: " + jsonArray.toString() + " }", new Callable() {
|
||||||
|
Object param = NativeJSON.parse(rhino, scope, jsonArray.toString(), new Callable() {
|
||||||
|
@Override
|
||||||
|
public Object call(Context context, Scriptable scriptable, Scriptable scriptable1, Object[] objects) {
|
||||||
|
return objects[1];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return param;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String readFile(String filename) throws IOException {
|
public String readFile(String filename) throws IOException {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import com.eclipsesource.v8.V8Object;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
import org.mozilla.javascript.NativeObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -25,35 +26,34 @@ public class DetermineBasalResultAMA extends APSResult {
|
||||||
public double snoozeBG;
|
public double snoozeBG;
|
||||||
public IobTotal iob;
|
public IobTotal iob;
|
||||||
|
|
||||||
public DetermineBasalResultAMA(V8Object result, JSONObject j) {
|
public DetermineBasalResultAMA(NativeObject result, JSONObject j) {
|
||||||
date = new Date();
|
date = new Date();
|
||||||
json = j;
|
json = j;
|
||||||
if (result.contains("error")) {
|
if (result.containsKey("error")) {
|
||||||
reason = result.getString("error");
|
reason = result.get("error").toString();
|
||||||
changeRequested = false;
|
changeRequested = false;
|
||||||
rate = -1;
|
rate = -1;
|
||||||
duration = -1;
|
duration = -1;
|
||||||
} else {
|
} else {
|
||||||
reason = result.getString("reason");
|
reason = result.get("reason").toString();
|
||||||
if (result.contains("eventualBG")) eventualBG = result.getDouble("eventualBG");
|
if (result.containsKey("eventualBG")) eventualBG = (Double) result.get("eventualBG");
|
||||||
if (result.contains("snoozeBG")) snoozeBG = result.getDouble("snoozeBG");
|
if (result.containsKey("snoozeBG")) snoozeBG = (Double) result.get("snoozeBG");
|
||||||
if (result.contains("rate")) {
|
if (result.containsKey("rate")) {
|
||||||
rate = result.getDouble("rate");
|
rate = (Double) result.get("rate");
|
||||||
if (rate < 0d) rate = 0d;
|
if (rate < 0d) rate = 0d;
|
||||||
changeRequested = true;
|
changeRequested = true;
|
||||||
} else {
|
} else {
|
||||||
rate = -1;
|
rate = -1;
|
||||||
changeRequested = false;
|
changeRequested = false;
|
||||||
}
|
}
|
||||||
if (result.contains("duration")) {
|
if (result.containsKey("duration")) {
|
||||||
duration = result.getInteger("duration");
|
duration = ((Double)result.get("duration")).intValue();
|
||||||
//changeRequested as above
|
//changeRequested as above
|
||||||
} else {
|
} else {
|
||||||
duration = -1;
|
duration = -1;
|
||||||
changeRequested = false;
|
changeRequested = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DetermineBasalResultAMA() {
|
public DetermineBasalResultAMA() {
|
||||||
|
|
|
@ -222,11 +222,16 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
|
||||||
Profiler.log(log, "AMA data gathering", start);
|
Profiler.log(log, "AMA data gathering", start);
|
||||||
|
|
||||||
start = new Date();
|
start = new Date();
|
||||||
determineBasalAdapterAMAJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, pump, iobArray, glucoseStatus, mealData,
|
|
||||||
lastAutosensResult.ratio, //autosensDataRatio
|
try {
|
||||||
isTempTarget,
|
determineBasalAdapterAMAJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, pump, iobArray, glucoseStatus, mealData,
|
||||||
SafeParse.stringToDouble(SP.getString("openapsama_min_5m_carbimpact", "3.0"))//min_5m_carbimpact
|
lastAutosensResult.ratio, //autosensDataRatio
|
||||||
);
|
isTempTarget,
|
||||||
|
SafeParse.stringToDouble(SP.getString("openapsama_min_5m_carbimpact", "3.0"))//min_5m_carbimpact
|
||||||
|
);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
log.error("Unable to set data: " + e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DetermineBasalResultAMA determineBasalResultAMA = determineBasalAdapterAMAJS.invoke();
|
DetermineBasalResultAMA determineBasalResultAMA = determineBasalAdapterAMAJS.invoke();
|
||||||
|
@ -244,8 +249,6 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
|
||||||
|
|
||||||
determineBasalResultAMA.iob = iobArray[0];
|
determineBasalResultAMA.iob = iobArray[0];
|
||||||
|
|
||||||
determineBasalAdapterAMAJS.release();
|
|
||||||
|
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
package info.nightscout.androidaps.plugins.OpenAPSMA;
|
package info.nightscout.androidaps.plugins.OpenAPSMA;
|
||||||
|
|
||||||
import com.eclipsesource.v8.JavaVoidCallback;
|
|
||||||
import com.eclipsesource.v8.V8;
|
|
||||||
import com.eclipsesource.v8.V8Array;
|
|
||||||
import com.eclipsesource.v8.V8Object;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
import org.mozilla.javascript.Callable;
|
||||||
|
import org.mozilla.javascript.Context;
|
||||||
|
import org.mozilla.javascript.Function;
|
||||||
|
import org.mozilla.javascript.NativeJSON;
|
||||||
|
import org.mozilla.javascript.NativeObject;
|
||||||
|
import org.mozilla.javascript.RhinoException;
|
||||||
|
import org.mozilla.javascript.Scriptable;
|
||||||
|
import org.mozilla.javascript.ScriptableObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Config;
|
import info.nightscout.androidaps.Config;
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
|
@ -26,20 +30,12 @@ import info.nightscout.utils.SP;
|
||||||
public class DetermineBasalAdapterMAJS {
|
public class DetermineBasalAdapterMAJS {
|
||||||
private static Logger log = LoggerFactory.getLogger(DetermineBasalAdapterMAJS.class);
|
private static Logger log = LoggerFactory.getLogger(DetermineBasalAdapterMAJS.class);
|
||||||
|
|
||||||
|
|
||||||
private ScriptReader mScriptReader = null;
|
private ScriptReader mScriptReader = null;
|
||||||
V8 mV8rt;
|
private JSONObject mProfile;
|
||||||
private V8Object mProfile;
|
private JSONObject mGlucoseStatus;
|
||||||
private V8Object mGlucoseStatus;
|
private JSONObject mIobData;
|
||||||
private V8Object mIobData;
|
private JSONObject mMealData;
|
||||||
private V8Object mMealData;
|
private JSONObject mCurrentTemp;
|
||||||
private V8Object mCurrentTemp;
|
|
||||||
|
|
||||||
private final String PARAM_currentTemp = "currentTemp";
|
|
||||||
private final String PARAM_iobData = "iobData";
|
|
||||||
private final String PARAM_glucoseStatus = "glucose_status";
|
|
||||||
private final String PARAM_profile = "profile";
|
|
||||||
private final String PARAM_meal_data = "meal_data";
|
|
||||||
|
|
||||||
private String storedCurrentTemp = null;
|
private String storedCurrentTemp = null;
|
||||||
public String storedIobData = null;
|
public String storedIobData = null;
|
||||||
|
@ -47,104 +43,90 @@ public class DetermineBasalAdapterMAJS {
|
||||||
private String storedProfile = null;
|
private String storedProfile = null;
|
||||||
private String storedMeal_data = null;
|
private String storedMeal_data = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* Main code
|
|
||||||
*/
|
|
||||||
|
|
||||||
public DetermineBasalAdapterMAJS(ScriptReader scriptReader) throws IOException {
|
public DetermineBasalAdapterMAJS(ScriptReader scriptReader) throws IOException {
|
||||||
mV8rt = V8.createV8Runtime();
|
|
||||||
mScriptReader = scriptReader;
|
mScriptReader = scriptReader;
|
||||||
|
|
||||||
init();
|
|
||||||
initLogCallback();
|
|
||||||
initProcessExitCallback();
|
|
||||||
initModuleParent();
|
|
||||||
loadScript();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init() {
|
|
||||||
// Profile
|
|
||||||
mProfile = new V8Object(mV8rt);
|
|
||||||
mProfile.add("max_iob", 0);
|
|
||||||
mProfile.add("dia", 0);
|
|
||||||
mProfile.add("type", "current");
|
|
||||||
mProfile.add("max_daily_basal", 0);
|
|
||||||
mProfile.add("max_basal", 0);
|
|
||||||
mProfile.add("max_bg", 0);
|
|
||||||
mProfile.add("min_bg", 0);
|
|
||||||
mProfile.add("carb_ratio", 0);
|
|
||||||
mProfile.add("sens", 0);
|
|
||||||
mProfile.add("current_basal", 0);
|
|
||||||
mV8rt.add(PARAM_profile, mProfile);
|
|
||||||
// Current temp
|
|
||||||
mCurrentTemp = new V8Object(mV8rt);
|
|
||||||
mCurrentTemp.add("temp", "absolute");
|
|
||||||
mCurrentTemp.add("duration", 0);
|
|
||||||
mCurrentTemp.add("rate", 0);
|
|
||||||
mV8rt.add(PARAM_currentTemp, mCurrentTemp);
|
|
||||||
// IOB data
|
|
||||||
mIobData = new V8Object(mV8rt);
|
|
||||||
mIobData.add("iob", 0); //netIob
|
|
||||||
mIobData.add("activity", 0); //netActivity
|
|
||||||
mIobData.add("bolussnooze", 0); //bolusIob
|
|
||||||
mIobData.add("basaliob", 0);
|
|
||||||
mIobData.add("netbasalinsulin", 0);
|
|
||||||
mIobData.add("hightempinsulin", 0);
|
|
||||||
mV8rt.add(PARAM_iobData, mIobData);
|
|
||||||
// Glucose status
|
|
||||||
mGlucoseStatus = new V8Object(mV8rt);
|
|
||||||
mGlucoseStatus.add("glucose", 0);
|
|
||||||
mGlucoseStatus.add("delta", 0);
|
|
||||||
mGlucoseStatus.add("avgdelta", 0);
|
|
||||||
mV8rt.add(PARAM_glucoseStatus, mGlucoseStatus);
|
|
||||||
// Meal data
|
|
||||||
mMealData = new V8Object(mV8rt);
|
|
||||||
mMealData.add("carbs", 0);
|
|
||||||
mMealData.add("boluses", 0);
|
|
||||||
mV8rt.add(PARAM_meal_data, mMealData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DetermineBasalResultMA invoke() {
|
public DetermineBasalResultMA invoke() {
|
||||||
mV8rt.executeVoidScript(
|
DetermineBasalResultMA determineBasalResultMA = null;
|
||||||
"console.error(\"determine_basal(\"+\n" +
|
|
||||||
"JSON.stringify(" + PARAM_glucoseStatus + ")+ \", \" +\n" +
|
|
||||||
"JSON.stringify(" + PARAM_currentTemp + ")+ \", \" +\n" +
|
|
||||||
"JSON.stringify(" + PARAM_iobData + ")+ \", \" +\n" +
|
|
||||||
"JSON.stringify(" + PARAM_profile + ")+ \", \" +\n" +
|
|
||||||
"JSON.stringify(" + PARAM_meal_data + ")+ \") \");"
|
|
||||||
);
|
|
||||||
mV8rt.executeVoidScript(
|
|
||||||
"var rT = determine_basal(" +
|
|
||||||
PARAM_glucoseStatus + ", " +
|
|
||||||
PARAM_currentTemp + ", " +
|
|
||||||
PARAM_iobData + ", " +
|
|
||||||
PARAM_profile + ", " +
|
|
||||||
"undefined, " +
|
|
||||||
PARAM_meal_data + ", " +
|
|
||||||
"setTempBasal" +
|
|
||||||
");");
|
|
||||||
|
|
||||||
|
Context rhino = Context.enter();
|
||||||
|
Scriptable scope = rhino.initStandardObjects();
|
||||||
|
// Turn off optimization to make Rhino Android compatible
|
||||||
|
rhino.setOptimizationLevel(-1);
|
||||||
|
|
||||||
String ret = mV8rt.executeStringScript("JSON.stringify(rT);");
|
|
||||||
if (Config.logAPSResult)
|
|
||||||
log.debug("Result: " + ret);
|
|
||||||
|
|
||||||
V8Object v8ObjectReuslt = mV8rt.getObject("rT");
|
|
||||||
|
|
||||||
DetermineBasalResultMA result = null;
|
|
||||||
try {
|
try {
|
||||||
result = new DetermineBasalResultMA(v8ObjectReuslt, new JSONObject(ret));
|
|
||||||
} catch (JSONException e) {
|
//register logger callback for console.log and console.error
|
||||||
log.error("Unhandled exception", e);
|
ScriptableObject.defineClass(scope, LoggerCallback.class);
|
||||||
|
Scriptable myLogger = rhino.newObject(scope, "LoggerCallback", null);
|
||||||
|
scope.put("console", scope, myLogger);
|
||||||
|
|
||||||
|
//set module parent
|
||||||
|
rhino.evaluateString(scope, "var module = {\"parent\":Boolean(1)};", "JavaScript", 0, null);
|
||||||
|
|
||||||
|
//generate functions "determine_basal" and "setTempBasal"
|
||||||
|
rhino.evaluateString(scope, readFile("OpenAPSMA/determine-basal.js"), "JavaScript", 0, null);
|
||||||
|
|
||||||
|
String setTempBasalCode = "var setTempBasal = function (rate, duration, profile, rT, offline) {" +
|
||||||
|
"rT.duration = duration;\n" +
|
||||||
|
" rT.rate = rate;" +
|
||||||
|
"return rT;" +
|
||||||
|
"};";
|
||||||
|
rhino.evaluateString(scope, setTempBasalCode, "setTempBasal.js", 0, null);
|
||||||
|
Object determineBasalObj = scope.get("determine_basal", scope);
|
||||||
|
Object setTempBasalObj = scope.get("setTempBasal", scope);
|
||||||
|
|
||||||
|
//call determine-basal
|
||||||
|
if (determineBasalObj instanceof Function && setTempBasalObj instanceof Function) {
|
||||||
|
Function determineBasalJS = (Function) determineBasalObj;
|
||||||
|
Function setTempBasalJS = (Function) setTempBasalObj;
|
||||||
|
|
||||||
|
//prepare parameters
|
||||||
|
Object[] params = new Object[]{
|
||||||
|
makeParam(mGlucoseStatus, rhino, scope),
|
||||||
|
makeParam(mCurrentTemp, rhino, scope),
|
||||||
|
makeParam(mIobData, rhino, scope),
|
||||||
|
makeParam(mProfile, rhino, scope),
|
||||||
|
"undefined",
|
||||||
|
makeParam(mMealData, rhino, scope),
|
||||||
|
setTempBasalJS};
|
||||||
|
|
||||||
|
NativeObject jsResult = (NativeObject) determineBasalJS.call(rhino, scope, scope, params);
|
||||||
|
|
||||||
|
// Parse the jsResult object to a JSON-String
|
||||||
|
String result = NativeJSON.stringify(rhino, scope, jsResult, null, null).toString();
|
||||||
|
if (Config.logAPSResult)
|
||||||
|
log.debug("Result: " + result);
|
||||||
|
try {
|
||||||
|
determineBasalResultMA = new DetermineBasalResultMA(jsResult, new JSONObject(result));
|
||||||
|
} catch (JSONException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.debug("Problem loading JS Functions");
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.debug("IOException");
|
||||||
|
} catch (RhinoException e) {
|
||||||
|
log.error("RhinoException: (" + e.lineNumber() + "," + e.columnNumber() + ") " + e.toString());
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
log.error(e.toString());
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
log.error(e.toString());
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
log.error(e.toString());
|
||||||
|
} finally {
|
||||||
|
Context.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
storedGlucoseStatus = mV8rt.executeStringScript("JSON.stringify(" + PARAM_glucoseStatus + ");");
|
storedGlucoseStatus = mGlucoseStatus.toString();
|
||||||
storedIobData = mV8rt.executeStringScript("JSON.stringify(" + PARAM_iobData + ");");
|
storedIobData = mIobData.toString();
|
||||||
storedCurrentTemp = mV8rt.executeStringScript("JSON.stringify(" + PARAM_currentTemp + ");");
|
storedCurrentTemp = mCurrentTemp.toString();
|
||||||
storedProfile = mV8rt.executeStringScript("JSON.stringify(" + PARAM_profile + ");");
|
storedProfile = mProfile.toString();
|
||||||
storedMeal_data = mV8rt.executeStringScript("JSON.stringify(" + PARAM_meal_data + ");");
|
storedMeal_data = mMealData.toString();
|
||||||
|
|
||||||
return result;
|
return determineBasalResultMA;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getGlucoseStatusParam() {
|
String getGlucoseStatusParam() {
|
||||||
|
@ -167,57 +149,6 @@ public class DetermineBasalAdapterMAJS {
|
||||||
return storedMeal_data;
|
return storedMeal_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadScript() throws IOException {
|
|
||||||
mV8rt.executeVoidScript(
|
|
||||||
readFile("OpenAPSMA/determine-basal.js"),
|
|
||||||
"OpenAPSMA/bin/oref0-determine-basal.js",
|
|
||||||
0);
|
|
||||||
mV8rt.executeVoidScript("var determine_basal = module.exports;");
|
|
||||||
mV8rt.executeVoidScript(
|
|
||||||
"var setTempBasal = function (rate, duration, profile, rT, offline) {" +
|
|
||||||
"rT.duration = duration;\n" +
|
|
||||||
" rT.rate = rate;" +
|
|
||||||
"return rT;" +
|
|
||||||
"};",
|
|
||||||
"setTempBasal.js",
|
|
||||||
0
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initModuleParent() {
|
|
||||||
mV8rt.executeVoidScript("var module = {\"parent\":Boolean(1)};");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initProcessExitCallback() {
|
|
||||||
JavaVoidCallback callbackProccessExit = new JavaVoidCallback() {
|
|
||||||
@Override
|
|
||||||
public void invoke(V8Object arg0, V8Array parameters) {
|
|
||||||
if (parameters.length() > 0) {
|
|
||||||
Object arg1 = parameters.get(0);
|
|
||||||
log.error("ProccessExit " + arg1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
mV8rt.registerJavaMethod(callbackProccessExit, "proccessExit");
|
|
||||||
mV8rt.executeVoidScript("var process = {\"exit\": function () { proccessExit(); } };");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initLogCallback() {
|
|
||||||
JavaVoidCallback callbackLog = new JavaVoidCallback() {
|
|
||||||
@Override
|
|
||||||
public void invoke(V8Object arg0, V8Array parameters) {
|
|
||||||
if (parameters.length() > 0) {
|
|
||||||
Object arg1 = parameters.get(0);
|
|
||||||
if (Config.logAPSResult)
|
|
||||||
log.debug("Input params: " + arg1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
mV8rt.registerJavaMethod(callbackLog, "log");
|
|
||||||
mV8rt.executeVoidScript("var console = {\"log\":log, \"error\":log};");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setData(Profile profile,
|
public void setData(Profile profile,
|
||||||
double maxIob,
|
double maxIob,
|
||||||
double maxBasal,
|
double maxBasal,
|
||||||
|
@ -227,57 +158,52 @@ public class DetermineBasalAdapterMAJS {
|
||||||
PumpInterface pump,
|
PumpInterface pump,
|
||||||
IobTotal iobData,
|
IobTotal iobData,
|
||||||
GlucoseStatus glucoseStatus,
|
GlucoseStatus glucoseStatus,
|
||||||
MealData mealData) {
|
MealData mealData) throws JSONException {
|
||||||
|
|
||||||
String units = profile.getUnits();
|
String units = profile.getUnits();
|
||||||
|
|
||||||
mProfile.add("max_iob", maxIob);
|
mProfile = new JSONObject();
|
||||||
mProfile.add("dia", Math.min(profile.getDia(), 3d));
|
mProfile.put("max_iob", maxIob);
|
||||||
mProfile.add("type", "current");
|
mProfile.put("dia", Math.min(profile.getDia(), 3d));
|
||||||
mProfile.add("max_daily_basal", profile.getMaxDailyBasal());
|
mProfile.put("type", "current");
|
||||||
mProfile.add("max_basal", maxBasal);
|
mProfile.put("max_daily_basal", profile.getMaxDailyBasal());
|
||||||
mProfile.add("min_bg", minBg);
|
mProfile.put("max_basal", maxBasal);
|
||||||
mProfile.add("max_bg", maxBg);
|
mProfile.put("min_bg", minBg);
|
||||||
mProfile.add("target_bg", targetBg);
|
mProfile.put("max_bg", maxBg);
|
||||||
mProfile.add("carb_ratio", profile.getIc());
|
mProfile.put("target_bg", targetBg);
|
||||||
mProfile.add("sens", Profile.toMgdl(profile.getIsf().doubleValue(), units));
|
mProfile.put("carb_ratio", profile.getIc());
|
||||||
|
mProfile.put("sens", Profile.toMgdl(profile.getIsf().doubleValue(), units));
|
||||||
|
|
||||||
mProfile.add("current_basal", pump.getBaseBasalRate());
|
mProfile.put("current_basal", pump.getBaseBasalRate());
|
||||||
|
|
||||||
if (units.equals(Constants.MMOL)) {
|
if (units.equals(Constants.MMOL)) {
|
||||||
mProfile.add("out_units", "mmol/L");
|
mProfile.put("out_units", "mmol/L");
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentTemp.add("duration", MainApp.getConfigBuilder().getTempBasalRemainingMinutesFromHistory());
|
mCurrentTemp = new JSONObject();
|
||||||
mCurrentTemp.add("rate", MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory());
|
mCurrentTemp.put("duration", MainApp.getConfigBuilder().getTempBasalRemainingMinutesFromHistory());
|
||||||
|
mCurrentTemp.put("rate", MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory());
|
||||||
|
|
||||||
mIobData.add("iob", iobData.iob); //netIob
|
mIobData = new JSONObject();
|
||||||
mIobData.add("activity", iobData.activity); //netActivity
|
mIobData.put("iob", iobData.iob); //netIob
|
||||||
mIobData.add("bolussnooze", iobData.bolussnooze); //bolusIob
|
mIobData.put("activity", iobData.activity); //netActivity
|
||||||
mIobData.add("basaliob", iobData.basaliob);
|
mIobData.put("bolussnooze", iobData.bolussnooze); //bolusIob
|
||||||
mIobData.add("netbasalinsulin", iobData.netbasalinsulin);
|
mIobData.put("basaliob", iobData.basaliob);
|
||||||
mIobData.add("hightempinsulin", iobData.hightempinsulin);
|
mIobData.put("netbasalinsulin", iobData.netbasalinsulin);
|
||||||
|
mIobData.put("hightempinsulin", iobData.hightempinsulin);
|
||||||
|
|
||||||
mGlucoseStatus.add("glucose", glucoseStatus.glucose);
|
mGlucoseStatus = new JSONObject();
|
||||||
|
mGlucoseStatus.put("glucose", glucoseStatus.glucose);
|
||||||
if (SP.getBoolean("always_use_shortavg", false)) {
|
if (SP.getBoolean("always_use_shortavg", false)) {
|
||||||
mGlucoseStatus.add("delta", glucoseStatus.short_avgdelta);
|
mGlucoseStatus.put("delta", glucoseStatus.short_avgdelta);
|
||||||
} else {
|
} else {
|
||||||
mGlucoseStatus.add("delta", glucoseStatus.delta);
|
mGlucoseStatus.put("delta", glucoseStatus.delta);
|
||||||
}
|
}
|
||||||
mGlucoseStatus.add("avgdelta", glucoseStatus.avgdelta);
|
mGlucoseStatus.put("avgdelta", glucoseStatus.avgdelta);
|
||||||
|
|
||||||
mMealData.add("carbs", mealData.carbs);
|
mMealData = new JSONObject();
|
||||||
mMealData.add("boluses", mealData.boluses);
|
mMealData.put("carbs", mealData.carbs);
|
||||||
}
|
mMealData.put("boluses", mealData.boluses);
|
||||||
|
|
||||||
|
|
||||||
public void release() {
|
|
||||||
mProfile.release();
|
|
||||||
mCurrentTemp.release();
|
|
||||||
mIobData.release();
|
|
||||||
mMealData.release();
|
|
||||||
mGlucoseStatus.release();
|
|
||||||
mV8rt.release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String readFile(String filename) throws IOException {
|
public String readFile(String filename) throws IOException {
|
||||||
|
@ -289,4 +215,14 @@ public class DetermineBasalAdapterMAJS {
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Object makeParam(JSONObject jsonObject, Context rhino, Scriptable scope) {
|
||||||
|
Object param = NativeJSON.parse(rhino, scope, jsonObject.toString(), new Callable() {
|
||||||
|
@Override
|
||||||
|
public Object call(Context context, Scriptable scriptable, Scriptable scriptable1, Object[] objects) {
|
||||||
|
return objects[1];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
package info.nightscout.androidaps.plugins.OpenAPSMA;
|
package info.nightscout.androidaps.plugins.OpenAPSMA;
|
||||||
|
|
||||||
import android.os.Parcel;
|
|
||||||
import android.os.Parcelable;
|
|
||||||
|
|
||||||
import com.eclipsesource.v8.V8Object;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
import org.mozilla.javascript.NativeObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -22,38 +18,37 @@ public class DetermineBasalResultMA extends APSResult {
|
||||||
public String mealAssist;
|
public String mealAssist;
|
||||||
public IobTotal iob;
|
public IobTotal iob;
|
||||||
|
|
||||||
public DetermineBasalResultMA(V8Object result, JSONObject j) {
|
public DetermineBasalResultMA(NativeObject result, JSONObject j) {
|
||||||
json = j;
|
json = j;
|
||||||
if (result.contains("error")) {
|
if (result.containsKey("error")) {
|
||||||
reason = result.getString("error");
|
reason = (String) result.get("error");
|
||||||
changeRequested = false;
|
changeRequested = false;
|
||||||
rate = -1;
|
rate = -1;
|
||||||
duration = -1;
|
duration = -1;
|
||||||
mealAssist = "";
|
mealAssist = "";
|
||||||
} else {
|
} else {
|
||||||
reason = result.getString("reason");
|
reason = result.get("reason").toString();
|
||||||
eventualBG = result.getDouble("eventualBG");
|
eventualBG = (Double) result.get("eventualBG");
|
||||||
snoozeBG = result.getDouble("snoozeBG");
|
snoozeBG = (Double) result.get("snoozeBG");
|
||||||
if (result.contains("rate")) {
|
if (result.containsKey("rate")) {
|
||||||
rate = result.getDouble("rate");
|
rate = (Double) result.get("rate");
|
||||||
if (rate < 0d) rate = 0d;
|
if (rate < 0d) rate = 0d;
|
||||||
changeRequested = true;
|
changeRequested = true;
|
||||||
} else {
|
} else {
|
||||||
rate = -1;
|
rate = -1;
|
||||||
changeRequested = false;
|
changeRequested = false;
|
||||||
}
|
}
|
||||||
if (result.contains("duration")) {
|
if (result.containsKey("duration")) {
|
||||||
duration = result.getInteger("duration");
|
duration = ((Double) result.get("duration")).intValue();
|
||||||
//changeRequested as above
|
//changeRequested as above
|
||||||
} else {
|
} else {
|
||||||
duration = -1;
|
duration = -1;
|
||||||
changeRequested = false;
|
changeRequested = false;
|
||||||
}
|
}
|
||||||
if (result.contains("mealAssist")) {
|
if (result.containsKey("mealAssist")) {
|
||||||
mealAssist = result.getString("mealAssist");
|
mealAssist = result.get("mealAssist").toString();
|
||||||
} else mealAssist = "";
|
} else mealAssist = "";
|
||||||
}
|
}
|
||||||
result.release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DetermineBasalResultMA() {
|
public DetermineBasalResultMA() {
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
package info.nightscout.androidaps.plugins.OpenAPSMA;
|
||||||
|
|
||||||
|
import org.mozilla.javascript.ScriptableObject;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.utils.ToastUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by adrian on 15/10/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
public class LoggerCallback extends ScriptableObject {
|
||||||
|
|
||||||
|
private static Logger log = LoggerFactory.getLogger(DetermineBasalAdapterMAJS.class);
|
||||||
|
|
||||||
|
static StringBuffer errorBuffer = new StringBuffer();
|
||||||
|
static StringBuffer logBuffer = new StringBuffer();
|
||||||
|
|
||||||
|
|
||||||
|
public LoggerCallback() {
|
||||||
|
//empty constructor needed for Rhino
|
||||||
|
errorBuffer = new StringBuffer();
|
||||||
|
logBuffer = new StringBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getClassName() {
|
||||||
|
return "LoggerCallback";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void jsConstructor() {
|
||||||
|
//empty constructor on JS site; could work as setter
|
||||||
|
}
|
||||||
|
|
||||||
|
public void jsFunction_log(Object obj1) {
|
||||||
|
log.debug(obj1.toString());
|
||||||
|
logBuffer.append(obj1.toString());
|
||||||
|
logBuffer.append(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
public void jsFunction_error(Object obj1) {
|
||||||
|
log.error(obj1.toString());
|
||||||
|
errorBuffer.append(obj1.toString());
|
||||||
|
errorBuffer.append(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static String getScriptDebug(){
|
||||||
|
String ret = "";
|
||||||
|
if(errorBuffer.length() > 0){
|
||||||
|
ret += "e:\n" + errorBuffer.toString();
|
||||||
|
}
|
||||||
|
if(ret.length() > 0 && logBuffer.length() > 0) ret += '\n';
|
||||||
|
if(logBuffer.length() > 0){
|
||||||
|
ret += "d:\n" + logBuffer.toString();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
|
@ -211,12 +211,16 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
|
||||||
if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, 5)) return;
|
if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, 5)) return;
|
||||||
|
|
||||||
start = new Date();
|
start = new Date();
|
||||||
determineBasalAdapterMAJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, pump, iobTotal, glucoseStatus, mealData);
|
try {
|
||||||
|
determineBasalAdapterMAJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, pump, iobTotal, glucoseStatus, mealData);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
Profiler.log(log, "MA calculation", start);
|
Profiler.log(log, "MA calculation", start);
|
||||||
|
|
||||||
|
|
||||||
DetermineBasalResultMA determineBasalResultMA = determineBasalAdapterMAJS.invoke();
|
DetermineBasalResultMA determineBasalResultMA = determineBasalAdapterMAJS.invoke();
|
||||||
// Fix bug determine basal
|
// Fix bug determinef basal
|
||||||
if (determineBasalResultMA.rate == 0d && determineBasalResultMA.duration == 0 && !MainApp.getConfigBuilder().isTempBasalInProgress())
|
if (determineBasalResultMA.rate == 0d && determineBasalResultMA.duration == 0 && !MainApp.getConfigBuilder().isTempBasalInProgress())
|
||||||
determineBasalResultMA.changeRequested = false;
|
determineBasalResultMA.changeRequested = false;
|
||||||
// limit requests on openloop mode
|
// limit requests on openloop mode
|
||||||
|
@ -229,8 +233,6 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
|
||||||
|
|
||||||
determineBasalResultMA.iob = iobTotal;
|
determineBasalResultMA.iob = iobTotal;
|
||||||
|
|
||||||
determineBasalAdapterMAJS.release();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
determineBasalResultMA.json.put("timestamp", DateUtil.toISOString(now));
|
determineBasalResultMA.json.put("timestamp", DateUtil.toISOString(now));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
|
@ -241,8 +243,6 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
|
||||||
lastAPSResult = determineBasalResultMA;
|
lastAPSResult = determineBasalResultMA;
|
||||||
lastAPSRun = now;
|
lastAPSRun = now;
|
||||||
MainApp.bus().post(new EventOpenAPSUpdateGui());
|
MainApp.bus().post(new EventOpenAPSUpdateGui());
|
||||||
|
|
||||||
//deviceStatus.suggested = determineBasalResultMA.json;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue