diff --git a/java_console/inifile/src/com/rusefi/config/Field.java b/java_console/inifile/src/com/rusefi/config/Field.java
index 71aced1d0f..881d5d229a 100644
--- a/java_console/inifile/src/com/rusefi/config/Field.java
+++ b/java_console/inifile/src/com/rusefi/config/Field.java
@@ -146,13 +146,13 @@ public class Field {
*/
@NotNull
@Deprecated
- public Number getValue(ConfigurationImage ci) {
+ public Double getValue(ConfigurationImage ci) {
return getValue(ci, 1);
}
// todo: rename to getNumberValue?
@NotNull
- public Number getValue(ConfigurationImage ci, double multiplier) {
+ public Double getValue(ConfigurationImage ci, double multiplier) {
Objects.requireNonNull(ci);
Number value;
ByteBuffer wrapped = ci.getByteBuffer(getOffset(), type.getStorageSize());
diff --git a/java_console/models/src/com/rusefi/core/Sensor.java b/java_console/models/src/com/rusefi/core/Sensor.java
index d6183ad306..926e91f42a 100644
--- a/java_console/models/src/com/rusefi/core/Sensor.java
+++ b/java_console/models/src/com/rusefi/core/Sensor.java
@@ -239,6 +239,10 @@ public enum Sensor {
public void writeToLog(DataOutputStream dos, double value) throws IOException {
switch (type) {
+ case INT8:
+ case UINT8:
+ dos.write((int) value);
+ return;
case FLOAT:
dos.writeFloat((float) value);
return;
diff --git a/java_console/ui/src/main/java/com/rusefi/ConsoleUI.java b/java_console/ui/src/main/java/com/rusefi/ConsoleUI.java
index bb320edc8d..43cf3ce46e 100644
--- a/java_console/ui/src/main/java/com/rusefi/ConsoleUI.java
+++ b/java_console/ui/src/main/java/com/rusefi/ConsoleUI.java
@@ -10,6 +10,7 @@ import com.rusefi.io.LinkManager;
import com.rusefi.io.serial.BaudRateHolder;
import com.rusefi.maintenance.FirmwareFlasher;
import com.rusefi.maintenance.VersionChecker;
+import com.rusefi.sensor_logs.SensorLogger;
import com.rusefi.ui.*;
import com.rusefi.ui.console.MainFrame;
import com.rusefi.ui.console.TabbedPanel;
@@ -135,6 +136,7 @@ public class ConsoleUI {
tabbedPane.addTab("rusEFI Online", new OnlineTab().getContent());
+ SensorLogger.init();
if (!LinkManager.isLogViewerMode(port)) {
int selectedIndex = getConfig().getRoot().getIntProperty(TAB_INDEX, DEFAULT_TAB_INDEX);
diff --git a/java_console/ui/src/main/java/com/rusefi/sensor_logs/BinarySensorLog.java b/java_console/ui/src/main/java/com/rusefi/sensor_logs/BinarySensorLog.java
index 30c45f6fdb..7ff7821272 100644
--- a/java_console/ui/src/main/java/com/rusefi/sensor_logs/BinarySensorLog.java
+++ b/java_console/ui/src/main/java/com/rusefi/sensor_logs/BinarySensorLog.java
@@ -1,34 +1,46 @@
package com.rusefi.sensor_logs;
import com.rusefi.FileLog;
+import com.rusefi.config.FieldType;
import com.rusefi.config.generated.Fields;
import com.rusefi.core.Sensor;
import com.rusefi.core.SensorCentral;
import com.rusefi.rusEFIVersion;
import java.io.*;
-import java.util.Date;
+import java.util.*;
import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+/**
+ * MLV .mlq binary log file
+ *
+ * Andrey Belomutskiy, (c) 2013-2020
+ */
public class BinarySensorLog extends SensorLog {
private final Function valueProvider;
- private final Sensor[] sensors;
+ private final Collection sensors;
private DataOutputStream stream;
private int counter;
public BinarySensorLog() {
- this(new Function() {
- @Override
- public Double apply(Sensor sensor) {
- return SensorCentral.getInstance().getValue(sensor);
- }
- }, SensorLogger.SENSORS);
+ this(sensor -> SensorCentral.getInstance().getValue(sensor), SensorLogger.SENSORS);
}
public BinarySensorLog(Function valueProvider, Sensor... sensors) {
this.valueProvider = valueProvider;
- this.sensors = sensors;
+ this.sensors = filterOutSensorsWithoutType(Objects.requireNonNull(sensors, "sensors"));
+ }
+
+ private Collection filterOutSensorsWithoutType(Sensor[] sensors) {
+ return Arrays.stream(sensors).filter(new Predicate() {
+ @Override
+ public boolean test(Sensor sensor) {
+ return sensor.getType() != null;
+ }
+ }).collect(Collectors.toCollection(ArrayList::new));
}
@Override
@@ -44,11 +56,11 @@ public class BinarySensorLog extends SensorLog {
try {
stream = new DataOutputStream(new FileOutputStream(fileName));
- } catch (IOException e) {
+ writeHeader();
+ } catch (Throwable e) {
e.printStackTrace();
stream = null;
}
- writeHeader();
}
if (stream != null) {
@@ -73,69 +85,76 @@ public class BinarySensorLog extends SensorLog {
stream.write(byteArray);
stream.write(checkSum);
+ if (counter % 20 == 0) {
+ // for not flush on each block of data but still flush
+ stream.flush();
+ }
+
} catch (IOException e) {
e.printStackTrace();
}
}
}
- private void writeHeader() {
- try {
+ private void writeHeader() throws IOException {
+ String headerText = "\"rusEFI " + rusEFIVersion.CONSOLE_VERSION + "\"\n" +
+ "\"Capture Date: " + new Date() + "\"\n";
- String headerText = "\"rusEFI " + rusEFIVersion.CONSOLE_VERSION + "\"\n" +
- "\"Capture Date: " + new Date() + "\"\n";
-
- for (char c : "MLVLG\0".toCharArray()) {
- stream.write(c);
- }
-
- int fieldsDataSize = 0;
- for (Sensor sensor : sensors) {
- fieldsDataSize += sensor.getType().getStorageSize();
- }
-
- // 0006h Format version = 01
- stream.write(0);
- stream.write(1);
- // 0008h Timestamp
- stream.writeInt(0);
- // 000ch
- int offsetToText = Fields.MLQ_HEADER_SIZE + Fields.MLQ_FIELD_HEADER_SIZE * sensors.length;
- stream.writeShort(offsetToText);
- stream.writeShort(0); // reserved?
- // 0010h = offset_to_data
- stream.writeShort(offsetToText + headerText.length());
- // 0012h
- stream.writeShort(fieldsDataSize);
- // 0014h number of fields
- stream.writeShort(sensors.length);
-
- for (Sensor sensor : sensors) {
- String name = SensorLogger.getSensorName(sensor, 0);
- String unit = sensor.getUnits();
-
- // 0000h
- stream.write(getSensorTypeValue(sensor));
- // 0001h
- writeLine(stream, name, 34);
- // 0023h
- writeLine(stream, unit, 11);
- // 002Eh scale
- stream.writeFloat(1); // todo: multiplier?
- // 0032h zeroes
- stream.writeInt(0);
- // 0036h precision
- stream.write(2);
- }
- writeLine(stream, headerText, 0);
-
- } catch (IOException e) {
- e.printStackTrace();
+ for (char c : "MLVLG\0".toCharArray()) {
+ stream.write(c);
}
+
+ int fieldsDataSize = 0;
+ for (Sensor sensor : sensors) {
+ FieldType type = sensor.getType();
+ if (type == null)
+ throw new NullPointerException("No type for " + sensor);
+ fieldsDataSize += type.getStorageSize();
+ }
+
+ // 0006h Format version = 01
+ stream.write(0);
+ stream.write(1);
+ // 0008h Timestamp
+ stream.writeInt(0);
+ // 000ch
+ int offsetToText = Fields.MLQ_HEADER_SIZE + Fields.MLQ_FIELD_HEADER_SIZE * sensors.size();
+ stream.writeShort(offsetToText);
+ stream.writeShort(0); // reserved?
+ // 0010h = offset_to_data
+ stream.writeShort(offsetToText + headerText.length());
+ // 0012h
+ stream.writeShort(fieldsDataSize);
+ // 0014h number of fields
+ stream.writeShort(sensors.size());
+
+ for (Sensor sensor : sensors) {
+ String name = SensorLogger.getSensorName(sensor, 0);
+ String unit = sensor.getUnits();
+
+ // 0000h
+ stream.write(getSensorTypeValue(sensor));
+ // 0001h
+ writeLine(stream, name, 34);
+ // 0023h
+ writeLine(stream, unit, 11);
+ // 002Eh scale
+ stream.writeFloat(1); // todo: multiplier?
+ // 0032h zeroes
+ stream.writeInt(0);
+ // 0036h precision
+ stream.write(2);
+ }
+ writeLine(stream, headerText, 0);
+
}
private int getSensorTypeValue(Sensor sensor) {
switch (sensor.getType()) {
+ case UINT8:
+ return 0;
+ case INT8:
+ return 1;
case UINT16:
return 2;
case INT16:
@@ -149,8 +168,10 @@ public class BinarySensorLog extends SensorLog {
}
}
+ @Override
public void close() {
close(stream);
+ stream = null;
}
public static void close(Closeable closeable) {
diff --git a/java_console/ui/src/main/java/com/rusefi/sensor_logs/BinarySensorLogSandbox.java b/java_console/ui/src/main/java/com/rusefi/sensor_logs/BinarySensorLogSandbox.java
index a27b3633f4..5510c28e65 100644
--- a/java_console/ui/src/main/java/com/rusefi/sensor_logs/BinarySensorLogSandbox.java
+++ b/java_console/ui/src/main/java/com/rusefi/sensor_logs/BinarySensorLogSandbox.java
@@ -20,11 +20,13 @@ public class BinarySensorLogSandbox {
BinarySensorLog l = new BinarySensorLog(valueProvider,
Sensor.TIME_SECONDS,
Sensor.RPM,
+ Sensor.VSS,
Sensor.FIRMWARE_VERSION,
Sensor.CLT);
values.put(Sensor.TIME_SECONDS, 1.0);
values.put(Sensor.RPM, 0.0);
+ values.put(Sensor.VSS, 60.0);
values.put(Sensor.FIRMWARE_VERSION, 20200101.0);
values.put(Sensor.CLT, 29.0);
@@ -39,6 +41,5 @@ public class BinarySensorLogSandbox {
}
l.close();
-
}
}
diff --git a/java_console/ui/src/main/java/com/rusefi/sensor_logs/PlainTextSensorLog.java b/java_console/ui/src/main/java/com/rusefi/sensor_logs/PlainTextSensorLog.java
index 7c287bc1d2..090d6596fe 100644
--- a/java_console/ui/src/main/java/com/rusefi/sensor_logs/PlainTextSensorLog.java
+++ b/java_console/ui/src/main/java/com/rusefi/sensor_logs/PlainTextSensorLog.java
@@ -14,13 +14,17 @@ import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
+/**
+ * Legacy human readable CSV log file
+ *
+ * Andrey Belomutskiy, (c) 2013-2020
+ */
public class PlainTextSensorLog extends SensorLog {
private Writer logFile;
private long fileStartTime;
-
- public void startIfNeeded() {
+ private void startIfNeeded() {
if (logFile == null) {
/*
* we only start file header once we have first bunch of data
@@ -75,7 +79,6 @@ public class PlainTextSensorLog extends SensorLog {
return msSinceFileStart / 1000.0;
}
-
@Override
void writeSensorLogLine() {
startIfNeeded();
@@ -94,5 +97,11 @@ public class PlainTextSensorLog extends SensorLog {
logFile = null;
}
}
+
+ @Override
+ public void close() {
+ BinarySensorLog.close(logFile);
+ logFile = null;
+ }
}
diff --git a/java_console/ui/src/main/java/com/rusefi/sensor_logs/SensorLog.java b/java_console/ui/src/main/java/com/rusefi/sensor_logs/SensorLog.java
index 836d96b565..9650cdaff1 100644
--- a/java_console/ui/src/main/java/com/rusefi/sensor_logs/SensorLog.java
+++ b/java_console/ui/src/main/java/com/rusefi/sensor_logs/SensorLog.java
@@ -4,4 +4,6 @@ public abstract class SensorLog {
public abstract double getSecondsSinceFileStart();
abstract void writeSensorLogLine();
+
+ public abstract void close();
}
diff --git a/java_console/ui/src/main/java/com/rusefi/sensor_logs/SensorLogger.java b/java_console/ui/src/main/java/com/rusefi/sensor_logs/SensorLogger.java
index a1eadb6af5..cb9d72c5eb 100644
--- a/java_console/ui/src/main/java/com/rusefi/sensor_logs/SensorLogger.java
+++ b/java_console/ui/src/main/java/com/rusefi/sensor_logs/SensorLogger.java
@@ -5,13 +5,14 @@ import com.rusefi.core.SensorCentral;
import com.rusefi.io.ConnectionStatusLogic;
import com.rusefi.io.ConnectionStatusValue;
+import java.util.Arrays;
+import java.util.List;
+
/**
* Andrey Belomutskiy, (c) 2013-2020
* 4/15/2016.
*/
public class SensorLogger {
- private static SensorLog sensorLog = new PlainTextSensorLog();
-
protected static Sensor[] SENSORS = {Sensor.RPM,
Sensor.INT_TEMP,
@@ -79,6 +80,10 @@ public class SensorLogger {
Sensor.tuneCrc16,
};
+ private static List sensorLogs = Arrays.asList(new PlainTextSensorLog(), new BinarySensorLog());
+
+ private static boolean isInitialized;
+
private SensorLogger() {
}
@@ -86,19 +91,24 @@ public class SensorLogger {
init();
}
- private static void init() {
+ public synchronized static void init() {
+ if (isInitialized) {
+ return;
+ }
+ isInitialized = true;
SensorCentral.getInstance().addListener(Sensor.TIME_SECONDS, new SensorCentral.SensorListener() {
@Override
public void onSensorUpdate(double value) {
if (ConnectionStatusLogic.INSTANCE.getValue() != ConnectionStatusValue.CONNECTED)
return;
- sensorLog.writeSensorLogLine();
+ for (SensorLog sensorLog : sensorLogs)
+ sensorLog.writeSensorLogLine();
}
});
}
public static double getSecondsSinceFileStart() {
- return sensorLog.getSecondsSinceFileStart();
+ return sensorLogs.get(0).getSecondsSinceFileStart();
}
static String getSensorName(Sensor sensor, int debugMode) {
diff --git a/java_console/ui/src/main/java/com/rusefi/ui/FormulasPane.java b/java_console/ui/src/main/java/com/rusefi/ui/FormulasPane.java
index 1f1e28d672..cfbf7b74e4 100644
--- a/java_console/ui/src/main/java/com/rusefi/ui/FormulasPane.java
+++ b/java_console/ui/src/main/java/com/rusefi/ui/FormulasPane.java
@@ -210,7 +210,7 @@ public class FormulasPane {
double displacement = ConfigField.getFloatValue(ci, Fields.DISPLACEMENT);
int cylinderCount = ConfigField.getIntValue(ci, Fields.CYLINDERSCOUNT);
String cylinderDisplacement = oneDecimal(displacement / cylinderCount);
- String injectorFlow = oneDecimal((float) Fields.INJECTOR_FLOW.getValue(ci));
+ String injectorFlow = oneDecimal((float) Fields.INJECTOR_FLOW.getValue(ci).doubleValue());
String tCharge = "$Tcharge=f(CLT=" + oneDecimal(Sensor.CLT) + "C,IAT=" + IAT
+ "C,TPS=" + tpsStr + "\\%, RPM = " + RPM + ")=" + T_CHARGE + "C$";
diff --git a/java_console/ui/src/main/java/com/rusefi/ui/light/LightweightGUI.java b/java_console/ui/src/main/java/com/rusefi/ui/light/LightweightGUI.java
index b8a055b881..739ad2d7bb 100644
--- a/java_console/ui/src/main/java/com/rusefi/ui/light/LightweightGUI.java
+++ b/java_console/ui/src/main/java/com/rusefi/ui/light/LightweightGUI.java
@@ -6,6 +6,7 @@ import com.rusefi.io.ConnectionStateListener;
import com.rusefi.io.ConnectionStatusLogic;
import com.rusefi.io.ConnectionWatchdog;
import com.rusefi.io.LinkManager;
+import com.rusefi.sensor_logs.SensorLogger;
import com.rusefi.ui.util.FrameHelper;
import javax.swing.*;
@@ -54,6 +55,7 @@ public class LightweightGUI {
ConnectionStatusLogic.INSTANCE.addListener(new ConnectionStatusLogic.Listener() {
@Override
public void onConnectionStatus(boolean isConnected) {
+ SensorLogger.init();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
diff --git a/java_console/ui/src/main/java/com/rusefi/ui/livedocs/LiveDocPanel.java b/java_console/ui/src/main/java/com/rusefi/ui/livedocs/LiveDocPanel.java
index ac8dcd2572..4900880231 100644
--- a/java_console/ui/src/main/java/com/rusefi/ui/livedocs/LiveDocPanel.java
+++ b/java_console/ui/src/main/java/com/rusefi/ui/livedocs/LiveDocPanel.java
@@ -193,7 +193,7 @@ public class LiveDocPanel {
combined.put(context, new RefreshActions() {
@Override
public void refresh(BinaryProtocol bp, byte[] response) {
- int value = (int) conditionField.getValue(new ConfigurationImage(response));
+ int value = (int) conditionField.getValue(new ConfigurationImage(response)).intValue();
conditionLabel.setText(request.getField() + " is " + (value == 1 ? "TRUE" : "FALSE"));
JPanel active;
JPanel passive;