From 53967652cbc17da48a5a9cb110de2c0681c90c68 Mon Sep 17 00:00:00 2001 From: supertick Date: Tue, 2 Apr 2024 07:20:17 -0700 Subject: [PATCH 1/9] callbacks started --- .../java/org/myrobotlab/service/InMoov2.java | 159 +++++++++++++++++- 1 file changed, 157 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/myrobotlab/service/InMoov2.java b/src/main/java/org/myrobotlab/service/InMoov2.java index 4f929231ff..913fe994be 100644 --- a/src/main/java/org/myrobotlab/service/InMoov2.java +++ b/src/main/java/org/myrobotlab/service/InMoov2.java @@ -3,6 +3,7 @@ import java.io.File; import java.io.FilenameFilter; import java.io.IOException; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; @@ -27,6 +28,8 @@ import org.myrobotlab.opencv.OpenCVData; import org.myrobotlab.programab.PredicateEvent; import org.myrobotlab.programab.Response; +import org.myrobotlab.programab.Session; +import org.myrobotlab.service.FiniteStateMachine.StateChange; import org.myrobotlab.service.Log.LogEntry; import org.myrobotlab.service.abstracts.AbstractSpeechRecognizer; import org.myrobotlab.service.abstracts.AbstractSpeechSynthesis; @@ -227,6 +230,8 @@ public static void main(String[] args) { protected transient HtmlFilter htmlFilter; protected transient ImageDisplay imageDisplay; + + protected String lastState = null; protected String lastGestureExecuted; @@ -248,6 +253,11 @@ public static void main(String[] args) { protected transient Python python; protected String voiceSelected; + + /** + * initial state - updated on any state change + */ + protected String state = "boot"; public InMoov2(String n, String id) { super(n, id); @@ -273,6 +283,8 @@ public InMoov2Config apply(InMoov2Config c) { setLocale(getSupportedLocale(Runtime.getInstance().getLocale().toString())); } + execScript(); + loadAppsScripts(); loadInitScripts(); @@ -287,6 +299,10 @@ public InMoov2Config apply(InMoov2Config c) { stopHeartbeat(); } + + // one way sync configuration into predicates + configToPredicates(); + } catch (Exception e) { error(e); } @@ -422,6 +438,13 @@ public long checkInactivity() { return lastActivityTime; } + /** + * clear all errors + */ + public void clearErrors() { + errors.clear(); + } + public void closeAllImages() { // FIXME - follow this pattern ? // CON npe possible although unlikely @@ -431,6 +454,38 @@ public void closeAllImages() { imageDisplay.closeAll(); } + /** + * Updates configuration into ProgramAB predicates. + */ + public void configToPredicates() { + log.info("configToPredicates"); + if (chatBot != null) { + Class pojoClass = config.getClass(); + Field[] fields = pojoClass.getDeclaredFields(); + for (Field field : fields) { + try { + field.setAccessible(true); + Object value = field.get(config); // Requires handling + Map sessions = chatBot.getSessions(); + if (sessions != null) { + for (Session session : sessions.values()) { + if (value != null) { + session.setPredicate(String.format("config.%s", field.getName()), value.toString()); + } else { + session.setPredicate(String.format("config.%s", field.getName()), null); + } + + } + } + } catch (Exception e) { + error(e); + } + } + } else { + log.info("chatbot not ready for config sync"); + } + } + public void cycleGestures() { // if not loaded load - // FIXME - this needs alot of "help" :P @@ -475,6 +530,23 @@ public void displayFullScreen(String src) { } } + public void enableRandomHead() { + Random random = (Random) getPeer("random"); + if (random != null) { + random.disableAll(); + random.enable(String.format("%s.setHeadSpeed", getName())); + random.enable(String.format("%s.moveHead", getName())); + random.enable(); + } + } + + public void disableRandom() { + Random random = (Random) getPeer("random"); + if (random != null) { + random.disable(); + } + } + public void enable() { sendToPeer("head", "enable"); sendToPeer("rightHand", "enable"); @@ -523,6 +595,13 @@ public String execGesture(String gesture) { return python.evalAndWait(gesture); } + /** + * Reload the InMoov2.py script + */ + public void execScript() { + execScript("InMoov2.py"); + } + /** * FIXME - I think there was lots of confusion of executing resources or just * a file on the file system ... "execScript" I would expect to be just a file @@ -1413,6 +1492,83 @@ public HashMap publishMoveTorso(Double topStom, Double midStom, map.put("lowStom", lowStom); return map; } + + + /** + * publishStateChange + * + * The integration between the FiniteStateMachine (fsm) and the InMoov2 + * service and potentially other services (Python, ProgramAB) happens here. + * + * After boot all state changes get published here. + * + * Some InMoov2 service methods will be called here for "default + * implemenation" of states. If a user doesn't want to have that default + * implementation, they can change it by changing the definition of the state + * machine, and have a new state which will call a Python inmoov2 library + * callback. Overriding, appending, or completely transforming the behavior is + * all easily accomplished by managing the fsm and python inmoov2 library + * callbacks. + * + * Python inmoov2 callbacks ProgramAB topic switching + * + * Depending on config: + * + * @param stateChange + * @return + */ + public StateChange publishStateChange(StateChange stateChange) { + log.info("publishStateChange {}", stateChange); + + log.info("onStateChange {}", stateChange); + + lastState = state; + state = stateChange.state; + + setPredicate(String.format("%s.end", lastState), System.currentTimeMillis()); + setPredicate(String.format("%s.start", state), System.currentTimeMillis()); + + processMessage("onStateChange", stateChange); + + return stateChange; + } + + public void processMessage(String method) { + processMessage(method, (Object[])null); + } + + /** + * Will publish processing messages to the processor(s) currently subscribed. + * + * @param method + * @param data + */ + public void processMessage(String method, Object... data) { + // User processing should not occur until after boot has completed + if (!state.equals("boot")) { + // FIXME - this needs to be in config + // FIXME - change peer name to "processor" + // String processor = getPeerName("py4j"); + String processor = "python"; + + Message msg = Message.createMessage(getName(), processor, method, data); + // FIXME - is this too much abstraction .. to publish as well as + // configurable send ? + invoke("publishProcessMessage", msg); + } + } + + /** + * One of the most important publishing point. Processing publishing point, + * where everything InMoov2 wants to be processed is turned into a message and + * published. + * + * @param msg + * @return + */ + public Message publishProcessMessage(Message msg) { + return msg; + } /** * all published text from InMoov2 - including ProgramAB @@ -1994,8 +2150,7 @@ public void stopNeopixelAnimation() { } public void systemCheck() { - log.error("systemCheck()"); - Runtime runtime = Runtime.getInstance(); + log.info("systemCheck()"); int servoCount = 0; int servoAttachedCount = 0; for (ServiceInterface si : Runtime.getServices()) { From c88c6551d270218984b66acf5e47f7681ef5fed0 Mon Sep 17 00:00:00 2001 From: supertick Date: Tue, 2 Apr 2024 07:43:40 -0700 Subject: [PATCH 2/9] more publishing points --- .../java/org/myrobotlab/service/InMoov2.java | 366 +++++++++++------- 1 file changed, 232 insertions(+), 134 deletions(-) diff --git a/src/main/java/org/myrobotlab/service/InMoov2.java b/src/main/java/org/myrobotlab/service/InMoov2.java index 913fe994be..3077d0472a 100644 --- a/src/main/java/org/myrobotlab/service/InMoov2.java +++ b/src/main/java/org/myrobotlab/service/InMoov2.java @@ -44,14 +44,15 @@ import org.myrobotlab.service.interfaces.ServiceLifeCycleListener; import org.myrobotlab.service.interfaces.ServoControl; import org.myrobotlab.service.interfaces.Simulator; +import org.myrobotlab.service.interfaces.SpeechListener; import org.myrobotlab.service.interfaces.SpeechRecognizer; import org.myrobotlab.service.interfaces.SpeechSynthesis; import org.myrobotlab.service.interfaces.TextListener; import org.myrobotlab.service.interfaces.TextPublisher; import org.slf4j.Logger; -public class InMoov2 extends Service implements ServiceLifeCycleListener, TextListener, TextPublisher, - JoystickListener, LocaleProvider, IKJointAngleListener { +public class InMoov2 extends Service + implements ServiceLifeCycleListener, SpeechListener, TextListener, TextPublisher, JoystickListener, LocaleProvider, IKJointAngleListener { public final static Logger log = LoggerFactory.getLogger(InMoov2.class); @@ -65,7 +66,7 @@ public class InMoov2 extends Service implements ServiceLifeCycleL * This method will load a python file into the python interpreter. * * @param file - * file to load + * file to load * @return success/failure */ @Deprecated /* use execScript - this doesn't handle resources correctly */ @@ -170,15 +171,11 @@ public static void main(String[] args) { random.addRandom(3000, 8000, "i01", "moveLeftArm", 0.0, 5.0, 85.0, 95.0, 25.0, 30.0, 10.0, 15.0); random.addRandom(3000, 8000, "i01", "moveRightArm", 0.0, 5.0, 85.0, 95.0, 25.0, 30.0, 10.0, 15.0); - random.addRandom(3000, 8000, "i01", "setLeftHandSpeed", 8.0, 25.0, 8.0, 25.0, 8.0, 25.0, 8.0, 25.0, 8.0, 25.0, - 8.0, 25.0); - random.addRandom(3000, 8000, "i01", "setRightHandSpeed", 8.0, 25.0, 8.0, 25.0, 8.0, 25.0, 8.0, 25.0, 8.0, 25.0, - 8.0, 25.0); + random.addRandom(3000, 8000, "i01", "setLeftHandSpeed", 8.0, 25.0, 8.0, 25.0, 8.0, 25.0, 8.0, 25.0, 8.0, 25.0, 8.0, 25.0); + random.addRandom(3000, 8000, "i01", "setRightHandSpeed", 8.0, 25.0, 8.0, 25.0, 8.0, 25.0, 8.0, 25.0, 8.0, 25.0, 8.0, 25.0); - random.addRandom(3000, 8000, "i01", "moveRightHand", 10.0, 160.0, 10.0, 60.0, 10.0, 60.0, 10.0, 60.0, 10.0, 60.0, - 130.0, 175.0); - random.addRandom(3000, 8000, "i01", "moveLeftHand", 10.0, 160.0, 10.0, 60.0, 10.0, 60.0, 10.0, 60.0, 10.0, 60.0, - 5.0, 40.0); + random.addRandom(3000, 8000, "i01", "moveRightHand", 10.0, 160.0, 10.0, 60.0, 10.0, 60.0, 10.0, 60.0, 10.0, 60.0, 130.0, 175.0); + random.addRandom(3000, 8000, "i01", "moveLeftHand", 10.0, 160.0, 10.0, 60.0, 10.0, 60.0, 10.0, 60.0, 10.0, 60.0, 5.0, 40.0); random.addRandom(200, 1000, "i01", "setHeadSpeed", 8.0, 20.0, 8.0, 20.0, 8.0, 20.0); random.addRandom(200, 1000, "i01", "moveHead", 70.0, 110.0, 65.0, 115.0, 70.0, 110.0); @@ -227,16 +224,25 @@ public static void main(String[] args) { protected Set gestures = new TreeSet(); + /** + * Prevents actions or events from happening when InMoov2 is first booted + */ + protected boolean hasBooted = false; + + protected long heartbeatCount = 0; + protected transient HtmlFilter htmlFilter; protected transient ImageDisplay imageDisplay; - - protected String lastState = null; + + protected boolean isSpeaking = false; protected String lastGestureExecuted; protected Long lastPirActivityTime; + protected String lastState = null; + /** * supported locales */ @@ -252,13 +258,13 @@ public static void main(String[] args) { protected transient Python python; - protected String voiceSelected; - /** * initial state - updated on any state change */ protected String state = "boot"; + protected String voiceSelected; + public InMoov2(String n, String id) { super(n, id); } @@ -274,8 +280,7 @@ public InMoov2Config apply(InMoov2Config c) { super.apply(c); try { - locales = Locale.getLocaleMap("en-US", "fr-FR", "es-ES", "de-DE", "nl-NL", "pl-PL", "ru-RU", "hi-IN", "it-IT", - "fi-FI", "pt-PT", "tr-TR"); + locales = Locale.getLocaleMap("en-US", "fr-FR", "es-ES", "de-DE", "nl-NL", "pl-PL", "ru-RU", "hi-IN", "it-IT", "fi-FI", "pt-PT", "tr-TR"); if (c.locale != null) { setLocale(c.locale); @@ -299,7 +304,6 @@ public InMoov2Config apply(InMoov2Config c) { stopHeartbeat(); } - // one way sync configuration into predicates configToPredicates(); @@ -518,6 +522,13 @@ public void disable() { sendToPeer("torso", "disable"); } + public void disableRandom() { + Random random = (Random) getPeer("random"); + if (random != null) { + random.disable(); + } + } + public void displayFullScreen(String src) { try { if (imageDisplay == null) { @@ -530,6 +541,15 @@ public void displayFullScreen(String src) { } } + public void enable() { + sendToPeer("head", "enable"); + sendToPeer("rightHand", "enable"); + sendToPeer("leftHand", "enable"); + sendToPeer("rightArm", "enable"); + sendToPeer("leftArm", "enable"); + sendToPeer("torso", "enable"); + } + public void enableRandomHead() { Random random = (Random) getPeer("random"); if (random != null) { @@ -540,22 +560,6 @@ public void enableRandomHead() { } } - public void disableRandom() { - Random random = (Random) getPeer("random"); - if (random != null) { - random.disable(); - } - } - - public void enable() { - sendToPeer("head", "enable"); - sendToPeer("rightHand", "enable"); - sendToPeer("leftHand", "enable"); - sendToPeer("rightArm", "enable"); - sendToPeer("leftArm", "enable"); - sendToPeer("torso", "enable"); - } - /** * Single place for InMoov2 service to execute arbitrary code - needed * initially to set "global" vars in python @@ -577,7 +581,7 @@ public boolean exec(String pythonCode) { * This method will try to launch a python command with error handling * * @param gesture - * the gesture + * the gesture * @return gesture result */ public String execGesture(String gesture) { @@ -612,7 +616,7 @@ public void execScript() { * a filesystem file :P * * @param someScriptName - * execute a resource script + * execute a resource script * @return success or failure */ public boolean execScript(String someScriptName) { @@ -742,6 +746,22 @@ public Object getPredicate(String key) { return null; } + public String getPredicate(String user, String key) { + ProgramAB chatBot = (ProgramAB) getPeer("chatBot"); + if (chatBot != null) { + return chatBot.getPredicate(user, key); + } else { + error("no chatBot available"); + } + return null; + } + + /** + * getResponse from ProgramAB + * + * @param text + * @return + */ public Response getResponse(String text) { ProgramAB chatBot = (ProgramAB) getPeer("chatBot"); if (chatBot != null) { @@ -761,6 +781,14 @@ public InMoov2Hand getRightHand() { return (InMoov2Hand) getPeer("rightHand"); } + public String getState() { + FiniteStateMachine fsm = (FiniteStateMachine) getPeer("fsm"); + if (fsm == null) { + return null; + } + return fsm.getState(); + } + /** * matches on language only not variant expands language match to full InMoov2 * bot locale @@ -791,10 +819,6 @@ public InMoov2Torso getTorso() { return (InMoov2Torso) getPeer("torso"); } - public InMoov2Config getTypedConfig() { - return (InMoov2Config) config; - } - public void halfSpeed() { sendToPeer("head", "setSpeed", 25.0, 25.0, 25.0, 25.0, 100.0, 25.0); sendToPeer("rightHand", "setSpeed", 30.0, 30.0, 30.0, 30.0, 30.0, 30.0); @@ -804,6 +828,15 @@ public void halfSpeed() { sendToPeer("torso", "setSpeed", 20.0, 20.0, 20.0); } + /** + * If there have been any errors + * + * @return + */ + public boolean hasErrors() { + return errors.size() > 0; + } + public boolean isCameraOn() { if (opencv != null) { if (opencv.isCapturing()) { @@ -817,6 +850,10 @@ public boolean isMute() { return mute; } + public boolean isSpeaking() { + return isSpeaking; + } + /** * execute python scripts in the app directory on startup of the service * @@ -837,7 +874,7 @@ public void loadGestures() { * file should contain 1 method definition that is the same as the filename. * * @param directory - * - the directory that contains the gesture python files. + * - the directory that contains the gesture python files. * @return true/false */ public boolean loadGestures(String directory) { @@ -936,8 +973,7 @@ public void moveHand(String which, Double thumb, Double index, Double majeure, D moveHand(which, thumb, index, majeure, ringFinger, pinky, null); } - public void moveHand(String which, Double thumb, Double index, Double majeure, Double ringFinger, Double pinky, - Double wrist) { + public void moveHand(String which, Double thumb, Double index, Double majeure, Double ringFinger, Double pinky, Double wrist) { invoke("publishMoveHand", which, thumb, index, majeure, ringFinger, pinky, wrist); } @@ -989,10 +1025,8 @@ public void moveLeftHand(Double thumb, Double index, Double majeure, Double ring moveHand("left", thumb, index, majeure, ringFinger, pinky, wrist); } - public void moveLeftHand(Integer thumb, Integer index, Integer majeure, Integer ringFinger, Integer pinky, - Integer wrist) { - moveHand("left", (double) thumb, (double) index, (double) majeure, (double) ringFinger, (double) pinky, - (double) wrist); + public void moveLeftHand(Integer thumb, Integer index, Integer majeure, Integer ringFinger, Integer pinky, Integer wrist) { + moveHand("left", (double) thumb, (double) index, (double) majeure, (double) ringFinger, (double) pinky, (double) wrist); } public void moveRightArm(Double bicep, Double rotate, Double shoulder, Double omoplate) { @@ -1003,10 +1037,8 @@ public void moveRightHand(Double thumb, Double index, Double majeure, Double rin moveHand("right", thumb, index, majeure, ringFinger, pinky, wrist); } - public void moveRightHand(Integer thumb, Integer index, Integer majeure, Integer ringFinger, Integer pinky, - Integer wrist) { - moveHand("right", (double) thumb, (double) index, (double) majeure, (double) ringFinger, (double) pinky, - (double) wrist); + public void moveRightHand(Integer thumb, Integer index, Integer majeure, Integer ringFinger, Integer pinky, Integer wrist) { + moveHand("right", (double) thumb, (double) index, (double) majeure, (double) ringFinger, (double) pinky, (double) wrist); } public void moveTorso(Double topStom, Double midStom, Double lowStom) { @@ -1035,7 +1067,7 @@ public PredicateEvent onChangePredicate(PredicateEvent event) { * comes in from runtime which owns the config list * * @param configList - * list of configs + * list of configs */ public void onConfigList(List configList) { this.configList = configList; @@ -1047,6 +1079,23 @@ public void onCreated(String fullname) { log.info("{} created", fullname); } + @Override + public void onEndSpeaking(String utterance) { + processMessage("onEndSpeaking", utterance); + isSpeaking = false; + } + + /** + * Centralized logging system will have all logging from all services, + * including lower level logs that do not propegate as statuses + * + * @param log + * - flushed log from Log service + */ + public void onErrors(List log) { + errors.addAll(log); + } + public void onFinishedConfig(String configName) { log.info("onFinishedConfig"); // invoke("publishEvent", "configFinished"); @@ -1062,6 +1111,10 @@ public void onGestureStatus(Status status) { unsubscribe("python", "publishStatus", this.getName(), "onGestureStatus"); } + /** + * Central hub of input motion control. Potentially, all input from joysticks, + * quest2 controllers and headset, or any IK service could be sent here + */ @Override public void onJointAngles(Map angleMap) { log.debug("onJointAngles {}", angleMap); @@ -1087,7 +1140,7 @@ public void onJoystickInput(JoystickData input) throws Exception { * including lower level logs that do not propegate as statuses * * @param log - * - flushed log from Log service + * - flushed log from Log service */ public void onLogEvents(List log) { // scan for warn or errors @@ -1127,11 +1180,13 @@ public OpenCVData onOpenCVData(OpenCVData data) { * @param volume */ public void onPeak(double volume) { - if (config.neoPixelFlashWhenSpeaking && !configStarted) { - if (volume > 0.5) { - invoke("publishSpeakingFlash", "speaking"); - } - } + processMessage("onPeak", volume); + } + + public void onPirOff() { + log.info("onPirOff"); + setPredicate(String.format("%s.pir_off", getName()), System.currentTimeMillis()); + processMessage("onPirOff"); } /** @@ -1151,10 +1206,6 @@ public void onPirOn() { } } - public void onPirOff() { - log.info("onPirOff"); - } - // GOOD GOOD GOOD - LOOPBACK - flexible and replacable by python // yet provides a stable default, which can be fully replaced // Works using common pub/sub rules @@ -1193,6 +1244,15 @@ public boolean onSense(boolean b) { return b; } + /** + * When a new session is started this will sync config with it + * + * @param sessionKey + */ + public void onSession(String sessionKey) { + configToPredicates(); + } + /** * runtime re-publish relay * @@ -1278,8 +1338,15 @@ public void onStarted(String name) { } } + @Override + public void onStartSpeaking(String utterance) { + processMessage("onStartSpeaking", utterance); + isSpeaking = true; + } + @Override public void onStopped(String name) { + log.info("service {} has stopped"); // using release peer for peer releasing // FIXME - auto remove subscriptions of peers? } @@ -1326,6 +1393,31 @@ public void powerUp() { python.execMethod("power_up"); } + public void processMessage(String method) { + processMessage(method, (Object[]) null); + } + + /** + * Will publish processing messages to the processor(s) currently subscribed. + * + * @param method + * @param data + */ + public void processMessage(String method, Object... data) { + // User processing should not occur until after boot has completed + if (!state.equals("boot")) { + // FIXME - this needs to be in config + // FIXME - change peer name to "processor" + // String processor = getPeerName("py4j"); + String processor = "python"; + + Message msg = Message.createMessage(getName(), processor, method, data); + // FIXME - is this too much abstraction .. to publish as well as + // configurable send ? + invoke("publishProcessMessage", msg); + } + } + /** * easy utility to publishMessage * @@ -1398,8 +1490,7 @@ public Message publishMessage(Message msg) { return msg; } - public HashMap publishMoveArm(String which, Double bicep, Double rotate, Double shoulder, - Double omoplate) { + public HashMap publishMoveArm(String which, Double bicep, Double rotate, Double shoulder, Double omoplate) { HashMap map = new HashMap<>(); map.put("bicep", bicep); map.put("rotate", rotate); @@ -1413,8 +1504,7 @@ public HashMap publishMoveArm(String which, Double bicep, Double return map; } - public HashMap publishMoveHand(String which, Double thumb, Double index, Double majeure, - Double ringFinger, Double pinky, Double wrist) { + public HashMap publishMoveHand(String which, Double thumb, Double index, Double majeure, Double ringFinger, Double pinky, Double wrist) { HashMap map = new HashMap<>(); map.put("which", which); map.put("thumb", thumb); @@ -1431,8 +1521,7 @@ public HashMap publishMoveHand(String which, Double thumb, Doubl return map; } - public HashMap publishMoveHead(Double neck, Double rothead, Double eyeX, Double eyeY, Double jaw, - Double rollNeck) { + public HashMap publishMoveHead(Double neck, Double rothead, Double eyeX, Double eyeY, Double jaw, Double rollNeck) { HashMap map = new HashMap<>(); map.put("neck", neck); map.put("rothead", rothead); @@ -1452,8 +1541,7 @@ public HashMap publishMoveLeftArm(Double bicep, Double rotate, D return map; } - public HashMap publishMoveLeftHand(Double thumb, Double index, Double majeure, Double ringFinger, - Double pinky, Double wrist) { + public HashMap publishMoveLeftHand(Double thumb, Double index, Double majeure, Double ringFinger, Double pinky, Double wrist) { HashMap map = new HashMap<>(); map.put("thumb", thumb); map.put("index", index); @@ -1473,8 +1561,7 @@ public HashMap publishMoveRightArm(Double bicep, Double rotate, return map; } - public HashMap publishMoveRightHand(Double thumb, Double index, Double majeure, Double ringFinger, - Double pinky, Double wrist) { + public HashMap publishMoveRightHand(Double thumb, Double index, Double majeure, Double ringFinger, Double pinky, Double wrist) { HashMap map = new HashMap<>(); map.put("thumb", thumb); map.put("index", index); @@ -1492,8 +1579,44 @@ public HashMap publishMoveTorso(Double topStom, Double midStom, map.put("lowStom", lowStom); return map; } - - + + public String publishPlayAudioFile(String filename) { + return filename; + } + + /** + * One of the most important publishing point. Processing publishing point, + * where everything InMoov2 wants to be processed is turned into a message and + * published. + * + * @param msg + * @return + */ + public Message publishProcessMessage(Message msg) { + return msg; + } + + /** + * Possible pub/sub way to interface with python - no blocking though + * + * @param code + * @return + */ + public String publishPython(String code) { + return code; + } + + /** + * publishes a name for NeoPixel.onFlash to consume, in a seperate channel to + * potentially be used by "speaking only" leds + * + * @param name + * @return + */ + public String publishSpeakingFlash(String name) { + return name; + } + /** * publishStateChange * @@ -1532,43 +1655,25 @@ public StateChange publishStateChange(StateChange stateChange) { return stateChange; } - - public void processMessage(String method) { - processMessage(method, (Object[])null); - } /** - * Will publish processing messages to the processor(s) currently subscribed. - * - * @param method - * @param data + * stop animation event */ - public void processMessage(String method, Object... data) { - // User processing should not occur until after boot has completed - if (!state.equals("boot")) { - // FIXME - this needs to be in config - // FIXME - change peer name to "processor" - // String processor = getPeerName("py4j"); - String processor = "python"; - - Message msg = Message.createMessage(getName(), processor, method, data); - // FIXME - is this too much abstraction .. to publish as well as - // configurable send ? - invoke("publishProcessMessage", msg); - } + public void publishStopAnimation() { } - + /** - * One of the most important publishing point. Processing publishing point, - * where everything InMoov2 wants to be processed is turned into a message and - * published. + * event publisher for the fsm - although other services potentially can + * consume and filter this event channel * - * @param msg + * @param event * @return */ - public Message publishProcessMessage(Message msg) { - return msg; - } + public String publishSystemEvent(String event) { + // well, it turned out underscore was a goofy selection, as underscore in + // aiml is wildcard ... duh + return String.format("SYSTEM_EVENT %s", event); + } /** * all published text from InMoov2 - including ProgramAB @@ -1636,12 +1741,17 @@ public void setAutoDisable(Boolean param) { sendToPeer("torso", "setAutoDisable", param); } + @Override + public void setConfigValue(String fieldname, Object value) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { + super.setConfigValue(fieldname, value); + setPredicate(fieldname, value); + } + public void setHandSpeed(String which, Double thumb, Double index, Double majeure, Double ringFinger, Double pinky) { setHandSpeed(which, thumb, index, majeure, ringFinger, pinky, null); } - public void setHandSpeed(String which, Double thumb, Double index, Double majeure, Double ringFinger, Double pinky, - Double wrist) { + public void setHandSpeed(String which, Double thumb, Double index, Double majeure, Double ringFinger, Double pinky, Double wrist) { InMoov2Hand hand = getHand(which); if (hand == null) { warn("%s hand not started", which); @@ -1651,14 +1761,12 @@ public void setHandSpeed(String which, Double thumb, Double index, Double majeur } @Deprecated - public void setHandVelocity(String which, Double thumb, Double index, Double majeure, Double ringFinger, - Double pinky) { + public void setHandVelocity(String which, Double thumb, Double index, Double majeure, Double ringFinger, Double pinky) { setHandSpeed(which, thumb, index, majeure, ringFinger, pinky, null); } @Deprecated - public void setHandVelocity(String which, Double thumb, Double index, Double majeure, Double ringFinger, Double pinky, - Double wrist) { + public void setHandVelocity(String which, Double thumb, Double index, Double majeure, Double ringFinger, Double pinky, Double wrist) { setHandSpeed(which, thumb, index, majeure, ringFinger, pinky, wrist); } @@ -1674,8 +1782,7 @@ public void setHeadSpeed(Double rothead, Double neck, Double eyeXSpeed, Double e setHeadSpeed(rothead, neck, eyeXSpeed, eyeYSpeed, jawSpeed, null); } - public void setHeadSpeed(Double rothead, Double neck, Double eyeXSpeed, Double eyeYSpeed, Double jawSpeed, - Double rollNeckSpeed) { + public void setHeadSpeed(Double rothead, Double neck, Double eyeXSpeed, Double eyeYSpeed, Double jawSpeed, Double rollNeckSpeed) { sendToPeer("head", "setSpeed", rothead, neck, eyeXSpeed, eyeYSpeed, jawSpeed, rollNeckSpeed); } @@ -1699,8 +1806,7 @@ public void setHeadVelocity(Double rothead, Double neck, Double eyeXSpeed, Doubl } @Deprecated - public void setHeadVelocity(Double rothead, Double neck, Double eyeXSpeed, Double eyeYSpeed, Double jawSpeed, - Double rollNeckSpeed) { + public void setHeadVelocity(Double rothead, Double neck, Double eyeXSpeed, Double eyeYSpeed, Double jawSpeed, Double rollNeckSpeed) { setHeadSpeed(rothead, neck, eyeXSpeed, eyeYSpeed, jawSpeed, rollNeckSpeed); } @@ -1712,15 +1818,12 @@ public void setLeftArmSpeed(Integer bicep, Integer rotate, Integer shoulder, Int setArmSpeed("left", (double) bicep, (double) rotate, (double) shoulder, (double) omoplate); } - public void setLeftHandSpeed(Double thumb, Double index, Double majeure, Double ringFinger, Double pinky, - Double wrist) { + public void setLeftHandSpeed(Double thumb, Double index, Double majeure, Double ringFinger, Double pinky, Double wrist) { setHandSpeed("left", thumb, index, majeure, ringFinger, pinky, wrist); } - public void setLeftHandSpeed(Integer thumb, Integer index, Integer majeure, Integer ringFinger, Integer pinky, - Integer wrist) { - setHandSpeed("left", (double) thumb, (double) index, (double) majeure, (double) ringFinger, (double) pinky, - (double) wrist); + public void setLeftHandSpeed(Integer thumb, Integer index, Integer majeure, Integer ringFinger, Integer pinky, Integer wrist) { + setHandSpeed("left", (double) thumb, (double) index, (double) majeure, (double) ringFinger, (double) pinky, (double) wrist); } @Override @@ -1758,12 +1861,8 @@ public void setNeopixelAnimation(String animation, Integer red, Integer green, I sendToPeer("neopixel", "animation", red, green, blue, speed); } - public void setOpenCV(OpenCV opencv) { - this.opencv = opencv; - } - public boolean setPirPlaySounds(boolean b) { - getTypedConfig().pirPlaySounds = b; + config.pirPlaySounds = b; return b; } @@ -1789,15 +1888,12 @@ public void setRightArmSpeed(Integer bicep, Integer rotate, Integer shoulder, In setArmSpeed("right", (double) bicep, (double) rotate, (double) shoulder, (double) omoplate); } - public void setRightHandSpeed(Double thumb, Double index, Double majeure, Double ringFinger, Double pinky, - Double wrist) { + public void setRightHandSpeed(Double thumb, Double index, Double majeure, Double ringFinger, Double pinky, Double wrist) { setHandSpeed("right", thumb, index, majeure, ringFinger, pinky, wrist); } - public void setRightHandSpeed(Integer thumb, Integer index, Integer majeure, Integer ringFinger, Integer pinky, - Integer wrist) { - setHandSpeed("right", (double) thumb, (double) index, (double) majeure, (double) ringFinger, (double) pinky, - (double) wrist); + public void setRightHandSpeed(Integer thumb, Integer index, Integer majeure, Integer ringFinger, Integer pinky, Integer wrist) { + setHandSpeed("right", (double) thumb, (double) index, (double) majeure, (double) ringFinger, (double) pinky, (double) wrist); } public boolean setSpeechType(String speechType) { @@ -1837,6 +1933,10 @@ public boolean setSpeechType(String speechType) { // return speechType; } + public void setTopic(String topic) { + chatBot.setTopic(topic); + } + public void setTorsoSpeed(Double topStom, Double midStom, Double lowStom) { sendToPeer("torso", "setSpeed", topStom, midStom, lowStom); } @@ -1960,8 +2060,7 @@ public ProgramAB startChatBot() { chatBot.setPredicate("null", ""); // load last user session if (!chatBot.getPredicate("name").isEmpty()) { - if (chatBot.getPredicate("lastUsername").isEmpty() || chatBot.getPredicate("lastUsername").equals("unknown") - || chatBot.getPredicate("lastUsername").equals("default")) { + if (chatBot.getPredicate("lastUsername").isEmpty() || chatBot.getPredicate("lastUsername").equals("unknown") || chatBot.getPredicate("lastUsername").equals("default")) { chatBot.setPredicate("lastUsername", chatBot.getPredicate("name")); } } @@ -1977,8 +2076,7 @@ public ProgramAB startChatBot() { // !chatBot.getPredicate("default", "lastUsername").equals("unknown")) { // chatBot.startSession(chatBot.getPredicate("lastUsername")); // } - if (chatBot.getPredicate("default", "firstinit").isEmpty() - || chatBot.getPredicate("default", "firstinit").equals("unknown") + if (chatBot.getPredicate("default", "firstinit").isEmpty() || chatBot.getPredicate("default", "firstinit").equals("unknown") || chatBot.getPredicate("default", "firstinit").equals("started")) { chatBot.startSession(chatBot.getPredicate("default", "lastUsername")); invoke("publishEvent", "FIRST INIT"); From e8950870575a67e40e37dafdf710d21a5e9ffea9 Mon Sep 17 00:00:00 2001 From: supertick Date: Tue, 2 Apr 2024 07:54:39 -0700 Subject: [PATCH 3/9] synch'd config --- .../service/config/InMoov2Config.java | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/myrobotlab/service/config/InMoov2Config.java b/src/main/java/org/myrobotlab/service/config/InMoov2Config.java index 2d1b121dae..b4e7bbf0bc 100644 --- a/src/main/java/org/myrobotlab/service/config/InMoov2Config.java +++ b/src/main/java/org/myrobotlab/service/config/InMoov2Config.java @@ -37,7 +37,7 @@ public class InMoov2Config extends ServiceConfig { public boolean flashOnErrors = true; - public boolean flashOnPir; + public boolean flashOnPir = false; public boolean forceMicroOnIfSleeping = true; @@ -276,7 +276,8 @@ public Plan getDefault(Plan plan, String name) { } } - chatBot.listeners.add(new Listener("publishText", name + ".htmlFilter", "onText")); + chatBot.listeners.add(new Listener("publishText", getPeerName("htmlFilter"), "onText")); + chatBot.listeners.add(new Listener("publishSession", name)); Gpt3Config gpt3 = (Gpt3Config) plan.get(getPeerName("gpt3")); gpt3.listeners.add(new Listener("publishText", name + ".htmlFilter", "onText")); @@ -290,7 +291,6 @@ public Plan getDefault(Plan plan, String name) { // setup name references to different services MarySpeechConfig mouth = (MarySpeechConfig) plan.get(getPeerName("mouth")); mouth.voice = "Mark"; - // == Peer - ear ============================= // setup name references to different services WebkitSpeechRecognitionConfig ear = (WebkitSpeechRecognitionConfig) plan.get(getPeerName("ear")); @@ -369,16 +369,16 @@ public Plan getDefault(Plan plan, String name) { // TODO - events easily gotten from InMoov data ?? auto callbacks in python // if // exists ? - fsm.current = "boot"; + fsm.start = "boot"; fsm.transitions.add(new Transition("boot", "wake", "wake")); // setup, nor sleep should be affected by idle fsm.transitions.add(new Transition("setup", "setup_done", "idle")); - fsm.transitions.add(new Transition("idle", "random", "random")); fsm.transitions.add(new Transition("random", "idle", "idle")); fsm.transitions.add(new Transition("idle", "sleep", "sleep")); + fsm.transitions.add(new Transition("idle", "power_down", "power_down")); + fsm.transitions.add(new Transition("idle", "random", "random")); fsm.transitions.add(new Transition("sleep", "wake", "wake")); fsm.transitions.add(new Transition("sleep", "power_down", "power_down")); - fsm.transitions.add(new Transition("idle", "power_down", "power_down")); fsm.transitions.add(new Transition("wake", "setup", "setup")); fsm.transitions.add(new Transition("wake", "idle", "idle")); fsm.transitions.add(new Transition("idle", "setup", "setup")); @@ -515,8 +515,9 @@ public Plan getDefault(Plan plan, String name) { // listeners.add(new Listener("publishConfigFinished", name)); LogConfig log = (LogConfig) plan.get(getPeerName("log")); - log.level = "WARN"; - log.listeners.add(new Listener("publishLogEvents", name)); + log.level = "warn"; + log.listeners.add(new Listener("publishErrors", name)); + // service --to--> InMoov2 // mouth_audioFile.listeners.add(new Listener("publishAudioEnd", name)); // mouth_audioFile.listeners.add(new Listener("publishAudioStart", name)); @@ -544,6 +545,8 @@ public Plan getDefault(Plan plan, String name) { // service --to--> InMoov2 AudioFileConfig mouth_audioFile = (AudioFileConfig) plan.get(getPeerName("mouth.audioFile")); mouth_audioFile.listeners.add(new Listener("publishPeak", name)); + + htmlFilter.listeners.add(new Listener("publishText", name)); htmlFilter.listeners.add(new Listener("publishText", name)); @@ -560,10 +563,12 @@ public Plan getDefault(Plan plan, String name) { fsm.listeners.add(new Listener("publishStateChange", name, "publishStateChange")); // peer --to--> peer + mouth.listeners.add(new Listener("publishStartSpeaking", name)); mouth.listeners.add(new Listener("publishStartSpeaking", getPeerName("ear"))); + mouth.listeners.add(new Listener("publishEndSpeaking", name)); mouth.listeners.add(new Listener("publishEndSpeaking", getPeerName("ear"))); return plan; } -} \ No newline at end of file +} From 3964a1ad7331b37fb1a9ec5462a82fc8d00e063a Mon Sep 17 00:00:00 2001 From: supertick Date: Tue, 2 Apr 2024 07:59:30 -0700 Subject: [PATCH 4/9] updated fsm --- .../org/myrobotlab/service/FiniteStateMachine.java | 14 ++++---------- .../service/config/FiniteStateMachineConfig.java | 2 +- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/myrobotlab/service/FiniteStateMachine.java b/src/main/java/org/myrobotlab/service/FiniteStateMachine.java index e998711e26..4089ac53f4 100644 --- a/src/main/java/org/myrobotlab/service/FiniteStateMachine.java +++ b/src/main/java/org/myrobotlab/service/FiniteStateMachine.java @@ -197,7 +197,8 @@ public void fire(String event) { stateMachine.send(event); current = stateMachine.getCurrent(); - log.info("fired event ({}) -> ({}) moves to ({})", event, last == null ? null : last.getName(), current == null ? null : current.getName()); + log.info("fired event ({}) -> ({}) moves to ({})", event, last == null ? null : last.getName(), + current == null ? null : current.getName()); if (last != null && !last.equals(current)) { StateChange stateChange = new StateChange(current.getName(), event); @@ -254,13 +255,6 @@ public StateChange publishStateChange(StateChange stateChange) { return stateChange; } - @Override - public FiniteStateMachineConfig getConfig() { - super.getConfig(); - config.current = getState(); - return config; - } - @Override public FiniteStateMachineConfig apply(FiniteStateMachineConfig c) { super.apply(c); @@ -280,8 +274,8 @@ public FiniteStateMachineConfig apply(FiniteStateMachineConfig c) { } // setCurrent - if (c.current != null) { - setCurrent(c.current); + if (c.start != null) { + setCurrent(c.start); } return c; diff --git a/src/main/java/org/myrobotlab/service/config/FiniteStateMachineConfig.java b/src/main/java/org/myrobotlab/service/config/FiniteStateMachineConfig.java index bd4e5648f3..e69c44a4f7 100644 --- a/src/main/java/org/myrobotlab/service/config/FiniteStateMachineConfig.java +++ b/src/main/java/org/myrobotlab/service/config/FiniteStateMachineConfig.java @@ -23,7 +23,7 @@ public Transition(String from, String event, String to) { public List transitions = new ArrayList<>(); - public String current = null; + public String start = null; } From 027fb25a874bc976f7283867081c9dd46f629ce7 Mon Sep 17 00:00:00 2001 From: supertick Date: Sun, 7 Apr 2024 08:47:22 -0700 Subject: [PATCH 5/9] api example and peak max --- api-example.sh | 11 +++++++++++ .../org/myrobotlab/service/config/InMoov2Config.java | 3 +++ .../resource/WebGui/app/service/js/AudioFileGui.js | 4 ++++ .../WebGui/app/service/views/AudioFileGui.html | 2 +- 4 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 api-example.sh diff --git a/api-example.sh b/api-example.sh new file mode 100644 index 0000000000..961fd93f78 --- /dev/null +++ b/api-example.sh @@ -0,0 +1,11 @@ +curl -X POST http://localhost:8888/api/service \ + -d '{"name":"i01.chatBot","method":"getResponse","data":["grog", "hi there!"]}' + +curl -X POST http://localhost:8888/api/service/i01.chatBot/getResponse \ + -d '["grog", "hi there!"]' + +curl -X POST http://localhost:8888/api/service/i01.chatBot/setCurrentBotName \ + -d '["ru-RU"]' + + + diff --git a/src/main/java/org/myrobotlab/service/config/InMoov2Config.java b/src/main/java/org/myrobotlab/service/config/InMoov2Config.java index b4e7bbf0bc..54ee9d764d 100644 --- a/src/main/java/org/myrobotlab/service/config/InMoov2Config.java +++ b/src/main/java/org/myrobotlab/service/config/InMoov2Config.java @@ -124,6 +124,9 @@ public class InMoov2Config extends ServiceConfig { */ public int sleepTimeoutMs = 300000; + /** + * Start sound + */ public boolean startupSound = true; /** diff --git a/src/main/resources/resource/WebGui/app/service/js/AudioFileGui.js b/src/main/resources/resource/WebGui/app/service/js/AudioFileGui.js index 1edc44bbf8..2a34217609 100644 --- a/src/main/resources/resource/WebGui/app/service/js/AudioFileGui.js +++ b/src/main/resources/resource/WebGui/app/service/js/AudioFileGui.js @@ -3,6 +3,7 @@ angular.module('mrlapp.service.AudioFileGui', []).controller('AudioFileGuiCtrl', var _self = this var msg = this.msg $scope.peak = 0 + $scope.peakMax = 0 // playing paused stopped $scope.activity = null @@ -90,6 +91,9 @@ angular.module('mrlapp.service.AudioFileGui', []).controller('AudioFileGuiCtrl', break case 'onPeak': $scope.peak = Math.round(data/* * 100 */) + if ($scope.peak > $scope.peakMax){ + $scope.peakMax = $scope.peak + } $scope.$apply() break diff --git a/src/main/resources/resource/WebGui/app/service/views/AudioFileGui.html b/src/main/resources/resource/WebGui/app/service/views/AudioFileGui.html index 49edaff5a9..ffd479fc41 100644 --- a/src/main/resources/resource/WebGui/app/service/views/AudioFileGui.html +++ b/src/main/resources/resource/WebGui/app/service/views/AudioFileGui.html @@ -101,7 +101,7 @@
- loudness {{peak}} + loudness {{peak}} max {{peakMax}}
From 012491855988ce502827395877fd26b615582fa3 Mon Sep 17 00:00:00 2001 From: supertick Date: Wed, 17 Apr 2024 13:21:51 -0700 Subject: [PATCH 6/9] fixed default programab bot config --- .../java/org/myrobotlab/service/config/ProgramABConfig.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/org/myrobotlab/service/config/ProgramABConfig.java b/src/main/java/org/myrobotlab/service/config/ProgramABConfig.java index 5e48ce636f..d91131ae66 100644 --- a/src/main/java/org/myrobotlab/service/config/ProgramABConfig.java +++ b/src/main/java/org/myrobotlab/service/config/ProgramABConfig.java @@ -52,6 +52,10 @@ public class ProgramABConfig extends ServiceConfig { public Plan getDefault(Plan plan, String name) { super.getDefault(plan, name); addDefaultPeerConfig(plan, name, "search", "Wikipedia"); + bots.add("resource/ProgramAB/Alice"); + bots.add("resource/ProgramAB/Dr.Who"); + bots.add("resource/ProgramAB/Ency"); + bots.add("resource/ProgramAB/Mr. Turing"); return plan; } From cfab826e534d3171274636176ad61a591d22ee62 Mon Sep 17 00:00:00 2001 From: supertick Date: Fri, 19 Apr 2024 13:01:48 -0700 Subject: [PATCH 7/9] let ImageDisplay show as available service --- .../java/org/myrobotlab/service/meta/ImageDisplayMeta.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/main/java/org/myrobotlab/service/meta/ImageDisplayMeta.java b/src/main/java/org/myrobotlab/service/meta/ImageDisplayMeta.java index e6fe0165ba..7a19a9e273 100644 --- a/src/main/java/org/myrobotlab/service/meta/ImageDisplayMeta.java +++ b/src/main/java/org/myrobotlab/service/meta/ImageDisplayMeta.java @@ -15,12 +15,6 @@ public class ImageDisplayMeta extends MetaData { public ImageDisplayMeta() { addDescription("IBus serial protocol"); setAvailable(true); // false if you do not want it viewable in a gui - // add dependency if necessary - - // TEMPORARY CORE DEPENDENCIES !!! (for uber-jar) - // addDependency("orgId", "artifactId", "2.4.0"); - - setAvailable(false); addCategory("general"); } From 8137ca69148b78bdf4e743942d9827ce7297d4f7 Mon Sep 17 00:00:00 2001 From: supertick Date: Mon, 22 Apr 2024 11:32:43 -0700 Subject: [PATCH 8/9] fixed config selected and onConfigFinished --- .../java/org/myrobotlab/service/Gpt3.java | 2 ++ .../java/org/myrobotlab/service/InMoov2.java | 13 ++++++- .../WebGui/app/service/js/RuntimeGui.js | 34 ++++++++++++------- .../WebGui/app/service/views/RuntimeGui.html | 6 ++-- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/myrobotlab/service/Gpt3.java b/src/main/java/org/myrobotlab/service/Gpt3.java index 93e4404b3c..b7b3308d64 100644 --- a/src/main/java/org/myrobotlab/service/Gpt3.java +++ b/src/main/java/org/myrobotlab/service/Gpt3.java @@ -109,6 +109,8 @@ public Response getResponse(String text) { HttpClient http = (HttpClient) startPeer("http"); + log.info("curl {} -d '{}'", c.url, json); + String msg = http.postJson(c.token, c.url, json); Map payload = CodecUtils.fromJson(msg, new StaticType<>() {}); diff --git a/src/main/java/org/myrobotlab/service/InMoov2.java b/src/main/java/org/myrobotlab/service/InMoov2.java index 3077d0472a..1152be9af6 100644 --- a/src/main/java/org/myrobotlab/service/InMoov2.java +++ b/src/main/java/org/myrobotlab/service/InMoov2.java @@ -1096,12 +1096,23 @@ public void onErrors(List log) { errors.addAll(log); } + @Deprecated /* use onConfigFinished */ public void onFinishedConfig(String configName) { log.info("onFinishedConfig"); - // invoke("publishEvent", "configFinished"); invoke("publishConfigFinished", configName); } + public void onConfigFinished(String configName) { + log.info("onConfigFinished"); + invoke("publishConfigFinished", configName); + } + + public void onConfigStarted(String configName) { + log.info("onConfigStarted"); + invoke("publishConfigStarted", configName); + } + + public void onGestureStatus(Status status) { if (!status.equals(Status.success()) && !status.equals(Status.warn("Python process killed !"))) { error("I cannot execute %s, please check logs", lastGestureExecuted); diff --git a/src/main/resources/resource/WebGui/app/service/js/RuntimeGui.js b/src/main/resources/resource/WebGui/app/service/js/RuntimeGui.js index 143f739d3f..8820b2de1f 100644 --- a/src/main/resources/resource/WebGui/app/service/js/RuntimeGui.js +++ b/src/main/resources/resource/WebGui/app/service/js/RuntimeGui.js @@ -5,6 +5,12 @@ angular.module('mrlapp.service.RuntimeGui', []).controller('RuntimeGuiCtrl', ['$ var statusMaxSize = 2500 + // configName is static so it needs to be + // kept in sync on a subobject + $scope.selected = { + configName :"default" + } + this.updateState = function(service) { $scope.service = service $scope.locale.selected = service.locale.language @@ -96,8 +102,8 @@ angular.module('mrlapp.service.RuntimeGui', []).controller('RuntimeGuiCtrl', ['$ $scope.setConfig = function() { console.info('setConfig') if ($scope.selectedConfig.length > 0) { - $scope.service.configName = $scope.selectedConfig[0] - msg.sendTo('runtime', 'setConfig', $scope.service.configName) + msg.sendTo('runtime', 'setConfig', $scope.selectedConfig[0]) + msg.sendTo('runtime', 'getConfigName') } } @@ -230,10 +236,13 @@ angular.module('mrlapp.service.RuntimeGui', []).controller('RuntimeGuiCtrl', ['$ } break case 'onReleased': - console.info("runtime - onRelease" + data) + console.info("runtime - onRelease " + data) break case 'onConfigName': - console.info("runtime - onConfigName" + data) + console.info("runtime - onConfigName " + data) + // is not part of service, because configName is static + $scope.selected.configName = data + $scope.$apply() break case 'onHeartbeat': let heartbeat = data @@ -338,7 +347,7 @@ angular.module('mrlapp.service.RuntimeGui', []).controller('RuntimeGuiCtrl', ['$ console.info('saveConfig') let onOK = function() { - msg.sendTo('runtime', 'savePlan', $scope.service.configName) + msg.sendTo('runtime', 'savePlan', $scope.selected.configName) // msg.sendTo('runtime', 'save') } @@ -355,10 +364,6 @@ angular.module('mrlapp.service.RuntimeGui', []).controller('RuntimeGuiCtrl', ['$ msg.send('saveDefaults', $scope.newType.simpleName) } - $scope.getConfigName = function(){ - return $scope.service.configName - } - $scope.setAutoStart = function(b) { console.info('setAutoStart') msg.send('setAutoStart', b) @@ -367,7 +372,8 @@ angular.module('mrlapp.service.RuntimeGui', []).controller('RuntimeGuiCtrl', ['$ $scope.saveConfig = function() { $scope.service.includePeers = false $scope.service.selectedOption = "current" - + + $scope.selected.configName = $scope.selected.configName var modalInstance = $uibModal.open({ templateUrl: 'saveConfig.html', scope: $scope, @@ -385,15 +391,17 @@ angular.module('mrlapp.service.RuntimeGui', []).controller('RuntimeGuiCtrl', ['$ modalInstance.result.then(function(result) { // Handle 'OK' button click - console.log('Config Name: ' + $scope.service.configName) + console.log('Config Name: ' + $scope.selected.configName) console.log('Selected Option: ' + $scope.service.selectedOption) console.log('includePeers Option: ' + $scope.service.includePeers) console.log('configType Option: ' + $scope.service.configType) + msg.send('setConfig', $scope.selected.configName) if ($scope.service.selectedOption == 'default'){ - msg.send('saveDefault', $scope.service.configName, $scope.service.defaultServiceName, $scope.service.configType, $scope.service.includePeers) + msg.send('saveDefault', $scope.selected.configName, $scope.service.defaultServiceName, $scope.service.configType, $scope.service.includePeers) } else { - msg.sendTo('runtime', 'saveConfig', $scope.service.configName) + msg.sendTo('runtime', 'saveConfig', $scope.selected.configName) } + msg.send('getConfigName') }, function() { // Handle 'Cancel' button click or modal dismissal console.log('Modal dismissed') diff --git a/src/main/resources/resource/WebGui/app/service/views/RuntimeGui.html b/src/main/resources/resource/WebGui/app/service/views/RuntimeGui.html index 7e1fd406ff..c81bb2b837 100644 --- a/src/main/resources/resource/WebGui/app/service/views/RuntimeGui.html +++ b/src/main/resources/resource/WebGui/app/service/views/RuntimeGui.html @@ -1,4 +1,4 @@ -

{{platform.arch}}.{{platform.jvmBitness}}.{{platform.os}} {{platform.mrlVersion}}

+

{{platform.arch}}.{{platform.jvmBitness}}.{{platform.os}} {{platform.mrlVersion}} {{service.id}}

@@ -58,7 +58,7 @@

{{platform.arch}}.{{platform.jvmBitness}}.{{platform.os}} {{platform.mrlVer
- Configurations {{getConfigName()}} + Configurations {{selected.configName}}

Save your current configuration in a directory named
- +


From 0b17318e5e579e6af330e739bdb71db7755f1083 Mon Sep 17 00:00:00 2001 From: Langevin Gael Date: Mon, 22 Apr 2024 22:37:54 +0200 Subject: [PATCH 9/9] peak icon (#1417) --- src/main/resources/resource/peak.png | Bin 0 -> 13300 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/main/resources/resource/peak.png diff --git a/src/main/resources/resource/peak.png b/src/main/resources/resource/peak.png new file mode 100644 index 0000000000000000000000000000000000000000..03106b3b233b47a42cc6441571ecd89c1ec73ab5 GIT binary patch literal 13300 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