diff --git a/firmware/controllers/actuators/electronic_throttle.cpp b/firmware/controllers/actuators/electronic_throttle.cpp index 47472b5488..fdefe63888 100644 --- a/firmware/controllers/actuators/electronic_throttle.cpp +++ b/firmware/controllers/actuators/electronic_throttle.cpp @@ -264,6 +264,7 @@ DISPLAY(DISPLAY_IF(hasEtbPedalPositionSensor)) DISPLAY_TEXT(Pedal); DISPLAY_SENSOR(PPS); + DISPLAY(DISPLAY_CONFIG(throttlePedalPositionAdcChannel)); DISPLAY_TEXT(eol); DISPLAY_STATE(ETB_pid) diff --git a/java_console/io/src/com/rusefi/ui/livedocs/StateId.java b/java_console/io/src/com/rusefi/ui/livedocs/LiveDataContext.java similarity index 80% rename from java_console/io/src/com/rusefi/ui/livedocs/StateId.java rename to java_console/io/src/com/rusefi/ui/livedocs/LiveDataContext.java index 66015c8210..711a7bae8a 100644 --- a/java_console/io/src/com/rusefi/ui/livedocs/StateId.java +++ b/java_console/io/src/com/rusefi/ui/livedocs/LiveDataContext.java @@ -7,10 +7,10 @@ import java.util.Objects; *

* (c) Andrey Belomutskiy 2013-2019 */ -public class StateId { +public class LiveDataContext { private final int id; - public StateId(int id) { + public LiveDataContext(int id) { this.id = id; } @@ -20,7 +20,7 @@ public class StateId { @Override public String toString() { - return "StateId{" + + return "LiveDataContext{" + "id=" + id + '}'; } @@ -29,7 +29,7 @@ public class StateId { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - StateId stateId = (StateId) o; + LiveDataContext stateId = (LiveDataContext) o; return id == stateId.id; } diff --git a/java_console/io/src/com/rusefi/ui/livedocs/LiveDocHolder.java b/java_console/io/src/com/rusefi/ui/livedocs/LiveDocHolder.java index 9254fd6672..edaf1069e3 100644 --- a/java_console/io/src/com/rusefi/ui/livedocs/LiveDocHolder.java +++ b/java_console/io/src/com/rusefi/ui/livedocs/LiveDocHolder.java @@ -3,27 +3,29 @@ package com.rusefi.ui.livedocs; import com.rusefi.binaryprotocol.BinaryProtocol; import com.rusefi.config.Field; -import java.util.List; - public abstract class LiveDocHolder { - private final StateId id; - private final List actions; + private final LiveDataContext id; + private final RefreshActionsMap actions; private final Field[] values; - public LiveDocHolder(StateId id, List actions, Field[] values) { + public LiveDocHolder(LiveDataContext id, com.rusefi.ui.livedocs.RefreshActionsMap actions, Field[] values) { this.id = id; this.actions = actions; this.values = values; } - public void update(BinaryProtocol binaryProtocol, byte[] response) { - for (RefreshActions action : actions) + public RefreshActionsMap getActions() { + return actions; + } + + public void update(BinaryProtocol binaryProtocol, LiveDataContext context, byte[] response) { + for (RefreshActions action : actions.getActions().get(context)) action.refresh(binaryProtocol, response); } public abstract boolean isVisible(); - public StateId getId() { + public LiveDataContext getId() { return id; } diff --git a/java_console/io/src/com/rusefi/ui/livedocs/LiveDocsRegistry.java b/java_console/io/src/com/rusefi/ui/livedocs/LiveDocsRegistry.java index 590cee06f2..e274a3e7fe 100644 --- a/java_console/io/src/com/rusefi/ui/livedocs/LiveDocsRegistry.java +++ b/java_console/io/src/com/rusefi/ui/livedocs/LiveDocsRegistry.java @@ -27,13 +27,15 @@ public enum LiveDocsRegistry { boolean visible = holder.isVisible(); System.out.println(holder + ": is_visible=" + visible); if (visible) { - refresh(binaryProtocol, holder); + for (LiveDataContext context : holder.getActions().getActions().keySet()) { + refresh(binaryProtocol, holder, context); + } } } } - private void refresh(BinaryProtocol binaryProtocol, LiveDocHolder holder) { - int liveDocRequestId = holder.getId().getId(); + private void refresh(BinaryProtocol binaryProtocol, LiveDocHolder holder, LiveDataContext context) { + int liveDocRequestId = context.getId(); int size = holder.getStructSize(); byte packet[] = new byte[5]; @@ -49,6 +51,6 @@ public enum LiveDocsRegistry { System.arraycopy(responseWithCode, 1, response, 0, size); - holder.update(binaryProtocol, response); + holder.update(binaryProtocol, context, response); } } diff --git a/java_console/io/src/com/rusefi/ui/livedocs/RefreshActionsMap.java b/java_console/io/src/com/rusefi/ui/livedocs/RefreshActionsMap.java new file mode 100644 index 0000000000..901740b0c4 --- /dev/null +++ b/java_console/io/src/com/rusefi/ui/livedocs/RefreshActionsMap.java @@ -0,0 +1,26 @@ +package com.rusefi.ui.livedocs; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class RefreshActionsMap { + private final Map> actions = new HashMap<>(); + + public void put(LiveDataContext context, RefreshActions refreshAction) { + actions.putIfAbsent(context, new ArrayList<>()); + actions.get(context).add(refreshAction); + } + + public void addAll(RefreshActionsMap actions) { + for (Map.Entry> e : actions.actions.entrySet()) { + for (RefreshActions action : e.getValue()) + put(e.getKey(), action); + } + } + + public Map> getActions() { + return actions; + } +} diff --git a/java_console/ui/src/com/rusefi/ldmp/StateDictionary.java b/java_console/ui/src/com/rusefi/ldmp/StateDictionary.java index d247ba2c0e..f9a23f036d 100644 --- a/java_console/ui/src/com/rusefi/ldmp/StateDictionary.java +++ b/java_console/ui/src/com/rusefi/ldmp/StateDictionary.java @@ -5,6 +5,8 @@ import com.rusefi.config.generated.EngineState; import com.rusefi.config.generated.Fields; import com.rusefi.config.generated.PidState; import com.rusefi.config.generated.TriggerState; +import com.rusefi.ui.livedocs.LiveDataContext; +import org.jetbrains.annotations.NotNull; import java.util.HashMap; import java.util.Map; @@ -26,25 +28,35 @@ public enum StateDictionary { } public Field[] getValue(String state) { - String indexFieldName = "LDS_" + state.toUpperCase() + "_STATE_INDEX"; - java.lang.reflect.Field field = null; - try { - field = Fields.class.getField(indexFieldName); - } catch (NoSuchFieldException e) { - throw new IllegalStateException(e); - } - Objects.requireNonNull(field, "Field " + indexFieldName); - int indexValue; - try { - indexValue = (int) field.get(null); - } catch (IllegalAccessException e) { - throw new IllegalStateException(e); - } - Field[] result = map.get(indexValue); + String indexFieldName = getContextIndexFieldName(state); + LiveDataContext indexValue = getStateContext(indexFieldName); + Field[] result = map.get(indexValue.getId()); if (result == null) { throw new IllegalStateException("Nothing for " + indexFieldName + "/" + indexValue); } return result; } + @NotNull + public static String getContextIndexFieldName(String state) { + return "LDS_" + state.toUpperCase() + "_STATE_INDEX"; + } + + public static LiveDataContext getStateContext(String contextIndexFieldName) { + java.lang.reflect.Field field; + try { + field = Fields.class.getField(contextIndexFieldName); + } catch (NoSuchFieldException e) { + throw new IllegalStateException(e); + } + Objects.requireNonNull(field, "Field " + contextIndexFieldName); + int indexValue; + try { + indexValue = (int) field.get(null); + } catch (IllegalAccessException e) { + throw new IllegalStateException(e); + } + return new LiveDataContext(indexValue); + } + } diff --git a/java_console/ui/src/com/rusefi/ldmp/generated/ElectronicThrottleMeta.java b/java_console/ui/src/com/rusefi/ldmp/generated/ElectronicThrottleMeta.java index 58e8519aba..8999dff79b 100644 --- a/java_console/ui/src/com/rusefi/ldmp/generated/ElectronicThrottleMeta.java +++ b/java_console/ui/src/com/rusefi/ldmp/generated/ElectronicThrottleMeta.java @@ -11,6 +11,7 @@ public class ElectronicThrottleMeta { new TextRequest("eol"), new TextRequest("Pedal"), new SensorRequest("PPS"), + new ConfigRequest("throttlePedalPositionAdcChannel"), new TextRequest("eol"), new TextRequest("Output"), new FieldRequest("ETB_pid", "output"), diff --git a/java_console/ui/src/com/rusefi/ui/livedocs/ActionPanel.java b/java_console/ui/src/com/rusefi/ui/livedocs/ActionPanel.java index 82b2d84d9c..76f30ddb18 100644 --- a/java_console/ui/src/com/rusefi/ui/livedocs/ActionPanel.java +++ b/java_console/ui/src/com/rusefi/ui/livedocs/ActionPanel.java @@ -6,15 +6,16 @@ import javax.swing.*; import java.awt.*; import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * Multi-line horizontal flow panel. - * - * + *

+ *

* (c) Andrey Belomutskiy 2013-2019 */ public class ActionPanel { - List actionsList = new ArrayList<>(); + private final RefreshActionsMap refreshActions = new RefreshActionsMap(); private final JPanel panel = new JPanel(new MigLayout()); private JPanel currentLinePanel; @@ -42,4 +43,16 @@ public class ActionPanel { panel.add(currentLinePanel, "wrap"); } } + + public RefreshActionsMap getRefreshActions() { + return refreshActions; + } + + public void actionsListAdd(LiveDataContext context, RefreshActions refreshAction) { + refreshActions.put(context, refreshAction); + } + + public void actionsListAddAll(RefreshActionsMap actions) { + refreshActions.addAll(actions); + } } diff --git a/java_console/ui/src/com/rusefi/ui/livedocs/IfConditionPanel.java b/java_console/ui/src/com/rusefi/ui/livedocs/IfConditionPanel.java index e4bb504c00..9d90d1bfbe 100644 --- a/java_console/ui/src/com/rusefi/ui/livedocs/IfConditionPanel.java +++ b/java_console/ui/src/com/rusefi/ui/livedocs/IfConditionPanel.java @@ -10,17 +10,16 @@ import java.util.List; * (c) Andrey Belomutskiy 2013-2019 */ public class IfConditionPanel { - private final List actionsList = new ArrayList<>(); + private final RefreshActionsMap actionsList; private final JPanel panel = new JPanel(new MigLayout()); - public IfConditionPanel(JPanel result, List combined) { + public IfConditionPanel(JPanel result, RefreshActionsMap actionsList) { // todo: do we really need this proxy panel or can we just use parameter value? panel.add(result); - // todo: do we really need this list or can we just use parameter value? - actionsList.addAll(combined); + this.actionsList = actionsList; } - public List getActionsList() { + public RefreshActionsMap getActionsList() { return actionsList; } diff --git a/java_console/ui/src/com/rusefi/ui/livedocs/LiveDocPanel.java b/java_console/ui/src/com/rusefi/ui/livedocs/LiveDocPanel.java index a6eb137ae9..4f2f216d44 100644 --- a/java_console/ui/src/com/rusefi/ui/livedocs/LiveDocPanel.java +++ b/java_console/ui/src/com/rusefi/ui/livedocs/LiveDocPanel.java @@ -24,8 +24,6 @@ import javax.swing.*; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.util.ArrayList; -import java.util.List; import static com.rusefi.config.Field.niceToString; @@ -38,13 +36,13 @@ public class LiveDocPanel { private static final int LIVE_DATA_PRECISION = 2; @NotNull - static JPanel createPanel(String title, String settingsInstancePrefix, final int integerId, Field[] values, Request[] content) { - StateId id = new StateId(integerId); + static JPanel createPanel(String title, String settingsInstancePrefix, final int defaultContextId, Field[] values, Request[] content) { + LiveDataContext defaultContext = new LiveDataContext(defaultContextId); - ActionPanel ap = createComponents(title, content, values, settingsInstancePrefix); + ActionPanel ap = createComponents(title, content, values, settingsInstancePrefix, defaultContext); JPanel panel = ap.getPanel(); - LiveDocHolder holder = new LiveDocHolder(id, ap.actionsList, values) { + LiveDocHolder holder = new LiveDocHolder(defaultContext, ap.getRefreshActions(), values) { @Override public boolean isVisible() { boolean isVisible = !panel.getVisibleRect().isEmpty(); @@ -61,7 +59,7 @@ public class LiveDocPanel { return c.isVisible() && (parent == null || isRecursivelyVisible(parent)); } - private static ActionPanel createComponents(String title, Request[] content, Field[] values, String settingsInstancePrefix) { + private static ActionPanel createComponents(String title, Request[] content, Field[] values, String settingsInstancePrefix, LiveDataContext defaultContext) { ActionPanel result = new ActionPanel(title); for (Request r : content) { @@ -74,12 +72,13 @@ public class LiveDocPanel { } } else if (r instanceof FieldRequest) { FieldRequest request = (FieldRequest) r; + LiveDataContext context = getFieldContext(defaultContext, request.getStateContext()); Field field = getField(values, request); JLabel label = new JLabel("*"); label.setIcon(UiUtils.loadIcon("livedocs/variable.png")); label.setToolTipText("Variable " + field.getName()); result.addControl(label); - result.actionsList.add(new RefreshActions() { + result.actionsListAdd(context, new RefreshActions() { @Override public void refresh(BinaryProtocol bp, byte[] response) { Number fieldValue = field.getValue(new ConfigurationImage(response)); @@ -94,19 +93,19 @@ public class LiveDocPanel { JLabel label = new JLabel("*"); label.setIcon(UiUtils.loadIcon("livedocs/setting.png")); label.setToolTipText(getTooltipText(field.getName())); - result.actionsList.add(new RefreshActions() { + result.addControl(label); + // todo: use different notification flow altogether since configuration has nothing to do with live data structures + result.actionsListAdd(new LiveDataContext(Fields.LDS_ENGINE_STATE_INDEX), new RefreshActions() { @Override public void refresh(BinaryProtocol bp, byte[] response) { String value = field.getAnyValue(bp.getController()).toString(); label.setText(value); } }); - result.addControl(label); } else if (r instanceof SensorRequest) { SensorRequest request = (SensorRequest) r; Sensor sensor = Sensor.find(request.getValue()); JLabel label = new JLabel("*"); - result.addControl(label); label.setIcon(UiUtils.loadIcon("livedocs/gauge.png")); label.setToolTipText("Sensor " + request.getValue()); label.addMouseListener(new MouseAdapter() { @@ -118,19 +117,19 @@ public class LiveDocPanel { } } }); - result.actionsList.add(new RefreshActions() { + result.addControl(label); + SensorCentral.getInstance().addListener(sensor, new SensorCentral.SensorListener() { @Override - public void refresh(BinaryProtocol bp, byte[] response) { - double value = SensorCentral.getInstance().getValue(sensor); + public void onSensorUpdate(double value) { label.setText(niceToString(value, LIVE_DATA_PRECISION)); } }); } else if (r instanceof IfRequest) { IfRequest request = (IfRequest) r; - IfConditionPanel panel = createIfRequestPanel(request, values); + IfConditionPanel panel = createIfRequestPanel(request, values, defaultContext); - result.actionsList.addAll(panel.getActionsList()); + result.actionsListAddAll(panel.getActionsList()); result.addControl(panel.getPanel()); } else { @@ -140,6 +139,15 @@ public class LiveDocPanel { return result; } + private static LiveDataContext getFieldContext(LiveDataContext defaultContext, String stateContext) { + if (stateContext.isEmpty()) { + return defaultContext; + } else { + String indexFieldName = StateDictionary.getContextIndexFieldName(stateContext); + return StateDictionary.getStateContext(indexFieldName); + } + } + private static Field getField(Field[] defaultContext, FieldRequest request) { Field[] context; if (request.getStateContext().isEmpty()) { @@ -158,8 +166,7 @@ public class LiveDocPanel { return "Configuration " + dialogField.getUiName() + " (" + configurationFieldName + ")"; } - private static IfConditionPanel createIfRequestPanel(IfRequest request, Field[] values) { - + private static IfConditionPanel createIfRequestPanel(IfRequest request, Field[] values, LiveDataContext defaultContext) { Field conditionField = Field.findField(values, "", request.getVariable()); JPanel result = new JPanel(new VerticalFlowLayout()); @@ -168,16 +175,18 @@ public class LiveDocPanel { result.add(conditionLabel); - ActionPanel trueAP = createComponents("", request.trueBlock.toArray(new Request[0]), values, ""); - ActionPanel falseAP = createComponents("", request.falseBlock.toArray(new Request[0]), values, ""); + ActionPanel trueAP = createComponents("", request.trueBlock.toArray(new Request[0]), values, "", defaultContext); + ActionPanel falseAP = createComponents("", request.falseBlock.toArray(new Request[0]), values, "", defaultContext); result.add(trueAP.getPanel()); result.add(falseAP.getPanel()); - List combined = new ArrayList<>(trueAP.actionsList); - combined.addAll(falseAP.actionsList); + RefreshActionsMap combined = trueAP.getRefreshActions(); + combined.addAll(falseAP.getRefreshActions()); - combined.add(new RefreshActions() { + LiveDataContext context = getFieldContext(defaultContext, request.getStateContext()); + + combined.put(context, new RefreshActions() { @Override public void refresh(BinaryProtocol bp, byte[] response) { int value = (int) conditionField.getValue(new ConfigurationImage(response)); diff --git a/java_tools/configuration_definition/src/com/rusefi/ldmp/IfRequest.java b/java_tools/configuration_definition/src/com/rusefi/ldmp/IfRequest.java index f0286d5051..11cbd5fdd8 100644 --- a/java_tools/configuration_definition/src/com/rusefi/ldmp/IfRequest.java +++ b/java_tools/configuration_definition/src/com/rusefi/ldmp/IfRequest.java @@ -23,6 +23,10 @@ public class IfRequest extends Request { this.falseBlock.addAll(Arrays.asList(falseBlock)); } + public String getStateContext() { + return stateContext; + } + @Override public String toString() { return "IfRequest{" +