proxy progress - hopefully getting closer?!
This commit is contained in:
parent
2de7d590f5
commit
2fdbf01a5d
|
@ -9,10 +9,7 @@ import com.rusefi.Timeouts;
|
||||||
import com.rusefi.composite.CompositeEvent;
|
import com.rusefi.composite.CompositeEvent;
|
||||||
import com.rusefi.composite.CompositeParser;
|
import com.rusefi.composite.CompositeParser;
|
||||||
import com.rusefi.config.generated.Fields;
|
import com.rusefi.config.generated.Fields;
|
||||||
import com.rusefi.core.MessagesCentral;
|
import com.rusefi.core.*;
|
||||||
import com.rusefi.core.Pair;
|
|
||||||
import com.rusefi.core.Sensor;
|
|
||||||
import com.rusefi.core.SensorCentral;
|
|
||||||
import com.rusefi.io.*;
|
import com.rusefi.io.*;
|
||||||
import com.rusefi.io.commands.GetOutputsCommand;
|
import com.rusefi.io.commands.GetOutputsCommand;
|
||||||
import com.rusefi.stream.LogicdataStreamFile;
|
import com.rusefi.stream.LogicdataStreamFile;
|
||||||
|
@ -588,45 +585,10 @@ public class BinaryProtocol implements BinaryProtocolCommands {
|
||||||
|
|
||||||
state.setCurrentOutputs(response);
|
state.setCurrentOutputs(response);
|
||||||
|
|
||||||
for (Sensor sensor : Sensor.values()) {
|
SensorCentral.getInstance().grabSensorValues(response);
|
||||||
if (sensor.getType() == null) {
|
|
||||||
// for example ETB_CONTROL_QUALITY, weird use-case
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ByteBuffer bb = ByteBuffer.wrap(response, 1 + sensor.getOffset(), 4);
|
|
||||||
bb.order(ByteOrder.LITTLE_ENDIAN);
|
|
||||||
|
|
||||||
double rawValue = getValueForChannel(bb, sensor);
|
|
||||||
double scaledValue = rawValue * sensor.getScale();
|
|
||||||
SensorCentral.getInstance().setValue(scaledValue, sensor);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double getValueForChannel(ByteBuffer bb, Sensor sensor) {
|
|
||||||
switch (sensor.getType()) {
|
|
||||||
case FLOAT:
|
|
||||||
return bb.getFloat();
|
|
||||||
case INT:
|
|
||||||
return bb.getInt();
|
|
||||||
case UINT16:
|
|
||||||
// no cast - we want to discard sign
|
|
||||||
return bb.getInt() & 0xFFFF;
|
|
||||||
case INT16:
|
|
||||||
// cast - we want to retain sign
|
|
||||||
return (short)(bb.getInt() & 0xFFFF);
|
|
||||||
case UINT8:
|
|
||||||
// no cast - discard sign
|
|
||||||
return bb.getInt() & 0xFF;
|
|
||||||
case INT8:
|
|
||||||
// cast - retain sign
|
|
||||||
return (byte)(bb.getInt() & 0xFF);
|
|
||||||
default:
|
|
||||||
throw new UnsupportedOperationException("type " + sensor.getType());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRange(byte[] src, int scrPos, int offset, int count) {
|
public void setRange(byte[] src, int scrPos, int offset, int count) {
|
||||||
state.setRange(src, scrPos, offset, count);
|
state.setRange(src, scrPos, offset, count);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,7 @@ package com.rusefi.core;
|
||||||
* 11/16/2017
|
* 11/16/2017
|
||||||
* Andrey Belomutskiy, (c) 2013-2020
|
* Andrey Belomutskiy, (c) 2013-2020
|
||||||
*/
|
*/
|
||||||
public interface ISensorCentral {
|
public interface ISensorCentral extends ISensorHolder {
|
||||||
double getValue(Sensor sensor);
|
|
||||||
|
|
||||||
void setValue(double value, Sensor sensor);
|
|
||||||
|
|
||||||
void setAnySensorListener(SensorCentral.SensorListener2 anySensorListener);
|
void setAnySensorListener(SensorCentral.SensorListener2 anySensorListener);
|
||||||
|
|
||||||
void addListener(Sensor sensor, SensorCentral.SensorListener listener);
|
void addListener(Sensor sensor, SensorCentral.SensorListener listener);
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.rusefi.core;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
|
public interface ISensorHolder {
|
||||||
|
default void grabSensorValues(byte[] response) {
|
||||||
|
for (Sensor sensor : Sensor.values()) {
|
||||||
|
if (sensor.getType() == null) {
|
||||||
|
// for example ETB_CONTROL_QUALITY, weird use-case
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuffer bb = ByteBuffer.wrap(response, 1 + sensor.getOffset(), 4);
|
||||||
|
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
|
||||||
|
double rawValue = sensor.getValueForChannel(bb);
|
||||||
|
double scaledValue = rawValue * sensor.getScale();
|
||||||
|
setValue(scaledValue, sensor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double getValue(Sensor sensor);
|
||||||
|
|
||||||
|
boolean setValue(double value, Sensor sensor);
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -201,6 +202,29 @@ public enum Sensor {
|
||||||
throw new IllegalStateException("Sensor not found: " + value);
|
throw new IllegalStateException("Sensor not found: " + value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getValueForChannel(ByteBuffer bb) {
|
||||||
|
switch (getType()) {
|
||||||
|
case FLOAT:
|
||||||
|
return bb.getFloat();
|
||||||
|
case INT:
|
||||||
|
return bb.getInt();
|
||||||
|
case UINT16:
|
||||||
|
// no cast - we want to discard sign
|
||||||
|
return bb.getInt() & 0xFFFF;
|
||||||
|
case INT16:
|
||||||
|
// cast - we want to retain sign
|
||||||
|
return (short)(bb.getInt() & 0xFFFF);
|
||||||
|
case UINT8:
|
||||||
|
// no cast - discard sign
|
||||||
|
return bb.getInt() & 0xFF;
|
||||||
|
case INT8:
|
||||||
|
// cast - retain sign
|
||||||
|
return (byte)(bb.getInt() & 0xFF);
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("type " + getType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ public class SensorCentral implements ISensorCentral {
|
||||||
public static final String RPM_KEY = "rpm";
|
public static final String RPM_KEY = "rpm";
|
||||||
private static final SensorCentral INSTANCE = new SensorCentral();
|
private static final SensorCentral INSTANCE = new SensorCentral();
|
||||||
|
|
||||||
private final Map<Sensor, Double> values = new EnumMap<>(Sensor.class);
|
private final SensorsHolder sensorsHolder = new SensorsHolder();
|
||||||
|
|
||||||
private final Map<Sensor, List<SensorListener>> allListeners = new EnumMap<>(Sensor.class);
|
private final Map<Sensor, List<SensorListener>> allListeners = new EnumMap<>(Sensor.class);
|
||||||
private SensorListener2 anySensorListener;
|
private SensorListener2 anySensorListener;
|
||||||
|
@ -30,17 +30,12 @@ public class SensorCentral implements ISensorCentral {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getValue(Sensor sensor) {
|
public double getValue(Sensor sensor) {
|
||||||
Double value = values.get(sensor);
|
return sensorsHolder.getValue(sensor);
|
||||||
if (value == null)
|
|
||||||
return Double.NaN;
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setValue(double value, final Sensor sensor) {
|
public boolean setValue(double value, final Sensor sensor) {
|
||||||
Double oldValue = values.get(sensor);
|
boolean isUpdated = sensorsHolder.setValue(value, sensor);
|
||||||
boolean isUpdated = oldValue == null || !oldValue.equals(value);
|
|
||||||
values.put(sensor, value);
|
|
||||||
List<SensorListener> listeners;
|
List<SensorListener> listeners;
|
||||||
synchronized (allListeners) {
|
synchronized (allListeners) {
|
||||||
listeners = allListeners.get(sensor);
|
listeners = allListeners.get(sensor);
|
||||||
|
@ -50,9 +45,10 @@ public class SensorCentral implements ISensorCentral {
|
||||||
applyValueToTables(value, sensor, isUpdated);
|
applyValueToTables(value, sensor, isUpdated);
|
||||||
|
|
||||||
if (listeners == null)
|
if (listeners == null)
|
||||||
return;
|
return isUpdated;
|
||||||
for (SensorListener listener : listeners)
|
for (SensorListener listener : listeners)
|
||||||
listener.onSensorUpdate(value);
|
listener.onSensorUpdate(value);
|
||||||
|
return isUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyValueToTables(double value, final Sensor sensor, boolean isUpdated) {
|
private void applyValueToTables(double value, final Sensor sensor, boolean isUpdated) {
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.rusefi.core;
|
||||||
|
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SensorsHolder implements ISensorHolder {
|
||||||
|
private final Map<Sensor, Double> values = new EnumMap<>(Sensor.class);
|
||||||
|
|
||||||
|
public double getValue(Sensor sensor) {
|
||||||
|
Double value = values.get(sensor);
|
||||||
|
if (value == null)
|
||||||
|
return Double.NaN;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setValue(double value, final Sensor sensor) {
|
||||||
|
Double oldValue = values.get(sensor);
|
||||||
|
boolean isUpdated = oldValue == null || !oldValue.equals(value);
|
||||||
|
values.put(sensor, value);
|
||||||
|
return isUpdated;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import com.opensr5.Logger;
|
||||||
import com.rusefi.Listener;
|
import com.rusefi.Listener;
|
||||||
import com.rusefi.Timeouts;
|
import com.rusefi.Timeouts;
|
||||||
import com.rusefi.binaryprotocol.BinaryProtocol;
|
import com.rusefi.binaryprotocol.BinaryProtocol;
|
||||||
|
import com.rusefi.core.Sensor;
|
||||||
import com.rusefi.io.IoStream;
|
import com.rusefi.io.IoStream;
|
||||||
import com.rusefi.io.commands.HelloCommand;
|
import com.rusefi.io.commands.HelloCommand;
|
||||||
import com.rusefi.io.tcp.BinaryProtocolProxy;
|
import com.rusefi.io.tcp.BinaryProtocolProxy;
|
||||||
|
@ -128,6 +129,7 @@ public class Backend implements Closeable {
|
||||||
if (System.currentTimeMillis() - controller.getStream().getStreamStats().getPreviousPacketArrivalTime() > 20 * SECOND) {
|
if (System.currentTimeMillis() - controller.getStream().getStreamStats().getPreviousPacketArrivalTime() > 20 * SECOND) {
|
||||||
if (controller.getTwoKindSemaphore().acquireForShortTermUsage()) {
|
if (controller.getTwoKindSemaphore().acquireForShortTermUsage()) {
|
||||||
try {
|
try {
|
||||||
|
controller.grabOutputs();
|
||||||
} finally {
|
} finally {
|
||||||
controller.getTwoKindSemaphore().releaseFromShortTermUsage();
|
controller.getTwoKindSemaphore().releaseFromShortTermUsage();
|
||||||
}
|
}
|
||||||
|
@ -257,10 +259,16 @@ public class Backend implements Closeable {
|
||||||
JsonArrayBuilder builder = Json.createArrayBuilder();
|
JsonArrayBuilder builder = Json.createArrayBuilder();
|
||||||
List<ControllerConnectionState> clients = getControllers();
|
List<ControllerConnectionState> clients = getControllers();
|
||||||
for (ControllerConnectionState client : clients) {
|
for (ControllerConnectionState client : clients) {
|
||||||
|
// todo: at the moment we use current OutputChannel layout - a better way would be to take
|
||||||
|
// todo: OutputChannel from .ini file based on controller signature
|
||||||
|
int rpm = (int) client.getSensorsHolder().getValue(Sensor.RPM);
|
||||||
|
double clt = client.getSensorsHolder().getValue(Sensor.CLT);
|
||||||
JsonObject controllerObject = Json.createObjectBuilder()
|
JsonObject controllerObject = Json.createObjectBuilder()
|
||||||
.add(UserDetails.USER_ID, client.getUserDetails().getUserId())
|
.add(UserDetails.USER_ID, client.getUserDetails().getUserId())
|
||||||
.add(UserDetails.USERNAME, client.getUserDetails().getUserName())
|
.add(UserDetails.USERNAME, client.getUserDetails().getUserName())
|
||||||
.add(IS_USED, client.getTwoKindSemaphore().isUsed())
|
.add(IS_USED, client.getTwoKindSemaphore().isUsed())
|
||||||
|
.add("RPM", rpm)
|
||||||
|
.add("CLT", clt)
|
||||||
.add(ControllerInfo.SIGNATURE, client.getSessionDetails().getControllerInfo().getSignature())
|
.add(ControllerInfo.SIGNATURE, client.getSessionDetails().getControllerInfo().getSignature())
|
||||||
.add(ControllerInfo.VEHICLE_NAME, client.getSessionDetails().getControllerInfo().getVehicleName())
|
.add(ControllerInfo.VEHICLE_NAME, client.getSessionDetails().getControllerInfo().getVehicleName())
|
||||||
.add(ControllerInfo.ENGINE_MAKE, client.getSessionDetails().getControllerInfo().getEngineMake())
|
.add(ControllerInfo.ENGINE_MAKE, client.getSessionDetails().getControllerInfo().getEngineMake())
|
||||||
|
|
|
@ -3,16 +3,16 @@ package com.rusefi.server;
|
||||||
import com.opensr5.Logger;
|
import com.opensr5.Logger;
|
||||||
import com.rusefi.auth.AutoTokenUtil;
|
import com.rusefi.auth.AutoTokenUtil;
|
||||||
import com.rusefi.binaryprotocol.IncomingDataBuffer;
|
import com.rusefi.binaryprotocol.IncomingDataBuffer;
|
||||||
|
import com.rusefi.core.SensorsHolder;
|
||||||
import com.rusefi.io.IoStream;
|
import com.rusefi.io.IoStream;
|
||||||
import com.rusefi.io.commands.GetOutputsCommand;
|
import com.rusefi.io.commands.GetOutputsCommand;
|
||||||
import com.rusefi.io.commands.HelloCommand;
|
import com.rusefi.io.commands.HelloCommand;
|
||||||
import com.rusefi.io.tcp.TcpIoStream;
|
import com.rusefi.io.tcp.TcpIoStream;
|
||||||
import com.rusefi.shared.FileUtil;
|
import com.rusefi.shared.FileUtil;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.concurrent.Semaphore;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class ControllerConnectionState {
|
public class ControllerConnectionState {
|
||||||
private final Socket clientSocket;
|
private final Socket clientSocket;
|
||||||
|
@ -33,6 +33,7 @@ public class ControllerConnectionState {
|
||||||
private ControllerKey controllerKey;
|
private ControllerKey controllerKey;
|
||||||
|
|
||||||
private final TwoKindSemaphore twoKindSemaphore = new TwoKindSemaphore();
|
private final TwoKindSemaphore twoKindSemaphore = new TwoKindSemaphore();
|
||||||
|
private final SensorsHolder sensorsHolder = new SensorsHolder();
|
||||||
|
|
||||||
public ControllerConnectionState(Socket clientSocket, Logger logger, UserDetailsResolver userDetailsResolver) {
|
public ControllerConnectionState(Socket clientSocket, Logger logger, UserDetailsResolver userDetailsResolver) {
|
||||||
this.clientSocket = clientSocket;
|
this.clientSocket = clientSocket;
|
||||||
|
@ -89,12 +90,6 @@ public class ControllerConnectionState {
|
||||||
return sessionDetails;
|
return sessionDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void runEndlessLoop() throws IOException {
|
|
||||||
while (true) {
|
|
||||||
getOutputs();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getOutputs() throws IOException {
|
public void getOutputs() throws IOException {
|
||||||
byte[] commandPacket = GetOutputsCommand.createRequest();
|
byte[] commandPacket = GetOutputsCommand.createRequest();
|
||||||
|
|
||||||
|
@ -103,9 +98,24 @@ public class ControllerConnectionState {
|
||||||
byte[] packet = incomingData.getPacket(logger, "msg", true);
|
byte[] packet = incomingData.getPacket(logger, "msg", true);
|
||||||
if (packet == null)
|
if (packet == null)
|
||||||
throw new IOException("getOutputs: No response");
|
throw new IOException("getOutputs: No response");
|
||||||
|
sensorsHolder.grabSensorValues(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public TwoKindSemaphore getTwoKindSemaphore() {
|
public TwoKindSemaphore getTwoKindSemaphore() {
|
||||||
return twoKindSemaphore;
|
return twoKindSemaphore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public SensorsHolder getSensorsHolder() {
|
||||||
|
return sensorsHolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void grabOutputs() {
|
||||||
|
try {
|
||||||
|
getOutputs();
|
||||||
|
} catch (IOException e) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue