REO progress - binary logs
This commit is contained in:
parent
8165ee016f
commit
1e240983bd
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
* </p>
|
||||
* Andrey Belomutskiy, (c) 2013-2020
|
||||
*/
|
||||
public class BinarySensorLog extends SensorLog {
|
||||
private final Function<Sensor, Double> valueProvider;
|
||||
private final Sensor[] sensors;
|
||||
private final Collection<Sensor> sensors;
|
||||
private DataOutputStream stream;
|
||||
|
||||
private int counter;
|
||||
|
||||
public BinarySensorLog() {
|
||||
this(new Function<Sensor, Double>() {
|
||||
@Override
|
||||
public Double apply(Sensor sensor) {
|
||||
return SensorCentral.getInstance().getValue(sensor);
|
||||
}
|
||||
}, SensorLogger.SENSORS);
|
||||
this(sensor -> SensorCentral.getInstance().getValue(sensor), SensorLogger.SENSORS);
|
||||
}
|
||||
|
||||
public BinarySensorLog(Function<Sensor, Double> valueProvider, Sensor... sensors) {
|
||||
this.valueProvider = valueProvider;
|
||||
this.sensors = sensors;
|
||||
this.sensors = filterOutSensorsWithoutType(Objects.requireNonNull(sensors, "sensors"));
|
||||
}
|
||||
|
||||
private Collection<Sensor> filterOutSensorsWithoutType(Sensor[] sensors) {
|
||||
return Arrays.stream(sensors).filter(new Predicate<Sensor>() {
|
||||
@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) {
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,13 +14,17 @@ import java.io.FileWriter;
|
|||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* Legacy human readable CSV log file
|
||||
* </p>
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,4 +4,6 @@ public abstract class SensorLog {
|
|||
public abstract double getSecondsSinceFileStart();
|
||||
|
||||
abstract void writeSensorLogLine();
|
||||
|
||||
public abstract void close();
|
||||
}
|
||||
|
|
|
@ -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<SensorLog> 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) {
|
||||
|
|
|
@ -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$";
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue