From 5ac854506003a77dc21106b40272b3f58c40d0ba Mon Sep 17 00:00:00 2001 From: rusefi Date: Wed, 11 Sep 2019 19:30:36 -0400 Subject: [PATCH] Delayed A/C compressor switch #922 --- firmware/controllers/core/fsio_core.h | 2 - firmware/controllers/core/fsio_impl.cpp | 13 ++--- firmware/controllers/generated/fsio_names.def | 24 ++++++++++ .../controllers/generated/fsio_strings.def | 45 ++++++++++++++++++ firmware/controllers/system_fsio.h | 4 +- firmware/gen_config.bat | 2 + java_tools/ConfigDefinition.jar | Bin 115463 -> 115441 bytes .../src/com/rusefi/ConfigDefinition.java | 14 +++++- .../output/FileFsioSettingsConsumer.java | 29 ++++++++--- .../rusefi/output/FsioSettingsConsumer.java | 23 ++++++++- .../rusefi/test/ConfigFieldParserTest.java | 26 ++++++++++ unit_tests/tests/test_logic_expression.cpp | 13 ++--- 12 files changed, 162 insertions(+), 33 deletions(-) create mode 100644 firmware/controllers/generated/fsio_names.def create mode 100644 firmware/controllers/generated/fsio_strings.def diff --git a/firmware/controllers/core/fsio_core.h b/firmware/controllers/core/fsio_core.h index 0a107805ff..ed816931b3 100644 --- a/firmware/controllers/core/fsio_core.h +++ b/firmware/controllers/core/fsio_core.h @@ -37,8 +37,6 @@ typedef enum { LE_METHOD_COOLANT = 101, LE_METHOD_FAN = 102, LE_METHOD_TIME_SINCE_BOOT = 103, - LE_METHOD_FAN_ON_SETTING = 104, - LE_METHOD_FAN_OFF_SETTING = 105, LE_METHOD_TPS = 106, LE_METHOD_MAF = 107, LE_METHOD_INTAKE_AIR = 108, diff --git a/firmware/controllers/core/fsio_impl.cpp b/firmware/controllers/core/fsio_impl.cpp index 1b91858413..c9a9ba0b5d 100644 --- a/firmware/controllers/core/fsio_impl.cpp +++ b/firmware/controllers/core/fsio_impl.cpp @@ -52,8 +52,6 @@ static LENameOrdinalPair leCoolant(LE_METHOD_COOLANT, "coolant"); static LENameOrdinalPair leIsCoolantBroken(LE_METHOD_IS_COOLANT_BROKEN, "is_clt_broken"); static LENameOrdinalPair leAcToggle(LE_METHOD_AC_TOGGLE, "ac_on_switch"); static LENameOrdinalPair leTimeSinceAcToggle(LE_METHOD_TIME_SINCE_AC_TOGGLE, "time_since_ac_on_switch"); -static LENameOrdinalPair leFanOnSetting(LE_METHOD_FAN_ON_SETTING, "fan_on_setting"); -static LENameOrdinalPair leFanOffSetting(LE_METHOD_FAN_OFF_SETTING, "fan_off_setting"); static LENameOrdinalPair leTimeSinceBoot(LE_METHOD_TIME_SINCE_BOOT, "time_since_boot"); static LENameOrdinalPair leFsioSetting(LE_METHOD_FSIO_SETTING, "fsio_setting"); static LENameOrdinalPair leFsioTable(LE_METHOD_FSIO_TABLE, "fsio_table"); @@ -66,6 +64,8 @@ static LENameOrdinalPair leCrankingRpm(LE_METHOD_CRANKING_RPM, "cranking_rpm"); static LENameOrdinalPair leStartupFuelPumpDuration(LE_METHOD_STARTUP_FUEL_PUMP_DURATION, "startup_fuel_pump_duration"); static LENameOrdinalPair leInShutdown(LE_METHOD_IN_SHUTDOWN, "in_shutdown"); +#include "fsio_names.def" + #define LE_EVAL_POOL_SIZE 32 extern EnginePins enginePins; @@ -136,10 +136,6 @@ float getEngineValue(le_action_e action DECLARE_ENGINE_PARAMETER_SUFFIX) { case LE_METHOD_TIME_SINCE_BOOT: return getTimeNowSeconds(); - case LE_METHOD_FAN_OFF_SETTING: - return engineConfiguration->fanOffTemperature; - case LE_METHOD_FAN_ON_SETTING: - return engineConfiguration->fanOnTemperature; case LE_METHOD_STARTUP_FUEL_PUMP_DURATION: return engineConfiguration->startUpFuelPumpDuration; @@ -364,16 +360,13 @@ static const char * action2String(le_action_e action) { return "cranking_rpm"; case LE_METHOD_COOLANT: return "CLT"; - case LE_METHOD_FAN_ON_SETTING: - return "fan_on"; - case LE_METHOD_FAN_OFF_SETTING: - return "fan_off"; case LE_METHOD_FAN: return "fan"; case LE_METHOD_STARTUP_FUEL_PUMP_DURATION: return "startup_fuel_pump_duration"; case LE_METHOD_IN_SHUTDOWN: return "in_shutdown"; +#include "fsio_strings.def" default: { // this is here to make compiler happy diff --git a/firmware/controllers/generated/fsio_names.def b/firmware/controllers/generated/fsio_names.def new file mode 100644 index 0000000000..4244e5c56f --- /dev/null +++ b/firmware/controllers/generated/fsio_names.def @@ -0,0 +1,24 @@ +// this file was generated automatically by rusEfi tool ConfigDefinition.jar based on integration\rusefi_config.txt Wed Sep 11 18:41:30 EDT 2019 + +// by class com.rusefi.output.FileFsioSettingsConsumer +static LENameOrdinalPair lefanOnTemperature(FSIO_SETTING_FANONTEMPERATURE, "cfg_fanOnTemperature"); +static LENameOrdinalPair lefanOffTemperature(FSIO_SETTING_FANOFFTEMPERATURE, "cfg_fanOffTemperature"); +static LENameOrdinalPair lealternatorControl_offset(FSIO_SETTING_ALTERNATORCONTROL_OFFSET, "cfg_alternatorControl_offset"); +static LENameOrdinalPair lealternatorControl_minValue(FSIO_SETTING_ALTERNATORCONTROL_MINVALUE, "cfg_alternatorControl_minValue"); +static LENameOrdinalPair leetb_offset(FSIO_SETTING_ETB_OFFSET, "cfg_etb_offset"); +static LENameOrdinalPair leetb_minValue(FSIO_SETTING_ETB_MINVALUE, "cfg_etb_minValue"); +static LENameOrdinalPair leidleRpmPid_offset(FSIO_SETTING_IDLERPMPID_OFFSET, "cfg_idleRpmPid_offset"); +static LENameOrdinalPair leidleRpmPid_minValue(FSIO_SETTING_IDLERPMPID_MINVALUE, "cfg_idleRpmPid_minValue"); +static LENameOrdinalPair lestartUpFuelPumpDuration(FSIO_SETTING_STARTUPFUELPUMPDURATION, "cfg_startUpFuelPumpDuration"); +static LENameOrdinalPair lefuelClosedLoopPid_offset(FSIO_SETTING_FUELCLOSEDLOOPPID_OFFSET, "cfg_fuelClosedLoopPid_offset"); +static LENameOrdinalPair lefuelClosedLoopPid_minValue(FSIO_SETTING_FUELCLOSEDLOOPPID_MINVALUE, "cfg_fuelClosedLoopPid_minValue"); +static LENameOrdinalPair leauxPid1_offset(FSIO_SETTING_AUXPID1_OFFSET, "cfg_auxPid1_offset"); +static LENameOrdinalPair leauxPid1_minValue(FSIO_SETTING_AUXPID1_MINVALUE, "cfg_auxPid1_minValue"); +static LENameOrdinalPair leauxPid2_offset(FSIO_SETTING_AUXPID2_OFFSET, "cfg_auxPid2_offset"); +static LENameOrdinalPair leauxPid2_minValue(FSIO_SETTING_AUXPID2_MINVALUE, "cfg_auxPid2_minValue"); +static LENameOrdinalPair leauxPid3_offset(FSIO_SETTING_AUXPID3_OFFSET, "cfg_auxPid3_offset"); +static LENameOrdinalPair leauxPid3_minValue(FSIO_SETTING_AUXPID3_MINVALUE, "cfg_auxPid3_minValue"); +static LENameOrdinalPair leauxPid4_offset(FSIO_SETTING_AUXPID4_OFFSET, "cfg_auxPid4_offset"); +static LENameOrdinalPair leauxPid4_minValue(FSIO_SETTING_AUXPID4_MINVALUE, "cfg_auxPid4_minValue"); +static LENameOrdinalPair leidleTimingPid_offset(FSIO_SETTING_IDLETIMINGPID_OFFSET, "cfg_idleTimingPid_offset"); +static LENameOrdinalPair leidleTimingPid_minValue(FSIO_SETTING_IDLETIMINGPID_MINVALUE, "cfg_idleTimingPid_minValue"); diff --git a/firmware/controllers/generated/fsio_strings.def b/firmware/controllers/generated/fsio_strings.def new file mode 100644 index 0000000000..ef2468dc58 --- /dev/null +++ b/firmware/controllers/generated/fsio_strings.def @@ -0,0 +1,45 @@ +// this file was generated automatically by rusEfi tool ConfigDefinition.jar based on integration\rusefi_config.txt Wed Sep 11 19:17:01 EDT 2019 + +// by class com.rusefi.output.FileFsioSettingsConsumer + case FSIO_SETTING_FANONTEMPERATURE: + return "cfg_fanOnTemperature"; + case FSIO_SETTING_FANOFFTEMPERATURE: + return "cfg_fanOffTemperature"; + case FSIO_SETTING_ALTERNATORCONTROL_OFFSET: + return "cfg_alternatorControl_offset"; + case FSIO_SETTING_ALTERNATORCONTROL_MINVALUE: + return "cfg_alternatorControl_minValue"; + case FSIO_SETTING_ETB_OFFSET: + return "cfg_etb_offset"; + case FSIO_SETTING_ETB_MINVALUE: + return "cfg_etb_minValue"; + case FSIO_SETTING_IDLERPMPID_OFFSET: + return "cfg_idleRpmPid_offset"; + case FSIO_SETTING_IDLERPMPID_MINVALUE: + return "cfg_idleRpmPid_minValue"; + case FSIO_SETTING_STARTUPFUELPUMPDURATION: + return "cfg_startUpFuelPumpDuration"; + case FSIO_SETTING_FUELCLOSEDLOOPPID_OFFSET: + return "cfg_fuelClosedLoopPid_offset"; + case FSIO_SETTING_FUELCLOSEDLOOPPID_MINVALUE: + return "cfg_fuelClosedLoopPid_minValue"; + case FSIO_SETTING_AUXPID1_OFFSET: + return "cfg_auxPid1_offset"; + case FSIO_SETTING_AUXPID1_MINVALUE: + return "cfg_auxPid1_minValue"; + case FSIO_SETTING_AUXPID2_OFFSET: + return "cfg_auxPid2_offset"; + case FSIO_SETTING_AUXPID2_MINVALUE: + return "cfg_auxPid2_minValue"; + case FSIO_SETTING_AUXPID3_OFFSET: + return "cfg_auxPid3_offset"; + case FSIO_SETTING_AUXPID3_MINVALUE: + return "cfg_auxPid3_minValue"; + case FSIO_SETTING_AUXPID4_OFFSET: + return "cfg_auxPid4_offset"; + case FSIO_SETTING_AUXPID4_MINVALUE: + return "cfg_auxPid4_minValue"; + case FSIO_SETTING_IDLETIMINGPID_OFFSET: + return "cfg_idleTimingPid_offset"; + case FSIO_SETTING_IDLETIMINGPID_MINVALUE: + return "cfg_idleTimingPid_minValue"; diff --git a/firmware/controllers/system_fsio.h b/firmware/controllers/system_fsio.h index 4213195e6b..8c32f58184 100644 --- a/firmware/controllers/system_fsio.h +++ b/firmware/controllers/system_fsio.h @@ -13,8 +13,8 @@ // Andrey Belomutskiy, (c) 2012-2017 // -// Human-readable: (fan and (coolant > fan_off_setting)) | (coolant > fan_on_setting) | is_clt_broken -#define FAN_CONTROL_LOGIC "fan coolant fan_off_setting > and coolant fan_on_setting > | is_clt_broken |" +// Human-readable: (fan and (coolant > cfg_fanOffTemperature)) | (coolant > cfg_fanOnTemperature) | is_clt_broken +#define FAN_CONTROL_LOGIC "fan coolant cfg_fanOffTemperature > and coolant cfg_fanOnTemperature > | is_clt_broken |" // Human-readable: (time_since_boot < startup_fuel_pump_duration) | (rpm > 0) #define FUEL_PUMP_LOGIC "time_since_boot startup_fuel_pump_duration < rpm 0 > |" diff --git a/firmware/gen_config.bat b/firmware/gen_config.bat index d7980a60b3..8a3ddc14d3 100644 --- a/firmware/gen_config.bat +++ b/firmware/gen_config.bat @@ -22,6 +22,8 @@ java -DSystemOut.name=gen_config ^ -c_destination controllers\generated\engine_configuration_generated_structures.h ^ -c_fsio_constants controllers\generated\fsio_enums_generated.def ^ -c_fsio_getters controllers\generated\fsio_getters.def ^ + -c_fsio_names controllers\generated\fsio_names.def ^ + -c_fsio_strings controllers\generated\fsio_strings.def ^ -java_destination ../java_console/models/src/com/rusefi/config/generated/Fields.java ^ -romraider_destination ../java_console/rusefi.xml ^ -skip build/config.gen diff --git a/java_tools/ConfigDefinition.jar b/java_tools/ConfigDefinition.jar index eaaf2f1dfccfaf6ff4bf74c822d9af9cc09c1ebf..b937768f747ec185533abd5fb25a628e944e6acc 100644 GIT binary patch delta 53498 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 Q0{#62eOty+_^A8-58}x`L;wH) diff --git a/java_tools/configuration_definition/src/com/rusefi/ConfigDefinition.java b/java_tools/configuration_definition/src/com/rusefi/ConfigDefinition.java index c66966d079..9257d537c4 100644 --- a/java_tools/configuration_definition/src/com/rusefi/ConfigDefinition.java +++ b/java_tools/configuration_definition/src/com/rusefi/ConfigDefinition.java @@ -30,6 +30,8 @@ public class ConfigDefinition { private static final String KEY_C_DESTINATION = "-c_destination"; private static final String KEY_C_FSIO_CONSTANTS = "-c_fsio_constants"; private static final String KEY_C_FSIO_GETTERS = "-c_fsio_getters"; + private static final String KEY_C_FSIO_NAMES = "-c_fsio_names"; + private static final String KEY_C_FSIO_STRING = "-c_fsio_strings"; private static final String KEY_C_DEFINES = "-c_defines"; private static final String KEY_WITH_C_DEFINES = "-with_c_defines"; private static final String KEY_JAVA_DESTINATION = "-java_destination"; @@ -68,6 +70,8 @@ public class ConfigDefinition { String destCDefinesFileName = null; String destCFsioConstantsFileName = null; String destCFsioGettersFileName = null; + String namesCFileName = null; + String stringsCFileName = null; String javaDestinationFileName = null; String romRaiderDestination = null; List prependFiles = new ArrayList<>(); @@ -85,6 +89,10 @@ public class ConfigDefinition { destCHeaderFileName = args[i + 1]; } else if (key.equals(KEY_C_FSIO_GETTERS)) { destCFsioGettersFileName = args[i + 1]; + } else if (key.equals(KEY_C_FSIO_STRING)) { + stringsCFileName = args[i + 1]; + } else if (key.equals(KEY_C_FSIO_NAMES)) { + namesCFileName = args[i + 1]; } else if (key.equals(KEY_C_FSIO_CONSTANTS)) { destCFsioConstantsFileName = args[i + 1]; } else if (key.equals(KEY_ZERO_INIT)) { @@ -141,7 +149,11 @@ public class ConfigDefinition { } if (destCFsioConstantsFileName != null || destCFsioGettersFileName != null) { - destinations.add(new FileFsioSettingsConsumer(state, destCFsioConstantsFileName, destCFsioGettersFileName)); + destinations.add(new FileFsioSettingsConsumer(state, + destCFsioConstantsFileName, + destCFsioGettersFileName, + namesCFileName, + stringsCFileName)); } if (destinations.isEmpty()) diff --git a/java_tools/configuration_definition/src/com/rusefi/output/FileFsioSettingsConsumer.java b/java_tools/configuration_definition/src/com/rusefi/output/FileFsioSettingsConsumer.java index 5c46c74701..76511b520e 100644 --- a/java_tools/configuration_definition/src/com/rusefi/output/FileFsioSettingsConsumer.java +++ b/java_tools/configuration_definition/src/com/rusefi/output/FileFsioSettingsConsumer.java @@ -5,34 +5,49 @@ import com.rusefi.ReaderState; import com.rusefi.util.LazyFile; import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; import static com.rusefi.ConfigDefinition.EOL; public class FileFsioSettingsConsumer extends FsioSettingsConsumer { private final LazyFile enumFile; private final LazyFile gettersFile; + private final LazyFile namesFile; + private final LazyFile stringsFile; - public FileFsioSettingsConsumer(ReaderState state, String destCFsioConstantsFileName, String destCFsioGettersFileName) { + public FileFsioSettingsConsumer(ReaderState state, + String destCFsioConstantsFileName, + String destCFsioGettersFileName, + String namesCFileName, + String stringsCFileName) { super(state); enumFile = new LazyFile(destCFsioConstantsFileName); gettersFile = new LazyFile(destCFsioGettersFileName); + namesFile = new LazyFile(namesCFileName); + stringsFile = new LazyFile(stringsCFileName); } @Override public void startFile() { - enumFile.write("// this file " + ConfigDefinition.MESSAGE + ConfigDefinition.EOL + EOL); - enumFile.write("// by " + getClass() + EOL); - - gettersFile.write("// this file " + ConfigDefinition.MESSAGE + ConfigDefinition.EOL + EOL); - gettersFile.write("// by " + getClass() + EOL); + for (LazyFile file : Arrays.asList(enumFile, gettersFile, stringsFile, namesFile)) { + file.write("// this file " + ConfigDefinition.MESSAGE + ConfigDefinition.EOL + EOL); + file.write("// by " + getClass() + EOL); + } } @Override public void endFile() throws IOException { - enumFile.write(enumDefinition.toString()); + enumFile.write(getEnumDefinition()); enumFile.close(); gettersFile.write(getContent()); gettersFile.close(); + + namesFile.write(getNames()); + namesFile.close(); + + stringsFile.write(getStrings()); + stringsFile.close(); } } diff --git a/java_tools/configuration_definition/src/com/rusefi/output/FsioSettingsConsumer.java b/java_tools/configuration_definition/src/com/rusefi/output/FsioSettingsConsumer.java index 965da0e458..f373db6b78 100644 --- a/java_tools/configuration_definition/src/com/rusefi/output/FsioSettingsConsumer.java +++ b/java_tools/configuration_definition/src/com/rusefi/output/FsioSettingsConsumer.java @@ -14,7 +14,9 @@ import java.util.List; public abstract class FsioSettingsConsumer implements ConfigurationConsumer { private final CharArrayWriter content = new CharArrayWriter(); - protected final CharArrayWriter enumDefinition = new CharArrayWriter(); + private final CharArrayWriter enumDefinition = new CharArrayWriter(); + private final CharArrayWriter names = new CharArrayWriter(); + private final CharArrayWriter strings = new CharArrayWriter(); private final ReaderState state; private int currentIndex = 1000; @@ -59,7 +61,8 @@ public abstract class FsioSettingsConsumer implements ConfigurationConsumer { String nameWithPrefix = prefix + configField.getName(); - String enumName = "FSIO_SETTING_" + nameWithPrefix.replaceAll("\\.", "_").toUpperCase(); + String nameWithPrefixUnderscore = nameWithPrefix.replaceAll("\\.", "_"); + String enumName = "FSIO_SETTING_" + nameWithPrefixUnderscore.toUpperCase(); enumDefinition.append("\t" + enumName + " = " + currentIndex++ + ",\n"); @@ -69,7 +72,23 @@ public abstract class FsioSettingsConsumer implements ConfigurationConsumer { content.append("\tcase " + enumName + ":\n"); content.append("\t\treturn engineConfiguration->" + cFieldName + ";\n"); + + String rusEfiName = "\"cfg_" + nameWithPrefixUnderscore + "\""; + + strings.append("\tcase " + enumName + ":\n"); + strings.append("\t\treturn " + rusEfiName + ";\n"); + + names.append("static LENameOrdinalPair le" + nameWithPrefixUnderscore + "(" + enumName + ", " + rusEfiName + ");\n"); } } + public String getNames() { + return names.toString(); + } + + + public String getStrings() { + return strings.toString(); + } + } diff --git a/java_tools/configuration_definition/src/com/rusefi/test/ConfigFieldParserTest.java b/java_tools/configuration_definition/src/com/rusefi/test/ConfigFieldParserTest.java index ad3fec5345..83c47f4f67 100644 --- a/java_tools/configuration_definition/src/com/rusefi/test/ConfigFieldParserTest.java +++ b/java_tools/configuration_definition/src/com/rusefi/test/ConfigFieldParserTest.java @@ -125,6 +125,32 @@ public class ConfigFieldParserTest { "\tFSIO_SETTING_ETB2_OFFSET = 1006,\n" + "\tFSIO_SETTING_ETB2_MINVALUE = 1007,\n", fsioSettingsConsumer.getEnumDefinition()); + + assertEquals("static LENameOrdinalPair leoffset(FSIO_SETTING_OFFSET, \"cfg_offset\");\n" + + "static LENameOrdinalPair leminValue(FSIO_SETTING_MINVALUE, \"cfg_minValue\");\n" + + "static LENameOrdinalPair lealternatorControl_offset(FSIO_SETTING_ALTERNATORCONTROL_OFFSET, \"cfg_alternatorControl_offset\");\n" + + "static LENameOrdinalPair lealternatorControl_minValue(FSIO_SETTING_ALTERNATORCONTROL_MINVALUE, \"cfg_alternatorControl_minValue\");\n" + + "static LENameOrdinalPair leetb1_offset(FSIO_SETTING_ETB1_OFFSET, \"cfg_etb1_offset\");\n" + + "static LENameOrdinalPair leetb1_minValue(FSIO_SETTING_ETB1_MINVALUE, \"cfg_etb1_minValue\");\n" + + "static LENameOrdinalPair leetb2_offset(FSIO_SETTING_ETB2_OFFSET, \"cfg_etb2_offset\");\n" + + "static LENameOrdinalPair leetb2_minValue(FSIO_SETTING_ETB2_MINVALUE, \"cfg_etb2_minValue\");\n", fsioSettingsConsumer.getNames()); + + assertEquals("\tcase FSIO_SETTING_OFFSET:\n" + + "\t\treturn \"cfg_offset\";\n" + + "\tcase FSIO_SETTING_MINVALUE:\n" + + "\t\treturn \"cfg_minValue\";\n" + + "\tcase FSIO_SETTING_ALTERNATORCONTROL_OFFSET:\n" + + "\t\treturn \"cfg_alternatorControl_offset\";\n" + + "\tcase FSIO_SETTING_ALTERNATORCONTROL_MINVALUE:\n" + + "\t\treturn \"cfg_alternatorControl_minValue\";\n" + + "\tcase FSIO_SETTING_ETB1_OFFSET:\n" + + "\t\treturn \"cfg_etb1_offset\";\n" + + "\tcase FSIO_SETTING_ETB1_MINVALUE:\n" + + "\t\treturn \"cfg_etb1_minValue\";\n" + + "\tcase FSIO_SETTING_ETB2_OFFSET:\n" + + "\t\treturn \"cfg_etb2_offset\";\n" + + "\tcase FSIO_SETTING_ETB2_MINVALUE:\n" + + "\t\treturn \"cfg_etb2_minValue\";\n", fsioSettingsConsumer.getStrings()); } } diff --git a/unit_tests/tests/test_logic_expression.cpp b/unit_tests/tests/test_logic_expression.cpp index 345ed2df27..54d573a4c6 100644 --- a/unit_tests/tests/test_logic_expression.cpp +++ b/unit_tests/tests/test_logic_expression.cpp @@ -31,9 +31,8 @@ float getEngineValue(le_action_e action DECLARE_ENGINE_PARAMETER_SUFFIX) { return mockCrankingRpm; case LE_METHOD_TIME_SINCE_BOOT: return mockTimeSinceBoot; - case LE_METHOD_FAN_ON_SETTING: - return 0; - case LE_METHOD_FAN_OFF_SETTING: + case FSIO_SETTING_FANONTEMPERATURE: + case FSIO_SETTING_FANOFFTEMPERATURE: return 0; case LE_METHOD_VBATT: return 12; @@ -211,8 +210,8 @@ TEST(misc, testLogicExpressions) { ASSERT_EQ(0, c.calcLogValue[0]); } - testExpression("fan_off_setting", 0); - testExpression("coolant fan_off_setting >", 1); + testExpression("cfg_fanOffTemperature", 0); + testExpression("coolant cfg_fanOffTemperature >", 1); testExpression("0 1 &", 0); testExpression("0 1 |", 1); @@ -228,9 +227,5 @@ TEST(misc, testLogicExpressions) { testExpression("cranking_rpm", 200); testExpression(STARTER_BLOCK, 0); testExpression("rpm cranking_rpm > ", 1); - } - mockRpm = 900; - testExpression("fan NOT coolant 90 > AND fan coolant 85 > AND OR", 1); - }