2020-07-18 20:17:36 -07:00
|
|
|
package com.rusefi.ts_plugin;
|
|
|
|
|
|
|
|
import com.efiAnalytics.plugin.ecu.ControllerAccess;
|
|
|
|
import com.efiAnalytics.plugin.ecu.ControllerException;
|
|
|
|
import com.efiAnalytics.plugin.ecu.ControllerParameterChangeListener;
|
|
|
|
import com.opensr5.ini.IniFileModel;
|
|
|
|
import com.opensr5.ini.field.IniField;
|
2020-10-08 20:23:45 -07:00
|
|
|
import com.rusefi.NamedThreadFactory;
|
2020-07-18 20:17:36 -07:00
|
|
|
import com.rusefi.TsTuneReader;
|
|
|
|
import com.rusefi.config.generated.Fields;
|
|
|
|
import com.rusefi.tools.online.Online;
|
|
|
|
import com.rusefi.tools.online.UploadResult;
|
|
|
|
import com.rusefi.ts_plugin.util.ManifestHelper;
|
|
|
|
import com.rusefi.tune.xml.Msq;
|
|
|
|
import com.rusefi.ui.AuthTokenPanel;
|
|
|
|
import com.rusefi.ui.util.URLLabel;
|
|
|
|
import org.apache.http.concurrent.FutureCallback;
|
|
|
|
import org.putgemin.VerticalFlowLayout;
|
|
|
|
|
|
|
|
import javax.swing.*;
|
|
|
|
import java.awt.*;
|
|
|
|
import java.awt.event.ActionEvent;
|
|
|
|
import java.util.Date;
|
|
|
|
import java.util.Map;
|
2020-10-08 20:23:45 -07:00
|
|
|
import java.util.concurrent.ThreadFactory;
|
2020-07-18 20:17:36 -07:00
|
|
|
import java.util.function.Supplier;
|
|
|
|
|
2020-08-12 17:37:37 -07:00
|
|
|
/**
|
2020-08-29 21:21:34 -07:00
|
|
|
* @see PluginBodySandbox
|
2020-08-12 17:37:37 -07:00
|
|
|
*/
|
|
|
|
public class TuneUploadTab {
|
2020-07-18 20:17:36 -07:00
|
|
|
private final JComponent content = new JPanel(new VerticalFlowLayout());
|
|
|
|
// 2 seconds aggregation by default
|
|
|
|
private static final int AUTO_UPDATE_AGGREGATION = Integer.parseInt(System.getProperty("autoupload.aggregation", "2000"));
|
2020-10-08 20:23:45 -07:00
|
|
|
private static final ThreadFactory THREAD_FACTORY = new NamedThreadFactory("Tune Upload", true);
|
2020-07-18 20:17:36 -07:00
|
|
|
|
|
|
|
private static final String REO_URL = "https://rusefi.com/online/";
|
|
|
|
private final AuthTokenPanel tokenPanel = new AuthTokenPanel();
|
|
|
|
|
|
|
|
private final Supplier<ControllerAccess> controllerAccessSupplier;
|
|
|
|
|
|
|
|
private final UploadView uploadView = new UploadView();
|
|
|
|
|
|
|
|
private final JButton upload = new JButton("Upload Current Tune");
|
|
|
|
|
2020-08-12 12:54:38 -07:00
|
|
|
private String projectName;
|
2020-07-18 20:17:36 -07:00
|
|
|
|
2020-08-12 12:54:38 -07:00
|
|
|
private final UploaderStatus uploaderStatus = new UploaderStatus();
|
2020-07-18 20:17:36 -07:00
|
|
|
|
|
|
|
private final Timer timer = new Timer(AUTO_UPDATE_AGGREGATION, new AbstractAction() {
|
|
|
|
@Override
|
|
|
|
public void actionPerformed(ActionEvent e) {
|
|
|
|
// System.out.println("Timer! " + System.currentTimeMillis() + " " + timer + " " + e);
|
|
|
|
if (UploadView.isAutoUpload()) {
|
|
|
|
System.out.println(new Date() + ": enqueue tune");
|
2020-08-12 12:54:38 -07:00
|
|
|
UploadQueue.enqueue(controllerAccessSupplier.get(), projectName);
|
2020-07-18 20:17:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
private final ControllerParameterChangeListener listener;
|
|
|
|
|
2020-08-12 17:37:37 -07:00
|
|
|
public TuneUploadTab(Supplier<ControllerAccess> controllerAccessSupplier) {
|
2020-07-18 20:17:36 -07:00
|
|
|
this.controllerAccessSupplier = controllerAccessSupplier;
|
|
|
|
|
|
|
|
timer.stop();
|
|
|
|
timer.setRepeats(false);
|
|
|
|
UploadQueue.start();
|
|
|
|
listener = parameterName -> {
|
|
|
|
// System.out.println("Parameter value changed " + parameterName);
|
|
|
|
timer.restart();
|
|
|
|
};
|
|
|
|
upload.setBackground(new Color(0x90EE90));
|
|
|
|
|
2020-10-08 20:23:45 -07:00
|
|
|
Thread t = THREAD_FACTORY.newThread(new Runnable() {
|
2020-07-18 20:17:36 -07:00
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
while (true) {
|
|
|
|
String configurationName = getConfigurationName();
|
2020-08-12 12:54:38 -07:00
|
|
|
if ((projectName == null && configurationName != null)
|
|
|
|
|| !projectName.equals(configurationName)) {
|
2020-07-18 20:17:36 -07:00
|
|
|
handleConfigurationChange(configurationName, controllerAccessSupplier.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
boolean isProjectActive = configurationName != null;
|
|
|
|
uploaderStatus.updateProjectStatus(configurationName, isProjectActive);
|
|
|
|
|
|
|
|
SwingUtilities.invokeLater(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
|
|
|
|
updateUploadEnabled();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
try {
|
|
|
|
Thread.sleep(1000);
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-08-29 21:21:34 -07:00
|
|
|
});
|
|
|
|
t.start();
|
2020-07-18 20:17:36 -07:00
|
|
|
|
|
|
|
upload.addActionListener(new AbstractAction() {
|
|
|
|
@Override
|
|
|
|
public void actionPerformed(ActionEvent e) {
|
|
|
|
if (!tokenPanel.hasToken()) {
|
|
|
|
tokenPanel.showError(content);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
String configurationName = getConfigurationName();
|
|
|
|
if (configurationName == null) {
|
|
|
|
JOptionPane.showMessageDialog(content, "No project opened");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
uploadView.uploadState.setVisible(true);
|
|
|
|
uploadView.uploadState.setText("Uploading...");
|
|
|
|
|
|
|
|
Msq tune = TuneUploder.writeCurrentTune(controllerAccessSupplier.get(), configurationName);
|
2024-02-16 13:19:15 -08:00
|
|
|
Online.uploadTune(tune, content, new FutureCallback<UploadResult>() {
|
2020-07-18 20:17:36 -07:00
|
|
|
@Override
|
|
|
|
public void completed(UploadResult array) {
|
|
|
|
SwingUtilities.invokeLater(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
2020-08-12 17:37:37 -07:00
|
|
|
UploadView.setResult(array, uploadView.uploadState);
|
2020-07-18 20:17:36 -07:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void failed(Exception e) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void cancelled() {
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
content.add(new JLabel("Version " + ManifestHelper.getBuildTimestamp()));
|
|
|
|
// content.add(new JLabel("Active project: " + getConfigurationName()));
|
|
|
|
|
|
|
|
|
|
|
|
content.add(uploadView.getContent());
|
|
|
|
content.add(upload);
|
|
|
|
|
2020-07-26 21:48:04 -07:00
|
|
|
content.add(new JLabel(PluginEntry.LOGO));
|
2020-07-18 20:17:36 -07:00
|
|
|
content.add(tokenPanel.getContent());
|
|
|
|
content.add(new URLLabel(REO_URL));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This method is invoked every time we defect a switch between projects
|
|
|
|
*/
|
2020-08-12 12:54:38 -07:00
|
|
|
private void handleConfigurationChange(String projectName, ControllerAccess controllerAccess) {
|
|
|
|
uploaderStatus.readTuneState(projectName);
|
2020-07-18 20:17:36 -07:00
|
|
|
|
2020-08-12 12:54:38 -07:00
|
|
|
if (projectName != null) {
|
|
|
|
subscribeToUpdates(projectName, controllerAccess);
|
2020-07-18 20:17:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
updateUploadEnabled();
|
|
|
|
|
2020-08-12 12:54:38 -07:00
|
|
|
this.projectName = projectName;
|
2020-07-18 20:17:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
private void updateUploadEnabled() {
|
|
|
|
uploadView.update(uploaderStatus);
|
|
|
|
|
|
|
|
upload.setEnabled(uploaderStatus.isTuneOk() && uploaderStatus.isProjectIsOk());
|
|
|
|
}
|
|
|
|
|
|
|
|
private void subscribeToUpdates(String configurationName, ControllerAccess controllerAccess) {
|
|
|
|
IniFileModel model = new IniFileModel().readIniFile(TsTuneReader.getProjectModeFileName(configurationName));
|
|
|
|
Map<String, IniField> allIniFields = model.allIniFields;
|
|
|
|
if (model.allIniFields == null)
|
|
|
|
return;
|
|
|
|
for (Map.Entry<String, IniField> field : allIniFields.entrySet()) {
|
|
|
|
boolean isOnlineTuneField = field.getValue().getOffset() >= Fields.engine_configuration_s_size;
|
|
|
|
if (!isOnlineTuneField) {
|
|
|
|
try {
|
|
|
|
controllerAccess.getControllerParameterServer().subscribe(configurationName, field.getKey(), listener);
|
|
|
|
} catch (ControllerException e) {
|
|
|
|
throw new IllegalStateException(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private String getConfigurationName() {
|
|
|
|
ControllerAccess controllerAccess = controllerAccessSupplier.get();
|
|
|
|
if (controllerAccess == null) {
|
|
|
|
System.out.println("No ControllerAccess");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
String[] configurationNames = controllerAccess.getEcuConfigurationNames();
|
|
|
|
if (configurationNames.length == 0)
|
|
|
|
return null;
|
|
|
|
return configurationNames[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
public JComponent getContent() {
|
|
|
|
return content;
|
|
|
|
}
|
|
|
|
}
|