From f367a16570a6902a6ceea9a89f716f0a9a61875c Mon Sep 17 00:00:00 2001
From: rusefillc
Date: Wed, 22 Jun 2022 02:05:04 -0400
Subject: [PATCH] progress
---
.../com/rusefi/can/reader/dbc/DbcPacket.java | 4 +
.../rusefi/sensor_logs/BinaryLogEntry.java | 14 ++
.../rusefi/sensor_logs/BinarySensorLog.java | 156 ++++++++++++++++++
.../java/com/rusefi/sensor_logs/Fields.java | 6 +
.../can/reader/impl/TrcToMlqSandbox.java | 71 ++++++++
5 files changed, 251 insertions(+)
create mode 100644 src/main/java/com/rusefi/sensor_logs/BinaryLogEntry.java
create mode 100644 src/main/java/com/rusefi/sensor_logs/BinarySensorLog.java
create mode 100644 src/main/java/com/rusefi/sensor_logs/Fields.java
create mode 100644 src/test/java/com/rusefi/can/reader/impl/TrcToMlqSandbox.java
diff --git a/src/main/java/com/rusefi/can/reader/dbc/DbcPacket.java b/src/main/java/com/rusefi/can/reader/dbc/DbcPacket.java
index a79387a..8dddb83 100644
--- a/src/main/java/com/rusefi/can/reader/dbc/DbcPacket.java
+++ b/src/main/java/com/rusefi/can/reader/dbc/DbcPacket.java
@@ -21,6 +21,10 @@ public class DbcPacket {
return name;
}
+ public List getFields() {
+ return fields;
+ }
+
@Override
public String toString() {
return "DbcPacket{" +
diff --git a/src/main/java/com/rusefi/sensor_logs/BinaryLogEntry.java b/src/main/java/com/rusefi/sensor_logs/BinaryLogEntry.java
new file mode 100644
index 0000000..9497e7a
--- /dev/null
+++ b/src/main/java/com/rusefi/sensor_logs/BinaryLogEntry.java
@@ -0,0 +1,14 @@
+package com.rusefi.sensor_logs;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public interface BinaryLogEntry {
+ String getName();
+
+ String getUnit();
+
+ int getByteSize();
+
+ void writeToLog(DataOutputStream dos, double value) throws IOException;
+}
diff --git a/src/main/java/com/rusefi/sensor_logs/BinarySensorLog.java b/src/main/java/com/rusefi/sensor_logs/BinarySensorLog.java
new file mode 100644
index 0000000..8473ec8
--- /dev/null
+++ b/src/main/java/com/rusefi/sensor_logs/BinarySensorLog.java
@@ -0,0 +1,156 @@
+package com.rusefi.sensor_logs;
+
+import java.io.*;
+import java.util.*;
+import java.util.function.Function;
+
+/**
+ * MLV .mlq binary log file
+ *
+ * Andrey Belomutskiy, (c) 2013-2020
+ */
+public class BinarySensorLog implements SensorLog {
+ private final Function valueProvider;
+ private final Collection entries;
+ private DataOutputStream stream;
+
+ private String fileName;
+
+ private int counter;
+
+ public BinarySensorLog(Function valueProvider, Collection sensors) {
+ this.valueProvider = valueProvider;
+ this.entries = Objects.requireNonNull(sensors, "entries");
+ }
+
+ @Override
+ public double getSecondsSinceFileStart() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void writeSensorLogLine() {
+ if (stream == null) {
+ fileName = "gauges_" + ".mlg";
+
+ try {
+ stream = new DataOutputStream(new FileOutputStream(fileName));
+ writeHeader();
+ } catch (Throwable e) {
+ e.printStackTrace();
+ stream = null;
+ }
+ }
+
+ if (stream != null) {
+ try {
+ stream.write(0);
+ stream.write(counter++);
+ stream.writeShort((int) (System.currentTimeMillis() * 100));
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ DataOutputStream dos = new DataOutputStream(baos);
+
+ for (T sensor : entries) {
+ double value = valueProvider.apply(sensor);
+ sensor.writeToLog(dos, value);
+ }
+
+ byte[] byteArray = baos.toByteArray();
+ byte checkSum = 0;
+ for (byte b : byteArray) {
+ checkSum += b;
+ }
+ 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() throws IOException {
+ String headerText = "\"rusEFI " + "sdsr" + "\"\n" +
+ "\"Capture Date: " + new Date() + "\"\n";
+
+ for (char c : "MLVLG\0".toCharArray()) {
+ stream.write(c);
+ }
+
+ int fieldsDataSize = 0;
+ for (BinaryLogEntry entry : entries) {
+ fieldsDataSize += entry.getByteSize();
+ }
+
+ // 0006h Format version = 01
+ stream.write(0);
+ stream.write(1);
+ // 0008h Timestamp
+ stream.writeInt((int) (System.currentTimeMillis() / 1000));
+ // 000ch
+ int offsetToText = Fields.MLQ_HEADER_SIZE + Fields.MLQ_FIELD_HEADER_SIZE * entries.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(entries.size());
+
+ for (BinaryLogEntry sensor : entries) {
+ String name = sensor.getName();
+ String unit = sensor.getUnit();
+
+ // 0000h
+ stream.write(sensor.getByteSize());
+ // 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);
+ }
+ if (stream.size() != offsetToText)
+ throw new IllegalStateException("We are doing something wrong :( stream.size=" + stream.size());
+ writeLine(stream, headerText, headerText.length());
+ }
+
+ @Override
+ public void close() {
+ close(stream);
+ stream = null;
+ }
+
+ public static void close(Closeable closeable) {
+ try {
+ if (closeable != null) {
+ closeable.close();
+ }
+ } catch (IOException e) {
+ // ignoring
+ }
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ private void writeLine(DataOutputStream stream, String name, int length) throws IOException {
+ for (int i = 0; i < Math.min(name.length(), length); i++) {
+ stream.write(name.charAt(i));
+ }
+ for (int i = name.length(); i < length; i++)
+ stream.write(0);
+ }
+}
diff --git a/src/main/java/com/rusefi/sensor_logs/Fields.java b/src/main/java/com/rusefi/sensor_logs/Fields.java
new file mode 100644
index 0000000..223aba8
--- /dev/null
+++ b/src/main/java/com/rusefi/sensor_logs/Fields.java
@@ -0,0 +1,6 @@
+package com.rusefi.sensor_logs;
+
+public class Fields {
+ public static final int MLQ_FIELD_HEADER_SIZE = 55;
+ public static final int MLQ_HEADER_SIZE = 22;
+}
diff --git a/src/test/java/com/rusefi/can/reader/impl/TrcToMlqSandbox.java b/src/test/java/com/rusefi/can/reader/impl/TrcToMlqSandbox.java
new file mode 100644
index 0000000..be480f4
--- /dev/null
+++ b/src/test/java/com/rusefi/can/reader/impl/TrcToMlqSandbox.java
@@ -0,0 +1,71 @@
+package com.rusefi.can.reader.impl;
+
+import com.rusefi.can.CANPacket;
+import com.rusefi.can.reader.dbc.DbcField;
+import com.rusefi.can.reader.dbc.DbcFile;
+import com.rusefi.can.reader.dbc.DbcPacket;
+import com.rusefi.sensor_logs.BinaryLogEntry;
+import com.rusefi.sensor_logs.BinarySensorLog;
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+
+import static com.rusefi.can.reader.impl.ParseDBC.VAG_MOTOR_1;
+
+public class TrcToMlqSandbox {
+ public static void main(String[] args) throws IOException {
+ DbcFile dbc = new DbcFile();
+ {
+ BufferedReader reader = new BufferedReader(new StringReader(VAG_MOTOR_1));
+ dbc.read(reader);
+ }
+
+ List entries = new ArrayList<>();
+ for (DbcPacket packet : dbc.packets) {
+ for (DbcField field : packet.getFields()) {
+ entries.add(new BinaryLogEntry() {
+ @Override
+ public String getName() {
+ return field.getName();
+ }
+
+ @Override
+ public String getUnit() {
+ return "x";
+ }
+
+ @Override
+ public int getByteSize() {
+ return 4;
+ }
+
+ @Override
+ public void writeToLog(DataOutputStream dos, double value) throws IOException {
+ dos.writeFloat((float) value);
+ }
+ });
+
+ }
+ }
+
+ PcanTrcReader reader = new PcanTrcReader();
+ List packets = reader.readFile("C:\\stuff\\rusefi_documentation\\OEM-Docs\\VAG\\2006-Passat-B6\\passat-b6-stock-ecu-ecu-ptcan-not-running-pedal-up-and-down.trc");
+ System.out.println(packets.size() + " packets");
+
+
+ BinarySensorLog log = new BinarySensorLog(new Function() {
+ @Override
+ public Double apply(BinaryLogEntry o) {
+ System.out.println("apply");
+ return null;
+ }
+ }, entries);
+
+
+ }
+}