REO progress

token setup usability
This commit is contained in:
rusefi 2020-06-22 19:52:40 -04:00
parent b07ee61699
commit a48513cc1e
13 changed files with 210 additions and 100 deletions

View File

@ -19,6 +19,8 @@ public class AutoupdateUtil {
private static final int BUFFER_SIZE = 32 * 1024;
private static final int STEPS = 1000;
// todo: figure out a better way to work with absolute path
private static final String APPICON = "/appicon.png";
public static void downloadAutoupdateFile(String localZipFileName, ConnectionAndMeta connectionAndMeta, String title) throws IOException {
HttpURLConnection httpConnection = connectionAndMeta.httpConnection;
@ -103,6 +105,12 @@ public class AutoupdateUtil {
}
}
public static void setAppIcon(JFrame frame) {
ImageIcon icon = loadIcon(APPICON);
if (icon != null)
frame.setIconImage(icon.getImage());
}
public static class ConnectionAndMeta {
private String zipFileName;
private HttpURLConnection httpConnection;

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -4,6 +4,7 @@
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />

View File

@ -98,7 +98,7 @@ public class AuthTokenPanel {
try {
String data = (String) clipboard.getData(DataFlavor.stringFlavor);
paste.setEnabled(AutoTokenUtil.isToken(data));
} catch (IOException | UnsupportedFlavorException ex) {
} catch (IOException | IllegalStateException | UnsupportedFlavorException ex) {
// ignoring this exception
}
}

View File

@ -1,6 +1,7 @@
package com.rusefi;
import com.rusefi.autodetect.PortDetector;
import com.rusefi.autoupdate.AutoupdateUtil;
import com.rusefi.config.generated.Fields;
import com.rusefi.core.MessagesCentral;
import com.rusefi.core.Sensor;
@ -158,7 +159,7 @@ public class ConsoleUI {
}
});
StartupFrame.setAppIcon(mainFrame.getFrame().getFrame());
AutoupdateUtil.setAppIcon(mainFrame.getFrame().getFrame());
mainFrame.getFrame().showFrame(tabbedPane.tabbedPane);
}

View File

@ -36,8 +36,6 @@ import static javax.swing.JOptionPane.YES_NO_OPTION;
* @see FirmwareFlasher
*/
public class StartupFrame {
// todo: figure out a better way to work with absolute path
private static final String APPICON = "/appicon.png";
private static final String LOGO = "/com/rusefi/logo.gif";
public static final String LINK_TEXT = "rusEFI (c) 2012-2020";
private static final String URI = "http://rusefi.com/?java_console";
@ -80,16 +78,10 @@ public class StartupFrame {
}
}
});
setAppIcon(frame);
AutoupdateUtil.setAppIcon(frame);
SerialPortScanner.INSTANCE.startTimer();
}
public static void setAppIcon(JFrame frame) {
ImageIcon icon = AutoupdateUtil.loadIcon(APPICON);
if (icon != null)
frame.setIconImage(icon.getImage());
}
public void chooseSerialPort() {
realHardwarePanel.setBorder(new TitledBorder(BorderFactory.createLineBorder(Color.darkGray), "Real stm32"));
miscPanel.setBorder(new TitledBorder(BorderFactory.createLineBorder(Color.darkGray), "Miscellaneous"));

View File

@ -32,6 +32,7 @@
<copy todir="build/classes">
<fileset dir="../ts_plugin_launcher/resources" includes="**/*.png"/>
<fileset dir="${console_path}/shared_ui/resources" includes="**/*.png"/>
</copy>
<tstamp>

View File

@ -1,12 +1,20 @@
package com.rusefi.ts_plugin;
import com.efiAnalytics.plugin.ecu.ControllerAccess;
import com.rusefi.ui.util.FrameHelper;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* @see PluginLauncherSandbox
*/
public class PluginBodySandbox {
public static void main(String[] args) {
new FrameHelper().showFrame(new PluginEntry().getContent());
new FrameHelper().showFrame(new PluginEntry(() -> {
ControllerAccess controllerAccess = mock(ControllerAccess.class);
when(controllerAccess.getEcuConfigurationNames()).thenReturn(new String[]{"dev"});
return controllerAccess;
}).getContent());
}
}

View File

@ -1,10 +1,6 @@
package com.rusefi.ts_plugin;
import com.efiAnalytics.plugin.ecu.ControllerAccess;
import com.efiAnalytics.plugin.ecu.ControllerException;
import com.efiAnalytics.plugin.ecu.ControllerParameter;
import com.efiAnalytics.plugin.ecu.servers.ControllerParameterServer;
import com.rusefi.TsTuneReader;
import com.rusefi.autoupdate.AutoupdateUtil;
import com.rusefi.tools.online.Online;
import com.rusefi.tune.xml.Constant;
@ -16,12 +12,12 @@ import org.jetbrains.annotations.NotNull;
import org.putgemin.VerticalFlowLayout;
import javax.swing.*;
import javax.xml.bind.JAXBException;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.net.URL;
import java.util.Map;
import java.util.TreeMap;
import java.util.function.Supplier;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
@ -37,20 +33,42 @@ public class PluginEntry implements TsPluginBody {
private static final ImageIcon LOGO = AutoupdateUtil.loadIcon("/rusefi_online_color_300.png");
private final JButton upload = new JButton("Upload Current Tune");
private static final JLabel warning = new JLabel("Please open project");
private static final JLabel projectWarning = new JLabel("Please open project");
private static final JLabel tuneWarning = new JLabel();
private final Supplier<ControllerAccess> controllerAccessSupplier;
private String currentConfiguration;
private boolean tuneIsOk;
private boolean projectIsOk;
/**
* the real constructor - this one is invoked via reflection
*/
public PluginEntry() {
this(ControllerAccess::getInstance);
}
public PluginEntry(Supplier<ControllerAccess> controllerAccessSupplier) {
this.controllerAccessSupplier = controllerAccessSupplier;
upload.setBackground(new Color(0x90EE90));
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
boolean isProjectActive = getConfigurationName() != null;
String configurationName = getConfigurationName();
if ((currentConfiguration == null && configurationName != null)
|| !currentConfiguration.equals(configurationName)) {
handleConfigurationChange(configurationName);
}
boolean isProjectActive = configurationName != null;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
warning.setVisible(!isProjectActive);
upload.setEnabled(isProjectActive);
projectWarning.setVisible(!isProjectActive);
projectIsOk = isProjectActive;
updateUploadEnabled();
}
});
@ -76,7 +94,7 @@ public class PluginEntry implements TsPluginBody {
return;
}
Msq tune = writeCurrentTune(ControllerAccess.getInstance(), configurationName);
Msq tune = TuneUploder.writeCurrentTune(ControllerAccess.getInstance(), configurationName);
Online.uploadTune(tune, tokenPanel, content);
}
});
@ -84,13 +102,51 @@ public class PluginEntry implements TsPluginBody {
content.add(new JLabel(getAttribute(BUILT_TIMESTAMP)));
// content.add(new JLabel("Active project: " + getConfigurationName()));
content.add(warning);
content.add(projectWarning);
content.add(tuneWarning);
content.add(upload);
content.add(new JLabel(LOGO));
content.add(tokenPanel.getContent());
content.add(new URLLabel(REO));
}
private void handleConfigurationChange(String configurationName) {
Map<String, Constant> fileSystemValues = TuneUploder.getFileSystemValues(configurationName);
Constant engineMake = fileSystemValues.get("enginemake");
Constant engineCode = fileSystemValues.get("enginecode");
Constant vehicleName = fileSystemValues.get("VEHICLENAME");
String warning = "";
if (isEmpty(engineMake.getValue())) {
warning += " engine make";
}
if (isEmpty(engineCode.getValue())) {
warning += " engine code";
}
if (isEmpty(vehicleName.getValue())) {
warning += " vehicle name";
}
if (warning.isEmpty()) {
tuneWarning.setVisible(false);
tuneIsOk = true;
updateUploadEnabled();
} else {
tuneWarning.setText("<html>Please set " + warning + " on Base Settings tab<br>and reopen Project");
tuneWarning.setForeground(Color.red);
tuneWarning.setVisible(true);
tuneIsOk = false;
updateUploadEnabled();
}
currentConfiguration = configurationName;
}
private void updateUploadEnabled() {
upload.setEnabled(tuneIsOk && projectIsOk);
}
private boolean isEmpty(String engineCode) {
return engineCode == null || engineCode.trim().length() == 0;
}
@Override
public JComponent getContent() {
return content;
@ -106,23 +162,8 @@ public class PluginEntry implements TsPluginBody {
}
}
private static String getArrayValue(double[][] arrayValues) {
StringBuilder sb = new StringBuilder();
for (int rowIndex = 0; rowIndex < arrayValues.length; rowIndex++) {
double[] array = arrayValues[rowIndex];
sb.append("\n\t");
for (int colIndex = 0; colIndex < array.length; colIndex++) {
double value = array[colIndex];
sb.append(' ');
sb.append(value);
}
}
sb.append("\n");
return sb.toString();
}
public static String getConfigurationName() {
ControllerAccess controllerAccess = ControllerAccess.getInstance();
private String getConfigurationName() {
ControllerAccess controllerAccess = controllerAccessSupplier.get();
if (controllerAccess == null) {
System.out.println("No ControllerAccess");
return null;
@ -133,65 +174,6 @@ public class PluginEntry implements TsPluginBody {
return configurationNames[0];
}
private static String toString(double scalarValue, int decimalPlaces) {
// todo: start using decimalPlaces parameter!
return Double.toString(scalarValue);
}
private static Msq writeCurrentTune(ControllerAccess controllerAccess, String configurationName) {
Msq msq = new Msq();
ControllerParameterServer controllerParameterServer = controllerAccess.getControllerParameterServer();
Msq tsTune = TsTuneReader.readTsTune(configurationName);
Map<String, Constant> byName = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
for (Constant c : tsTune.findPage().constant) {
byName.put(c.getName(), c);
}
try {
String[] parameterNames = controllerParameterServer.getParameterNames(configurationName);
for (String parameterName : parameterNames) {
ControllerParameter cp = controllerParameterServer.getControllerParameter(configurationName, parameterName);
String type = cp.getParamClass();
String value;
if (ControllerParameter.PARAM_CLASS_BITS.equals(type)) {
value = cp.getStringValue();
System.out.println("TsPlugin bits " + parameterName + ": " + value);
} else if (ControllerParameter.PARAM_CLASS_SCALAR.equals(type)) {
value = toString(cp.getScalarValue(), cp.getDecimalPlaces());
System.out.println("TsPlugin scalar " + parameterName + ": " + cp.getScalarValue() + "/" + cp.getStringValue());
} else if (ControllerParameter.PARAM_CLASS_ARRAY.equals(type)) {
value = getArrayValue(cp.getArrayValues());
} else if ("string".equals(type)) {
//value = cp.getStringValue();
// WOW hack
// TS does not provide values for string parameters?! so we read the file directly
Constant constant = byName.get(parameterName);
if (constant == null) {
System.out.println("Not found in TS tune " + parameterName);
value = null;
} else {
value = constant.getValue();
System.out.println("TsPlugin name=" + parameterName + " string=" + cp.getStringValue() + "/h=" + value);
}
} else {
System.out.println("TsPlugin name=" + parameterName + " unexpected type " + type + "/" + cp.getStringValue());
value = cp.getStringValue();
}
msq.findPage().constant.add(new Constant(parameterName, cp.getUnits(), value));
}
String fileName = Msq.outputXmlFileName;
msq.writeXmlFile(fileName);
return msq;
} catch (JAXBException | IOException | ControllerException e) {
System.out.println("Error writing XML: " + e);
return null;
}
}
/**
* this method is invoked by refection
*

View File

@ -0,0 +1,104 @@
package com.rusefi.ts_plugin;
import com.efiAnalytics.plugin.ecu.ControllerAccess;
import com.efiAnalytics.plugin.ecu.ControllerException;
import com.efiAnalytics.plugin.ecu.ControllerParameter;
import com.efiAnalytics.plugin.ecu.servers.ControllerParameterServer;
import com.rusefi.TsTuneReader;
import com.rusefi.tune.xml.Constant;
import com.rusefi.tune.xml.Msq;
import org.jetbrains.annotations.NotNull;
import javax.xml.bind.JAXBException;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;
public class TuneUploder {
static Msq writeCurrentTune(ControllerAccess controllerAccess, String configurationName) {
Msq msq = new Msq();
ControllerParameterServer controllerParameterServer = controllerAccess.getControllerParameterServer();
Map<String, Constant> fileSystemValues = getFileSystemValues(configurationName);
try {
String[] parameterNames = controllerParameterServer.getParameterNames(configurationName);
for (String parameterName : parameterNames) {
handleParameter(configurationName, msq, controllerParameterServer, fileSystemValues, parameterName);
}
String fileName = Msq.outputXmlFileName;
msq.writeXmlFile(fileName);
return msq;
} catch (JAXBException | IOException | ControllerException e) {
System.out.println("Error writing XML: " + e);
return null;
}
}
@NotNull
static Map<String, Constant> getFileSystemValues(String configurationName) {
if (configurationName == null)
return Collections.emptyMap();
Msq tsTune = TsTuneReader.readTsTune(configurationName);
Map<String, Constant> byName = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
for (Constant c : tsTune.findPage().constant) {
byName.put(c.getName(), c);
}
return byName;
}
private static void handleParameter(String configurationName, Msq msq, ControllerParameterServer controllerParameterServer, Map<String, Constant> byName, String parameterName) throws ControllerException {
ControllerParameter cp = controllerParameterServer.getControllerParameter(configurationName, parameterName);
String type = cp.getParamClass();
String value;
if (ControllerParameter.PARAM_CLASS_BITS.equals(type)) {
value = cp.getStringValue();
System.out.println("TsPlugin bits " + parameterName + ": " + value);
} else if (ControllerParameter.PARAM_CLASS_SCALAR.equals(type)) {
value = toString(cp.getScalarValue(), cp.getDecimalPlaces());
System.out.println("TsPlugin scalar " + parameterName + ": " + cp.getScalarValue() + "/" + cp.getStringValue());
} else if (ControllerParameter.PARAM_CLASS_ARRAY.equals(type)) {
value = getArrayValue(cp.getArrayValues());
} else if ("string".equals(type)) {
//value = cp.getStringValue();
// WOW hack
// TS does not provide values for string parameters?! so we read the file directly
Constant constant = byName.get(parameterName);
if (constant == null) {
System.out.println("Not found in TS tune " + parameterName);
value = null;
} else {
value = constant.getValue();
System.out.println("TsPlugin name=" + parameterName + " string=" + cp.getStringValue() + "/h=" + value);
}
} else {
System.out.println("TsPlugin name=" + parameterName + " unexpected type " + type + "/" + cp.getStringValue());
value = cp.getStringValue();
}
msq.findPage().constant.add(new Constant(parameterName, cp.getUnits(), value));
}
private static String getArrayValue(double[][] arrayValues) {
StringBuilder sb = new StringBuilder();
for (int rowIndex = 0; rowIndex < arrayValues.length; rowIndex++) {
double[] array = arrayValues[rowIndex];
sb.append("\n\t");
for (int colIndex = 0; colIndex < array.length; colIndex++) {
double value = array[colIndex];
sb.append(' ');
sb.append(value);
}
}
sb.append("\n");
return sb.toString();
}
private static String toString(double scalarValue, int decimalPlaces) {
// todo: start using decimalPlaces parameter!
return Double.toString(scalarValue);
}
}

View File

@ -11,5 +11,6 @@
<orderEntry type="module" module-name="shared_ui" />
<orderEntry type="library" name="TunerStudioPluginAPI" level="project" />
<orderEntry type="module" module-name="ts_plugin_launcher" />
<orderEntry type="library" name="org.mockito:mockito-all:1.10.19" level="project" />
</component>
</module>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="org.mockito:mockito-all:1.10.19" type="repository">
<properties maven-id="org.mockito:mockito-all:1.10.19" />
<CLASSES>
<root url="jar://$USER_HOME$/.m2/repository/org/mockito/mockito-all/1.10.19/mockito-all-1.10.19.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -5,6 +5,7 @@ import com.rusefi.ui.storage.PersistentConfiguration;
import org.putgemin.VerticalFlowLayout;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
@ -61,6 +62,7 @@ public class Updater {
JButton download = new JButton("Update plugin");
if (version != null) {
JButton run = new JButton("Run Version " + version);
run.setBackground(new Color(0x90EE90));
run.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {