[Cleanup] Reduce build size by using float instead of double in rules

This commit is contained in:
TD-er
2023-05-12 14:56:59 +02:00
parent 75f2d94aea
commit 1ddeee5183
55 changed files with 568 additions and 235 deletions
@@ -29,20 +29,6 @@
/* PRIVATE FUNCTIONS */
/*========================================================================*/
/**************************************************************************/
/*!
* @brief Implements missing powf function
* @param x
* Base number
* @param y
* Exponent
* @return x raised to the power of y
*/
/**************************************************************************/
float powf(const float x, const float y)
{
return (float)(pow((double)x, (double)y));
}
/**************************************************************************/
/*!
+1 -1
View File
@@ -493,7 +493,7 @@ boolean Plugin_016(uint8_t function, struct EventStruct *event, String& string)
# if P016_FEATURE_COMMAND_HANDLING
P016_CMDINHIBIT = getFormItemInt(F("pcmdinhibit"));
# endif // if P016_FEATURE_COMMAND_HANDLING
P016_BUFFERSIZE = ceil(getFormItemInt(F("pbuffersize")) / 2.0f); // UI shows bytes, we store buffer unit = uint16_t
P016_BUFFERSIZE = (getFormItemInt(F("pbuffersize")) + 1) >> 1; // UI shows bytes, we store buffer unit = uint16_t
# if P016_FEATURE_COMMAND_HANDLING
+2 -2
View File
@@ -131,10 +131,10 @@ boolean Plugin_021(uint8_t function, struct EventStruct *event, String& string)
if (equals(command, F("setlevel"))) {
String value = parseString(string, 2);
double result = 0.0;
ESPEASY_RULES_FLOAT_TYPE result{};
if (!isError(Calculate(value, result))) {
if (!essentiallyEqual(static_cast<double>(P021_TRIGGER_LEVEL), result)) { // Save only if different
if (!essentiallyEqual(static_cast<ESPEASY_RULES_FLOAT_TYPE>(P021_TRIGGER_LEVEL), result)) { // Save only if different
P021_TRIGGER_LEVEL = result;
if (P021_DONT_ALWAYS_SAVE == 0) { // save only if explicitly enabled
+1 -1
View File
@@ -1200,7 +1200,7 @@ boolean Plugin_036(uint8_t function, struct EventStruct *event, String& string)
if (strlen > 0) {
const float fAvgPixPerChar = static_cast<float>(PixLength) / strlen;
const int iCharToRemove = ceil((static_cast<float>(PixLength - 255)) / fAvgPixPerChar);
const int iCharToRemove = ceilf((static_cast<float>(PixLength - 255)) / fAvgPixPerChar);
// shorten string because OLED controller can not handle such long strings
*currentLine = currentLine->substring(0, strlen - iCharToRemove);
+1 -1
View File
@@ -589,7 +589,7 @@ boolean Plugin_037(uint8_t function, struct EventStruct *event, String& string)
bool numericPayload = true; // Unless it's not
if (!checkJson || (checkJson && (!key.isEmpty()))) {
double doublePayload;
ESPEASY_RULES_FLOAT_TYPE doublePayload{};
if (!validDoubleFromString(Payload, doublePayload)) {
if (!checkJson && (P037_SEND_EVENTS == 0)) { // If we want all values as events, then no error logged and don't stop here
+1 -1
View File
@@ -128,7 +128,7 @@ boolean Plugin_071(uint8_t function, struct EventStruct *event, String& string)
i = 0;
parityerrors = 0;
char *tmpstr;
double m_energy, m_volume;
ESPEASY_RULES_FLOAT_TYPE m_energy, m_volume;
float m_tempin, m_tempout, m_tempdiff, m_power;
long m_hours, m_flow;
+34 -9
View File
@@ -228,16 +228,31 @@ boolean Plugin_076(uint8_t function, struct EventStruct *event, String& string)
}
double current, voltage, power;
ESPEASY_RULES_FLOAT_TYPE current, voltage, power;
if (Plugin076_LoadMultipliers(event->TaskIndex, current, voltage, power)) {
addFormSubHeader(F("Calibration Values"));
addFormTextBox(F("Current Multiplier"), F("currmult"),
doubleToString(current, 2), 25);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
doubleToString(current, 2)
#else
floatToString(current, 2)
#endif
, 25);
addFormTextBox(F("Voltage Multiplier"), F("voltmult"),
doubleToString(voltage, 2), 25);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
doubleToString(voltage, 2)
#else
floatToString(voltage, 2)
#endif
, 25);
addFormTextBox(F("Power Multiplier"), F("powmult"),
doubleToString(power, 2), 25);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
doubleToString(power, 2)
#else
floatToString(power, 2)
#endif
, 25);
}
success = true;
@@ -268,7 +283,7 @@ boolean Plugin_076(uint8_t function, struct EventStruct *event, String& string)
}
// Set Multipliers
double hlwMultipliers[3];
ESPEASY_RULES_FLOAT_TYPE hlwMultipliers[3];
hlwMultipliers[0] = getFormItemFloat(F("currmult"));
hlwMultipliers[1] = getFormItemFloat(F("voltmult"));
hlwMultipliers[2] = getFormItemFloat(F("powmult"));
@@ -438,7 +453,7 @@ boolean Plugin_076(uint8_t function, struct EventStruct *event, String& string)
}
# endif // ifndef BUILD_NO_DEBUG
double current, voltage, power;
ESPEASY_RULES_FLOAT_TYPE current, voltage, power;
if (Plugin076_LoadMultipliers(event->TaskIndex, current, voltage, power)) {
# ifndef BUILD_NO_DEBUG
@@ -554,15 +569,25 @@ void Plugin076_SaveMultipliers() {
if (StoredTaskIndex < 0) {
return; // Not yet initialized.
}
double hlwMultipliers[3]{};
ESPEASY_RULES_FLOAT_TYPE hlwMultipliers[3]{};
if (Plugin076_ReadMultipliers(hlwMultipliers[0], hlwMultipliers[1], hlwMultipliers[2])) {
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
SaveCustomTaskSettings(StoredTaskIndex, reinterpret_cast<const uint8_t *>(&hlwMultipliers),
sizeof(hlwMultipliers));
#else
double hlwMultipliers_d[3]{};
hlwMultipliers_d[0] = hlwMultipliers[0];
hlwMultipliers_d[1] = hlwMultipliers[1];
hlwMultipliers_d[2] = hlwMultipliers[2];
SaveCustomTaskSettings(StoredTaskIndex, reinterpret_cast<const uint8_t *>(&hlwMultipliers_d),
sizeof(hlwMultipliers_d));
#endif
}
}
bool Plugin076_ReadMultipliers(double& current, double& voltage, double& power) {
bool Plugin076_ReadMultipliers(ESPEASY_RULES_FLOAT_TYPE& current, ESPEASY_RULES_FLOAT_TYPE& voltage, ESPEASY_RULES_FLOAT_TYPE& power) {
current = 0.0f;
voltage = 0.0f;
power = 0.0f;
@@ -576,7 +601,7 @@ bool Plugin076_ReadMultipliers(double& current, double& voltage, double& power)
return false;
}
bool Plugin076_LoadMultipliers(taskIndex_t TaskIndex, double& current, double& voltage, double& power) {
bool Plugin076_LoadMultipliers(taskIndex_t TaskIndex, ESPEASY_RULES_FLOAT_TYPE& current, ESPEASY_RULES_FLOAT_TYPE& voltage, ESPEASY_RULES_FLOAT_TYPE& power) {
// If multipliers are empty load default ones and save all of them as
// "CustomTaskSettings"
if (!Plugin076_ReadMultipliers(current, voltage, power)) {
+5 -5
View File
@@ -426,7 +426,7 @@ boolean Plugin_082(uint8_t function, struct EventStruct *event, String& string)
}
activeFix = curFixStatus;
}
double distance = 0.0;
ESPEASY_RULES_FLOAT_TYPE distance{};
if (curFixStatus) {
if (P082_data->gps->location.isUpdated()) {
@@ -482,12 +482,12 @@ boolean Plugin_082(uint8_t function, struct EventStruct *event, String& string)
if (P082_DISTANCE > 0) {
// Check travelled distance.
if ((distance > static_cast<double>(P082_DISTANCE)) || (distance < 0.0)) {
if ((distance > static_cast<ESPEASY_RULES_FLOAT_TYPE>(P082_DISTANCE)) || (distance < 0)) {
if (P082_data->storeCurPos(P082_TIMEOUT)) {
distance_passed = true;
// Add sanity check for distance travelled
if (distance > static_cast<double>(P082_DISTANCE)) {
if (distance > static_cast<ESPEASY_RULES_FLOAT_TYPE>(P082_DISTANCE)) {
if (Settings.UseRules) {
String eventString = F("GPS#travelled=");
eventString += distance;
@@ -813,8 +813,8 @@ void P082_setSystemTime(struct EventStruct *event) {
if (updated) {
// Use floating point precision to use the time since last update from GPS
// and the given offset in centisecond.
double time = makeTime(dateTime);
time += static_cast<double>(age) / 1000.0;
ESPEASY_RULES_FLOAT_TYPE time = makeTime(dateTime);
time += (static_cast<ESPEASY_RULES_FLOAT_TYPE>(age) / static_cast<ESPEASY_RULES_FLOAT_TYPE>(1000));
node_time.setExternalTimeSource(time, timeSource_t::GPS_time_source);
P082_data->_last_setSystemTime = millis();
}
+17 -14
View File
@@ -20,14 +20,14 @@
#define VEML6070_ADDR_H 0x39
#define VEML6070_ADDR_L 0x38
#define VEML6070_RSET_DEFAULT 270000 // 270K default resistor value 270000 ohm, range from 220K..1Meg
#define VEML6070_UV_MAX_INDEX 15 // normal 11, internal on weather laboratories and NASA it's 15 so far the sensor is linear
#define VEML6070_UV_MAX_DEFAULT 11 // 11 = public default table values
#define VEML6070_POWER_COEFFCIENT 0.025 // based on calculations from Karel Vanicek and reorder by hand
#define VEML6070_TABLE_COEFFCIENT 32.86270591 // calculated by hand with help from a friend of mine, a professor which works in aero space
// things
// (resistor, differences, power coefficients and official UV index calculations (LAT & LONG
// will be added later)
#define VEML6070_RSET_DEFAULT 270000 // 270K default resistor value 270000 ohm, range from 220K..1Meg
#define VEML6070_UV_MAX_INDEX 15 // normal 11, internal on weather laboratories and NASA it's 15 so far the sensor is linear
#define VEML6070_UV_MAX_DEFAULT 11 // 11 = public default table values
#define VEML6070_POWER_COEFFCIENT 0.025f // based on calculations from Karel Vanicek and reorder by hand
#define VEML6070_TABLE_COEFFCIENT 32.86270591f // calculated by hand with help from a friend of mine, a professor which works in aero space
// things
// (resistor, differences, power coefficients and official UV index calculations (LAT & LONG
// will be added later)
#define VEML6070_base_value ((VEML6070_RSET_DEFAULT / VEML6070_TABLE_COEFFCIENT) / VEML6070_UV_MAX_DEFAULT) * (1)
#define VEML6070_max_value ((VEML6070_RSET_DEFAULT / VEML6070_TABLE_COEFFCIENT) / VEML6070_UV_MAX_DEFAULT) * (VEML6070_UV_MAX_INDEX)
@@ -116,7 +116,7 @@ boolean Plugin_084(uint8_t function, struct EventStruct *event, String& string)
case PLUGIN_READ:
{
uint16_t uv_raw;
double uv_risk, uv_power;
ESPEASY_RULES_FLOAT_TYPE uv_risk, uv_power;
bool read_status;
uv_raw = VEML6070_ReadUv(&read_status); // get UV raw values
@@ -183,12 +183,15 @@ bool VEML6070_Init(uint8_t it)
// 11.0 - 12.9 "BurnL1/2" = sun->skin burns level 1..2
// 13.0 - 25.0 "BurnL3" = sun->skin burns with level 3
double VEML6070_UvRiskLevel(uint16_t uv_level)
ESPEASY_RULES_FLOAT_TYPE VEML6070_UvRiskLevel(uint16_t uv_level)
{
double risk = 0;
ESPEASY_RULES_FLOAT_TYPE risk{};
if (uv_level < VEML6070_max_value) {
return (double)uv_level / VEML6070_base_value;
constexpr ESPEASY_RULES_FLOAT_TYPE max_value = VEML6070_max_value;
if (uv_level < max_value) {
constexpr ESPEASY_RULES_FLOAT_TYPE factor = VEML6070_base_value;
return (ESPEASY_RULES_FLOAT_TYPE)uv_level / factor;
} else {
// out of range and much to high - it must be outerspace or sensor damaged
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
@@ -201,7 +204,7 @@ double VEML6070_UvRiskLevel(uint16_t uv_level)
}
}
double VEML6070_UvPower(double uvrisk)
ESPEASY_RULES_FLOAT_TYPE VEML6070_UvPower(ESPEASY_RULES_FLOAT_TYPE uvrisk)
{
// based on calculations for effective irradiation from Karel Vanicek
return VEML6070_POWER_COEFFCIENT * uvrisk;
+3 -6
View File
@@ -304,8 +304,7 @@ boolean Plugin_103(uint8_t function, struct EventStruct *event, String& string)
(board_type == AtlasEZO_Sensors_e::EC) ||
(board_type == AtlasEZO_Sensors_e::DO))
{
double value;
char strValue[6] = { 0 };
ESPEASY_RULES_FLOAT_TYPE value{};
addFormSubHeader(F("Temperature compensation"));
char deviceTemperatureTemplate[40] = { 0 };
@@ -324,9 +323,7 @@ boolean Plugin_103(uint8_t function, struct EventStruct *event, String& string)
value = P103_FIXED_TEMP_VALUE;
}
dtostrf(value, 5, 2, strValue);
ZERO_TERMINATE(strValue);
addFormNote(concat(F("Actual value: "), String(strValue)));
addFormNote(concat(F("Actual value: "), toString(value, 2)));
}
success = true;
@@ -461,7 +458,7 @@ boolean Plugin_103(uint8_t function, struct EventStruct *event, String& string)
String temperatureString(parseTemplate(deviceTemperatureTemplateString, 40));
readCommand = F("RT,");
double temperatureReading;
ESPEASY_RULES_FLOAT_TYPE temperatureReading{};
if (Calculate(temperatureString, temperatureReading) != CalculateReturnCode::OK)
{
+3 -3
View File
@@ -75,7 +75,7 @@ const __FlashStringHelper * Command_Rules_Let(struct EventStruct *event, const c
if (GetArgv(Line, TmpStr1, 3)) {
if (event->Par1 >= 0) {
double result = 0.0;
ESPEASY_RULES_FLOAT_TYPE result{};
if (!isError(Calculate(TmpStr1, result))) {
setCustomFloatVar(event->Par1, result);
@@ -86,10 +86,10 @@ const __FlashStringHelper * Command_Rules_Let(struct EventStruct *event, const c
return return_command_failed();
}
const __FlashStringHelper * Command_Rules_IncDec(struct EventStruct *event, const char *Line, const double factor)
const __FlashStringHelper * Command_Rules_IncDec(struct EventStruct *event, const char *Line, const ESPEASY_RULES_FLOAT_TYPE factor)
{
String TmpStr1;
double result = 1.0;
ESPEASY_RULES_FLOAT_TYPE result = 1;
if (GetArgv(Line, TmpStr1, 3) && isError(Calculate(TmpStr1, result))) {
return return_command_failed();
+1 -1
View File
@@ -131,7 +131,7 @@ const __FlashStringHelper * taskValueSet(struct EventStruct *event, const char *
// FIXME TD-er: Must check if the value has to be computed and not convert to double when sensor type is 64 bit int.
// Perform calculation with float result.
double result = 0;
ESPEASY_RULES_FLOAT_TYPE result{};
if (isError(Calculate(TmpStr1, result))) {
success = false;
+17 -1
View File
@@ -2911,7 +2911,7 @@ To create/register a plugin, you have to :
// Extra task value types, typically used in Dummy tasks.
// For example 32-bit, 64-bit ints and doubles.
#ifndef FEATURE_EXTENDED_TASK_VALUE_TYPES
#ifdef ESP8266_1M
#ifdef LIMIT_BUILD_SIZE
#define FEATURE_EXTENDED_TASK_VALUE_TYPES 0
#else
#define FEATURE_EXTENDED_TASK_VALUE_TYPES 1
@@ -2931,5 +2931,21 @@ To create/register a plugin, you have to :
#endif
#endif
#ifndef ESPEASY_RULES_FLOAT_TYPE
#if defined(ESP8266) && defined(LIMIT_BUILD_SIZE)
#ifdef FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
#undef FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
#define FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE 0
#endif
#define ESPEASY_RULES_FLOAT_TYPE float
#else
#ifdef FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
#undef FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
#define FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE 1
#endif
#define ESPEASY_RULES_FLOAT_TYPE double
#endif
#endif
#endif // CUSTOMBUILD_DEFINE_PLUGIN_SETS_H
+1 -1
View File
@@ -238,7 +238,7 @@ bool Modbus::hasTimeout()
// tryread can be called in a round robin fashion. It will initiate a read if Modbus is idle and update the result once it is available.
// subsequent calls (if Modbus is busy etc. ) will return false and not update the result.
// Use to read multiple values non blocking in an re-entrant function. Not tested yet.
bool Modbus::tryRead(uint8_t ModbusID, uint16_t M_register, MODBUS_registerTypes_t type, char *IPaddress, double& result) {
bool Modbus::tryRead(uint8_t ModbusID, uint16_t M_register, MODBUS_registerTypes_t type, char *IPaddress, ESPEASY_RULES_FLOAT_TYPE& result) {
if (isBusy()) { return false; // not done yet
}
+19 -19
View File
@@ -21,7 +21,7 @@ public:
uint16_t ModbusRegister,
MODBUS_registerTypes_t type,
char *IPaddress);
double read() {
ESPEASY_RULES_FLOAT_TYPE read() {
if (resultReceived) {
resultReceived = false;
return result;
@@ -48,34 +48,34 @@ public:
handle();
}
bool tryRead(uint8_t ModbusID,
uint16_t M_register,
MODBUS_registerTypes_t type,
char *IPaddress,
double & result);
bool tryRead(uint8_t ModbusID,
uint16_t M_register,
MODBUS_registerTypes_t type,
char *IPaddress,
ESPEASY_RULES_FLOAT_TYPE& result);
private:
WiFiClient *ModbusClient = nullptr; // pointer to tcp client
unsigned int errcnt = 0;
char sendBuffer[12] = { 0, 1, 0, 0, 0, 6, 0x7e, 4, 0x9d, 7, 0, 1 };
#ifndef BUILD_NO_DEBUG
String LogString; // for debug logging
#endif
unsigned long timeout = 0; // send and read timeout
MODBUS_states_t TXRXstate = MODBUS_IDLE; // state for handle() state machine
unsigned int RXavailable = 0;
unsigned int payLoad = 0; // number of bytes to receive as payload. Payload may come as seperate frame.
WiFiClient *ModbusClient = nullptr; // pointer to tcp client
unsigned int errcnt = 0;
char sendBuffer[12] = { 0, 1, 0, 0, 0, 6, 0x7e, 4, 0x9d, 7, 0, 1 };
# ifndef BUILD_NO_DEBUG
String LogString; // for debug logging
# endif // ifndef BUILD_NO_DEBUG
unsigned long timeout = 0; // send and read timeout
MODBUS_states_t TXRXstate = MODBUS_IDLE; // state for handle() state machine
unsigned int RXavailable = 0;
unsigned int payLoad = 0; // number of bytes to receive as payload. Payload may come as seperate frame.
bool hasTimeout();
MODBUS_registerTypes_t incomingValue = signed16; // how to interpret the incoming value
double result = 0.0; // incoming value, converted to double
bool resultReceived = false; // incoming value is valid ?
ESPEASY_RULES_FLOAT_TYPE result{}; // incoming value, converted to ESPEASY_RULES_FLOAT_TYPE
bool resultReceived = false; // incoming value is valid ?
bool isBusy(void) {
return TXRXstate != MODBUS_IDLE;
}
uint16_t currentRegister = 0;
uint8_t currentFunction = 0;
uint8_t currentFunction = 0;
};
+1 -1
View File
@@ -304,7 +304,7 @@ bool PluginStats::webformLoad_show_peaks(struct EventStruct *event, bool include
void PluginStats::webformLoad_show_val(
struct EventStruct *event,
const String & label,
double value,
ESPEASY_RULES_FLOAT_TYPE value,
const String & unit) const
{
addRowLabel(getLabel() + label);
+1 -1
View File
@@ -107,7 +107,7 @@ public:
void webformLoad_show_val(
struct EventStruct *event,
const String & label,
double value,
ESPEASY_RULES_FLOAT_TYPE value,
const String & unit) const;
+4 -4
View File
@@ -156,7 +156,7 @@ void UserVarStruct::setFloat(taskIndex_t taskIndex,
}
#if FEATURE_EXTENDED_TASK_VALUE_TYPES
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
double UserVarStruct::getDouble(taskIndex_t taskIndex,
uint8_t varNr) const
{
@@ -174,10 +174,10 @@ void UserVarStruct::setDouble(taskIndex_t taskIndex,
_data[taskIndex].setDouble(varNr, value);
}
}
#endif
#endif // if FEATURE_EXTENDED_TASK_VALUE_TYPES
double UserVarStruct::getAsDouble(taskIndex_t taskIndex,
ESPEASY_RULES_FLOAT_TYPE UserVarStruct::getAsDouble(taskIndex_t taskIndex,
uint8_t varNr,
Sensor_VType sensorType) const
{
@@ -195,7 +195,7 @@ String UserVarStruct::getAsString(taskIndex_t taskIndex, uint8_t varNr, Sensor_V
return EMPTY_STRING;
}
void UserVarStruct::set(taskIndex_t taskIndex, uint8_t varNr, const double& value, Sensor_VType sensorType)
void UserVarStruct::set(taskIndex_t taskIndex, uint8_t varNr, const ESPEASY_RULES_FLOAT_TYPE& value, Sensor_VType sensorType)
{
if (taskIndex < _data.size()) {
_data[taskIndex].set(varNr, value, sensorType);
+4 -3
View File
@@ -65,16 +65,17 @@ struct UserVarStruct {
float value);
#if FEATURE_EXTENDED_TASK_VALUE_TYPES
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
// Double stored at the memory location of the float
double getDouble(taskIndex_t taskIndex,
uint8_t varNr) const;
void setDouble(taskIndex_t taskIndex,
uint8_t varNr,
double value);
#endif
#endif // if FEATURE_EXTENDED_TASK_VALUE_TYPES
double getAsDouble(taskIndex_t taskIndex,
ESPEASY_RULES_FLOAT_TYPE getAsDouble(taskIndex_t taskIndex,
uint8_t varNr,
Sensor_VType sensorType) const;
@@ -86,7 +87,7 @@ struct UserVarStruct {
void set(taskIndex_t taskIndex,
uint8_t varNr,
const double& value,
const ESPEASY_RULES_FLOAT_TYPE& value,
Sensor_VType sensorType);
bool isValid(taskIndex_t taskIndex,
@@ -48,9 +48,11 @@ Web_StreamingBuffer& Web_StreamingBuffer::operator+=(const float& a) {
return addString(toString(a, 2));
}
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
Web_StreamingBuffer& Web_StreamingBuffer::operator+=(const double& a) {
return addString(doubleToString(a));
}
#endif
Web_StreamingBuffer& Web_StreamingBuffer::operator+=(const String& a) {
return addString(a);
@@ -41,7 +41,9 @@ public:
Web_StreamingBuffer& operator+=(int64_t a);
Web_StreamingBuffer& operator+=(const float& a);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
Web_StreamingBuffer& operator+=(const double& a);
#endif
template <typename T>
Web_StreamingBuffer& operator+=(T a) {
+2 -2
View File
@@ -18,7 +18,7 @@ uint8_t getValueCountFromSensorType(Sensor_VType sensorType)
case Sensor_VType::SENSOR_TYPE_INT32_SINGLE: // 1x int32_t
case Sensor_VType::SENSOR_TYPE_UINT64_SINGLE: // 1x uint64_t
case Sensor_VType::SENSOR_TYPE_INT64_SINGLE: // 1x int64_t
case Sensor_VType::SENSOR_TYPE_DOUBLE_SINGLE: // 1x double
case Sensor_VType::SENSOR_TYPE_DOUBLE_SINGLE: // 1x ESPEASY_RULES_FLOAT_TYPE
#endif
case Sensor_VType::SENSOR_TYPE_SWITCH:
case Sensor_VType::SENSOR_TYPE_DIMMER:
@@ -33,7 +33,7 @@ uint8_t getValueCountFromSensorType(Sensor_VType sensorType)
case Sensor_VType::SENSOR_TYPE_INT32_DUAL: // 2x int32_t
case Sensor_VType::SENSOR_TYPE_UINT64_DUAL: // 2x uint64_t
case Sensor_VType::SENSOR_TYPE_INT64_DUAL: // 2x int64_t
case Sensor_VType::SENSOR_TYPE_DOUBLE_DUAL: // 2x double
case Sensor_VType::SENSOR_TYPE_DOUBLE_DUAL: // 2x ESPEASY_RULES_FLOAT_TYPE
#endif
return 2;
case Sensor_VType::SENSOR_TYPE_TEMP_HUM_BARO:
+12 -3
View File
@@ -138,7 +138,7 @@ void TaskValues_Data_t::setFloat(uint8_t varNr, float value)
}
#if FEATURE_EXTENDED_TASK_VALUE_TYPES
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
double TaskValues_Data_t::getDouble(uint8_t varNr) const
{
if ((varNr < (VARS_PER_TASK / 2))) {
@@ -154,8 +154,9 @@ void TaskValues_Data_t::setDouble(uint8_t varNr, double value)
}
}
#endif
#endif
double TaskValues_Data_t::getAsDouble(uint8_t varNr, Sensor_VType sensorType) const
ESPEASY_RULES_FLOAT_TYPE TaskValues_Data_t::getAsDouble(uint8_t varNr, Sensor_VType sensorType) const
{
if (sensorType == Sensor_VType::SENSOR_TYPE_ULONG) {
return getSensorTypeLong();
@@ -170,14 +171,16 @@ double TaskValues_Data_t::getAsDouble(uint8_t varNr, Sensor_VType sensorType) co
return getUint64(varNr);
} else if (isInt64OutputDataType(sensorType)) {
return getInt64(varNr);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
} else if (isDoubleOutputDataType(sensorType)) {
return getDouble(varNr);
#endif
#endif
}
return 0.0;
}
void TaskValues_Data_t::set(uint8_t varNr, const double& value, Sensor_VType sensorType)
void TaskValues_Data_t::set(uint8_t varNr, const ESPEASY_RULES_FLOAT_TYPE& value, Sensor_VType sensorType)
{
if (sensorType == Sensor_VType::SENSOR_TYPE_ULONG) {
// Legacy formatting the old "SENSOR_TYPE_ULONG" type
@@ -193,8 +196,10 @@ void TaskValues_Data_t::set(uint8_t varNr, const double& value, Sensor_VType sen
setUint64(varNr, value);
} else if (isInt64OutputDataType(sensorType)) {
setInt64(varNr, value);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
} else if (isDoubleOutputDataType(sensorType)) {
setDouble(varNr, value);
#endif
#endif
}
}
@@ -206,8 +211,10 @@ bool TaskValues_Data_t::isValid(uint8_t varNr, Sensor_VType sensorType) const
} else if (isFloatOutputDataType(sensorType)) {
return isValidFloat(getFloat(varNr));
#if FEATURE_EXTENDED_TASK_VALUE_TYPES
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
} else if (isDoubleOutputDataType(sensorType)) {
return isValidDouble(getDouble(varNr));
#endif
#endif
}
return true;
@@ -220,8 +227,10 @@ String TaskValues_Data_t::getAsString(uint8_t varNr, Sensor_VType sensorType, u
if (isFloatOutputDataType(sensorType)) {
result = toString(getFloat(varNr), nrDecimals);
#if FEATURE_EXTENDED_TASK_VALUE_TYPES
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
} else if (isDoubleOutputDataType(sensorType)) {
result = doubleToString(getDouble(varNr), nrDecimals);
#endif
#endif
} else if (sensorType == Sensor_VType::SENSOR_TYPE_ULONG) {
return String(getSensorTypeLong());
+6 -3
View File
@@ -45,18 +45,19 @@ struct TaskValues_Data_t {
float value);
#if FEATURE_EXTENDED_TASK_VALUE_TYPES
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
double getDouble(uint8_t varNr) const;
void setDouble(uint8_t varNr,
double value);
#endif
#endif
// Interpret the data according to the given sensorType
double getAsDouble(uint8_t varNr,
ESPEASY_RULES_FLOAT_TYPE getAsDouble(uint8_t varNr,
Sensor_VType sensorType) const;
void set(uint8_t varNr,
const double& value,
const ESPEASY_RULES_FLOAT_TYPE& value,
Sensor_VType sensorType);
bool isValid(uint8_t varNr,
@@ -73,7 +74,9 @@ struct TaskValues_Data_t {
int32_t int32s[VARS_PER_TASK];
uint64_t uint64s[VARS_PER_TASK / 2];
int64_t int64s[VARS_PER_TASK / 2];
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
double doubles[VARS_PER_TASK / 2];
#endif
#endif
};
};
+1 -1
View File
@@ -675,7 +675,7 @@ void SensorSendTask(struct EventStruct *event, unsigned long timestampUnixTime,
// See: https://github.com/letscontrolit/ESPEasy/issues/3721#issuecomment-889649437
formula.replace(F("%pvalue%"), preValue[varNr]);
formula.replace(F("%value%"), formatUserVarNoCheck(&TempEvent, varNr));
double result = 0;
ESPEASY_RULES_FLOAT_TYPE result{};
if (!isError(Calculate(parseTemplate(formula), result))) {
UserVar.set(event->TaskIndex, varNr, result, TempEvent.sensorType);
+22 -8
View File
@@ -424,8 +424,8 @@ bool parse_bitwise_functions(const String& cmd_s_lower, const String& arg1, cons
return true;
}
bool parse_math_functions(const String& cmd_s_lower, const String& arg1, const String& arg2, const String& arg3, double& result) {
double farg1;
bool parse_math_functions(const String& cmd_s_lower, const String& arg1, const String& arg2, const String& arg3, ESPEASY_RULES_FLOAT_TYPE& result) {
ESPEASY_RULES_FLOAT_TYPE farg1;
float farg2, farg3 = 0.0f;
if (!validDoubleFromString(arg1, farg1)) {
@@ -486,7 +486,7 @@ void parse_string_commands(String& line) {
if (cmd_s_lower.length() > 0) {
String replacement; // maybe just replace with empty to avoid looping?
uint64_t iarg1, iarg2 = 0;
double fresult = 0.0;
ESPEASY_RULES_FLOAT_TYPE fresult{};
int64_t iresult = 0;
int startpos, endpos = -1;
const bool arg1valid = validIntFromString(arg1, startpos);
@@ -494,7 +494,11 @@ void parse_string_commands(String& line) {
if (parse_math_functions(cmd_s_lower, arg1, arg2, arg3, fresult)) {
const bool trimTrailingZeros = true;
replacement = doubleToString(fresult, maxNrDecimals_double(fresult), trimTrailingZeros);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
replacement = doubleToString(fresult, maxNrDecimals_fpType(fresult), trimTrailingZeros);
#else
replacement = floatToString(fresult, maxNrDecimals_fpType(fresult), trimTrailingZeros);
#endif
} else if (parse_bitwise_functions(cmd_s_lower, arg1, arg2, arg3, iresult)) {
replacement = ull2String(iresult);
} else {
@@ -1209,8 +1213,8 @@ bool conditionMatch(const String& check) {
tmpCheck1.trim();
tmpCheck2.trim();
double Value1 = 0;
double Value2 = 0;
ESPEASY_RULES_FLOAT_TYPE Value1{};
ESPEASY_RULES_FLOAT_TYPE Value2{};
int timeInSec1 = 0;
int timeInSec2 = 0;
@@ -1267,9 +1271,19 @@ bool conditionMatch(const String& check) {
log += '(';
const bool trimTrailingZeros = true;
log += compareTimes ? String(timeInSec1) : doubleToString(Value1, 6, trimTrailingZeros);
log += compareTimes ? String(timeInSec1) :
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
doubleToString(Value1, 6, trimTrailingZeros);
#else
floatToString(Value1, 6, trimTrailingZeros);
#endif
log += wrap_String(check.substring(posStart, posEnd), ' '); // Compare
log += compareTimes ? String(timeInSec2) : doubleToString(Value2, 6, trimTrailingZeros);
log += compareTimes ? String(timeInSec2) :
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
doubleToString(Value2, 6, trimTrailingZeros);
#else
floatToString(Value2, 6, trimTrailingZeros);
#endif
log += ')';
addLogMove(LOG_LEVEL_DEBUG, log);
}
+1 -1
View File
@@ -61,7 +61,7 @@ bool parse_math_functions(const String& cmd_s_lower,
const String& arg1,
const String& arg2,
const String& arg3,
double & result);
ESPEASY_RULES_FLOAT_TYPE & result);
void parse_string_commands(String& line);
+6 -2
View File
@@ -17,7 +17,7 @@ int CalculateParam(const String& TmpStr) {
if (TmpStr[0] != '=') {
validIntFromString(TmpStr, returnValue);
} else {
double param = 0;
ESPEASY_RULES_FLOAT_TYPE param{};
// Starts with an '=', so Calculate starting at next position
CalculateReturnCode returnCode = Calculate(TmpStr.substring(1), param);
@@ -40,7 +40,7 @@ int CalculateParam(const String& TmpStr) {
}
CalculateReturnCode Calculate(const String& input,
double & result)
ESPEASY_RULES_FLOAT_TYPE & result)
{
START_TIMER;
CalculateReturnCode returnCode = RulesCalculate.doCalculate(
@@ -78,7 +78,11 @@ CalculateReturnCode Calculate(const String& input,
log += F(" = ");
const bool trimTrailingZeros = true;
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
log += doubleToString(result, 6, trimTrailingZeros);
#else
log += floatToString(result, 6, trimTrailingZeros);
#endif
#endif // ifndef BUILD_NO_DEBUG
addLogMove(LOG_LEVEL_ERROR, log);
+1 -1
View File
@@ -20,7 +20,7 @@ extern RulesCalculate_t RulesCalculate;
int CalculateParam(const String& TmpStr);
CalculateReturnCode Calculate(const String& input,
double & result);
ESPEASY_RULES_FLOAT_TYPE & result);
+4 -4
View File
@@ -1,14 +1,14 @@
#include "../Globals/RuntimeData.h"
std::map<uint32_t, double> customFloatVar;
std::map<uint32_t, ESPEASY_RULES_FLOAT_TYPE> customFloatVar;
//float UserVar[VARS_PER_TASK * TASKS_MAX];
UserVarStruct UserVar;
double getCustomFloatVar(uint32_t index) {
ESPEASY_RULES_FLOAT_TYPE getCustomFloatVar(uint32_t index) {
auto it = customFloatVar.find(index);
if (it != customFloatVar.end()) {
@@ -17,11 +17,11 @@ double getCustomFloatVar(uint32_t index) {
return 0.0;
}
void setCustomFloatVar(uint32_t index, const double& value) {
void setCustomFloatVar(uint32_t index, const ESPEASY_RULES_FLOAT_TYPE& value) {
customFloatVar[index] = value;
}
bool getNextCustomFloatVar(uint32_t& index, double& value) {
bool getNextCustomFloatVar(uint32_t& index, ESPEASY_RULES_FLOAT_TYPE& value) {
auto it = customFloatVar.find(index);
if (it == customFloatVar.end()) { return false; }
+4 -4
View File
@@ -17,12 +17,12 @@
* let,1,10
* if %v1%=10 do ...
\*********************************************************************************************/
extern std::map<uint32_t, double> customFloatVar;
extern std::map<uint32_t, ESPEASY_RULES_FLOAT_TYPE> customFloatVar;
double getCustomFloatVar(uint32_t index);
void setCustomFloatVar(uint32_t index, const double& value);
ESPEASY_RULES_FLOAT_TYPE getCustomFloatVar(uint32_t index);
void setCustomFloatVar(uint32_t index, const ESPEASY_RULES_FLOAT_TYPE& value);
bool getNextCustomFloatVar(uint32_t& index, double& value);
bool getNextCustomFloatVar(uint32_t& index, ESPEASY_RULES_FLOAT_TYPE& value);
/*********************************************************************************************\
+101 -7
View File
@@ -5,14 +5,15 @@
// See: https://github.com/esp8266/Arduino/issues/8922#issuecomment-1542301697
#include <cmath>
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
double ESPEASY_DOUBLE_EPSILON = ESPEASY_DOUBLE_EPSILON_FACTOR * std::numeric_limits<double>::epsilon();
double ESPEASY_DOUBLE_EPSILON_NEG = -1.0 * ESPEASY_DOUBLE_EPSILON_FACTOR * std::numeric_limits<double>::epsilon();
#endif
float ESPEASY_FLOAT_EPSILON = std::numeric_limits<float>::epsilon();
float ESPEASY_FLOAT_EPSILON_NEG = -1.0f * std::numeric_limits<float>::epsilon();
int maxNrDecimals_double(const double& value)
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
int maxNrDecimals_fpType(const double& value)
{
int res = ESPEASY_DOUBLE_NR_DECIMALS;
double factor = 1;
@@ -23,91 +24,184 @@ int maxNrDecimals_double(const double& value)
}
return res;
}
#endif
int maxNrDecimals_fpType(const float& value)
{
int res = ESPEASY_FLOAT_NR_DECIMALS;
float factor = 1;
while ((value / factor) > 10 && res > 2) {
factor *= 10.0f;
--res;
}
return res;
}
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool approximatelyEqual(const double& a, const double& b) {
return approximatelyEqual(a, b, ESPEASY_DOUBLE_EPSILON);
}
#endif
bool approximatelyEqual(const float& a, const float& b) {
return approximatelyEqual(a, b, ESPEASY_FLOAT_EPSILON);
}
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool approximatelyEqual(const double& a, const double& b, double epsilon)
{
return std::abs(a - b) <= ((std::abs(a) < std::abs(b) ? std::abs(b) : std::abs(a)) * epsilon);
}
#endif
bool approximatelyEqual(const float& a, const float& b, float epsilon)
{
return std::abs(a - b) <= ((std::abs(a) < std::abs(b) ? std::abs(b) : std::abs(a)) * epsilon);
}
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool definitelyGreaterThan(const double& a, const double& b) {
return definitelyGreaterThan(a, b, ESPEASY_DOUBLE_EPSILON);
}
#endif
bool definitelyGreaterThan(const float& a, const float& b) {
return definitelyGreaterThan(a, b, ESPEASY_FLOAT_EPSILON);
}
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool definitelyGreaterThan(const double& a, const double& b, double epsilon)
{
return (a - b) > ((std::abs(a) < std::abs(b) ? std::abs(b) : std::abs(a)) * epsilon);
}
#endif
bool definitelyGreaterThan(const float& a, const float& b, float epsilon)
{
return (a - b) > ((std::abs(a) < std::abs(b) ? std::abs(b) : std::abs(a)) * epsilon);
}
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool definitelyLessThan(const double& a, const double& b) {
return definitelyLessThan(a, b, ESPEASY_DOUBLE_EPSILON);
}
#endif
bool definitelyLessThan(const float& a, const float& b) {
return definitelyLessThan(a, b, ESPEASY_FLOAT_EPSILON);
}
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool definitelyLessThan(const double& a, const double& b, double epsilon)
{
return (b - a) > ((std::abs(a) < std::abs(b) ? std::abs(b) : std::abs(a)) * epsilon);
}
#endif
bool definitelyLessThan(const float& a, const float& b, float epsilon)
{
return (b - a) > ((std::abs(a) < std::abs(b) ? std::abs(b) : std::abs(a)) * epsilon);
}
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool essentiallyEqual(const double& a, const double& b) {
return essentiallyEqual(a, b, ESPEASY_DOUBLE_EPSILON);
}
#endif
bool essentiallyEqual(const float& a, const float& b) {
return essentiallyEqual(a, b, ESPEASY_FLOAT_EPSILON);
}
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool essentiallyEqual(const double& a, const double& b, double epsilon)
{
return std::abs(a - b) <= ((std::abs(a) > std::abs(b) ? std::abs(b) : std::abs(a)) * epsilon);
}
#endif
bool essentiallyEqual(const float& a, const float& b, float epsilon)
{
return std::abs(a - b) <= ((std::abs(a) > std::abs(b) ? std::abs(b) : std::abs(a)) * epsilon);
}
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool essentiallyZero(const double& a)
{
return ESPEASY_DOUBLE_EPSILON_NEG <= a &&
a <= ESPEASY_DOUBLE_EPSILON;
}
#endif
bool essentiallyZero(const float& a)
{
return ESPEASY_FLOAT_EPSILON_NEG <= a &&
a <= ESPEASY_FLOAT_EPSILON;
}
/*========================================================================*/
/* Functions that would otherwise duplicate code */
/* For example due to being implemented as macros */
/* Or duplications as it is being implemented both for double and float */
/*========================================================================*/
float powf(const float x, const float y)
{
return (float)(pow((double)x, (double)y));
}
float ceilf(const float x)
{
return (float)(ceil((double)x));
}
float floorf(const float x)
{
return (float)(floor((double)x));
}
float fabsf(const float x)
{
return (float)(fabs((double)x));
}
float acosf(const float x)
{
return (float)(acos((double)x));
}
float cosf(const float x)
{
return (float)(cos((double)x));
}
float asinf(const float x)
{
return (float)(asin((double)x));
}
float sinf(const float x)
{
return (float)(sin((double)x));
}
float atanf(const float x)
{
return (float)(atan((double)x));
}
float tanf(const float x)
{
return (float)(tan((double)x));
}
float sqrtf(const float x)
{
return (float)(sqrt((double)x));
}
float roundf(const float x)
{
return (float)(round((double)x));
}
+45 -1
View File
@@ -7,33 +7,77 @@
// Internal ESPEasy representation of double values
#define ESPEASY_DOUBLE_NR_DECIMALS 14
#define ESPEASY_DOUBLE_EPSILON_FACTOR 1000
#define ESPEASY_FLOAT_NR_DECIMALS 6
#define ESPEASY_FLOAT_EPSILON_FACTOR 1000
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
int maxNrDecimals_fpType(const double& value);
#endif
int maxNrDecimals_fpType(const float& value);
int maxNrDecimals_double(const double& value);
// The following definitions are from The art of computer programming by Knuth
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool approximatelyEqual(const double& a, const double& b);
#endif
bool approximatelyEqual(const float& a, const float& b);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool approximatelyEqual(const double& a, const double& b, double epsilon);
#endif
bool approximatelyEqual(const float& a, const float& b, float epsilon);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool definitelyGreaterThan(const double& a, const double& b);
#endif
bool definitelyGreaterThan(const float& a, const float& b);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool definitelyGreaterThan(const double& a, const double& b, double epsilon);
#endif
bool definitelyGreaterThan(const float& a, const float& b, float epsilon);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool definitelyLessThan(const double& a, const double& b);
#endif
bool definitelyLessThan(const float& a, const float& b);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool definitelyLessThan(const double& a, const double& b, double epsilon);
#endif
bool definitelyLessThan(const float& a, const float& b, float epsilon);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool essentiallyEqual(const double& a, const double& b);
#endif
bool essentiallyEqual(const float& a, const float& b);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool essentiallyEqual(const double& a, const double& b, double epsilon);
#endif
bool essentiallyEqual(const float& a, const float& b, float epsilon);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool essentiallyZero(const double& a);
#endif
bool essentiallyZero(const float& a);
/*========================================================================*/
/* Functions that would otherwise duplicate code */
/* For example due to being implemented as macros */
/* Or duplications as it is being implemented both for double and float */
/* Another factor is that converting from double to float on each call */
/* also adds up */
/*========================================================================*/
float powf(const float x, const float y);
float ceilf(const float x);
float floorf(const float x);
float fabsf(const float x);
float acosf(const float x);
float cosf(const float x);
float asinf(const float x);
float sinf(const float x);
float atanf(const float x);
float tanf(const float x);
float sqrtf(const float x);
float roundf(const float x);
#endif // HELPERS_ESPEASY_MATH_H
+8 -4
View File
@@ -263,14 +263,18 @@ unsigned long ESPEasy_time::now() {
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
String log = F("Time set to ");
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
log += doubleToString(unixTime_d, 3);
#else
log += static_cast<uint32_t>(unixTime_d);
#endif
if ((-86400 < time_offset) && (time_offset < 86400)) {
// Only useful to show adjustment if it is less than a day.
log += F(" Time adjusted by ");
log += doubleToString(time_offset * 1000.0);
log += static_cast<uint32_t>(time_offset * 1000.0);
log += F(" msec. Wander: ");
log += doubleToString(timeWander, 1);
log += floatToString(timeWander, 1);
log += F(" ppm");
log += F(" Source: ");
log += toString(timeSource);
@@ -528,8 +532,8 @@ bool ESPEasy_time::getNtpTime(double& unixTime_d)
// We gained more than 1 second in accuracy
fractpart += 1.0;
}
log += doubleToString(fractpart, 3);
log += F(" seconds");
log += static_cast<int>(fractpart * 1000.0);
log += F(" msec");
addLogMove(LOG_LEVEL_INFO, log);
}
udp.stop();
+6 -6
View File
@@ -10,7 +10,7 @@ bool isValidFloat(float f) {
return !isnan(f) && !isinf(f);
}
bool isValidDouble(double f) {
bool isValidDouble(ESPEASY_RULES_FLOAT_TYPE f) {
return !isnan(f) && !isinf(f);
}
@@ -97,8 +97,8 @@ bool validUInt64FromString(const String& tBuf, uint64_t& result) {
bool validFloatFromString(const String& tBuf, float& result) {
// DO not call validDoubleFromString and then cast to float.
// Working with double values is quite CPU intensive as it must be done in software
// since the ESP does not have large enough registers for handling double values in hardware.
// Working with ESPEASY_RULES_FLOAT_TYPE values is quite CPU intensive as it must be done in software
// since the ESP does not have large enough registers for handling ESPEASY_RULES_FLOAT_TYPE values in hardware.
NumericalType detectedType;
const String numerical = getNumerical(tBuf, NumericalType::FloatingPoint, detectedType);
@@ -118,7 +118,7 @@ bool validFloatFromString(const String& tBuf, float& result) {
return isvalid;
}
bool validDoubleFromString(const String& tBuf, double& result) {
bool validDoubleFromString(const String& tBuf, ESPEASY_RULES_FLOAT_TYPE& result) {
#if defined(CORE_POST_2_5_0) || defined(ESP32)
// String.toDouble() is introduced in core 2.5.0
@@ -129,7 +129,7 @@ bool validDoubleFromString(const String& tBuf, double& result) {
(detectedType == NumericalType::HexadecimalUInt)) {
uint64_t tmp;
bool isvalid = validUInt64FromString(tBuf, tmp);
result = static_cast<double>(tmp);
result = static_cast<ESPEASY_RULES_FLOAT_TYPE>(tmp);
return isvalid;
}
@@ -142,7 +142,7 @@ bool validDoubleFromString(const String& tBuf, double& result) {
#else // if defined(CORE_POST_2_5_0) || defined(ESP32)
float tmp = static_cast<float>(result);
bool res = validFloatFromString(tBuf, tmp);
result = static_cast<double>(tmp);
result = static_cast<ESPEASY_RULES_FLOAT_TYPE>(tmp);
return res;
#endif // if defined(CORE_POST_2_5_0) || defined(ESP32)
}
+2 -2
View File
@@ -8,7 +8,7 @@
\*********************************************************************************************/
bool isValidFloat(float f);
bool isValidDouble(double f);
bool isValidDouble(ESPEASY_RULES_FLOAT_TYPE f);
bool validIntFromString(const String& tBuf, int& result);
@@ -20,7 +20,7 @@ bool validUInt64FromString(const String& tBuf, uint64_t& result);
bool validFloatFromString(const String& tBuf, float& result);
bool validDoubleFromString(const String& tBuf, double& result);
bool validDoubleFromString(const String& tBuf, ESPEASY_RULES_FLOAT_TYPE& result);
// Numerical types sorted from least specific to most specific.
enum class NumericalType {
+3 -3
View File
@@ -72,7 +72,7 @@ bool ruleMatch(String event, String rule) {
// parse event into verb and value
double value = 0;
ESPEASY_RULES_FLOAT_TYPE value{};
int equal_pos = event.indexOf('=');
if (equal_pos >= 0) {
@@ -94,7 +94,7 @@ bool ruleMatch(String event, String rule) {
}
const bool stringMatch = event.equalsIgnoreCase(rule.substring(0, posStart));
double ruleValue = 0;
ESPEASY_RULES_FLOAT_TYPE ruleValue{};
if (!validDoubleFromString(rule.substring(posEnd), ruleValue)) {
return false;
@@ -126,7 +126,7 @@ bool compareIntValues(char compare, const int& Value1, const int& Value2)
return false;
}
bool compareDoubleValues(char compare, const double& Value1, const double& Value2)
bool compareDoubleValues(char compare, const ESPEASY_RULES_FLOAT_TYPE& Value1, const ESPEASY_RULES_FLOAT_TYPE& Value2)
{
switch (compare) {
case '>' + '=': return !definitelyLessThan(Value1, Value2);
+2 -2
View File
@@ -16,8 +16,8 @@ bool compareIntValues(char compare,
const int& Value2);
bool compareDoubleValues(char compare,
const double& Value1,
const double& Value2);
const ESPEASY_RULES_FLOAT_TYPE& Value1,
const ESPEASY_RULES_FLOAT_TYPE& Value2);
bool findCompareCondition(const String& check,
char & compare,
+72 -12
View File
@@ -71,7 +71,7 @@ bool RulesCalculate_t::is_unary_operator(char c)
*/
}
CalculateReturnCode RulesCalculate_t::push(double value)
CalculateReturnCode RulesCalculate_t::push(ESPEASY_RULES_FLOAT_TYPE value)
{
if (sp != sp_max) // Full
{
@@ -81,7 +81,7 @@ CalculateReturnCode RulesCalculate_t::push(double value)
return CalculateReturnCode::ERROR_STACK_OVERFLOW;
}
double RulesCalculate_t::pop()
ESPEASY_RULES_FLOAT_TYPE RulesCalculate_t::pop()
{
if (sp != (globalstack - 1)) { // empty
return *(sp--);
@@ -91,7 +91,7 @@ double RulesCalculate_t::pop()
}
}
double RulesCalculate_t::apply_operator(char op, double first, double second)
ESPEASY_RULES_FLOAT_TYPE RulesCalculate_t::apply_operator(char op, ESPEASY_RULES_FLOAT_TYPE first, ESPEASY_RULES_FLOAT_TYPE second)
{
switch (op)
{
@@ -104,36 +104,72 @@ double RulesCalculate_t::apply_operator(char op, double first, double second)
case '/':
return first / second;
case '%':
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
return static_cast<int>(round(first)) % static_cast<int>(round(second));
#else
return static_cast<int>(roundf(first)) % static_cast<int>(roundf(second));
#endif
case '^':
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
return pow(first, second);
#else
return powf(first, second);
#endif
default:
return 0.0;
return 0;
}
}
double RulesCalculate_t::apply_unary_operator(char op, double first)
ESPEASY_RULES_FLOAT_TYPE RulesCalculate_t::apply_unary_operator(char op, ESPEASY_RULES_FLOAT_TYPE first)
{
double ret = 0.0;
ESPEASY_RULES_FLOAT_TYPE ret{};
const UnaryOperator un_op = static_cast<UnaryOperator>(op);
switch (un_op) {
case UnaryOperator::Not:
return essentiallyZero(roundf(first)) ? 1.0 : 0.0;
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
return essentiallyZero(round(first)) ? 1 : 0;
#else
return essentiallyZero(roundf(first)) ? 1 : 0;
#endif
case UnaryOperator::Log:
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
return log10(first);
#else
return log10f(first);
#endif
case UnaryOperator::Ln:
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
return log(first);
#else
return logf(first);
#endif
case UnaryOperator::Abs:
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
return fabs(first);
#else
return fabs(first);
#endif
case UnaryOperator::Exp:
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
return exp(first);
#else
return expf(first);
#endif
case UnaryOperator::Sqrt:
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
return sqrt(first);
#else
return sqrtf(first);
#endif
case UnaryOperator::Sq:
return first * first;
case UnaryOperator::Round:
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
return round(first);
#else
return roundf(first);
#endif
default:
break;
}
@@ -145,15 +181,27 @@ double RulesCalculate_t::apply_unary_operator(char op, double first)
switch (un_op) {
case UnaryOperator::ArcSin:
case UnaryOperator::ArcSin_d:
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
ret = asin(first);
#else
ret = asinf(first);
#endif
return useDegree ? degrees(ret) : ret;
case UnaryOperator::ArcCos:
case UnaryOperator::ArcCos_d:
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
ret = acos(first);
#else
ret = acosf(first);
#endif
return useDegree ? degrees(ret) : ret;
case UnaryOperator::ArcTan:
case UnaryOperator::ArcTan_d:
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
ret = atan(first);
#else
ret = atanf(first);
#endif
return useDegree ? degrees(ret) : ret;
default:
break;
@@ -167,13 +215,25 @@ double RulesCalculate_t::apply_unary_operator(char op, double first)
switch (un_op) {
case UnaryOperator::Sin:
case UnaryOperator::Sin_d:
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
return sin(first);
#else
return sinf(first);
#endif
case UnaryOperator::Cos:
case UnaryOperator::Cos_d:
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
return cos(first);
#else
return cosf(first);
#endif
case UnaryOperator::Tan:
case UnaryOperator::Tan_d:
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
return tan(first);
#else
return tanf(first);
#endif
default:
break;
}
@@ -220,8 +280,8 @@ CalculateReturnCode RulesCalculate_t::RPNCalculate(char *token)
if (is_operator(token[0]) && (token[1] == 0))
{
double second = pop();
double first = pop();
ESPEASY_RULES_FLOAT_TYPE second = pop();
ESPEASY_RULES_FLOAT_TYPE first = pop();
ret = push(apply_operator(token[0], first, second));
@@ -229,7 +289,7 @@ CalculateReturnCode RulesCalculate_t::RPNCalculate(char *token)
// if (isError(ret)) { return ret; }
} else if (is_unary_operator(token[0]) && (token[1] == 0))
{
double first = pop();
ESPEASY_RULES_FLOAT_TYPE first = pop();
ret = push(apply_unary_operator(token[0], first));
@@ -237,7 +297,7 @@ CalculateReturnCode RulesCalculate_t::RPNCalculate(char *token)
// if (isError(ret)) { return ret; }
} else {
// Fetch next if there is any
double value = 0.0;
ESPEASY_RULES_FLOAT_TYPE value{};
validDoubleFromString(token, value);
ret = push(value); // If it is a value, push to the stack
@@ -295,7 +355,7 @@ unsigned int RulesCalculate_t::op_arg_count(const char c)
return 0;
}
CalculateReturnCode RulesCalculate_t::doCalculate(const char *input, double *result)
CalculateReturnCode RulesCalculate_t::doCalculate(const char *input, ESPEASY_RULES_FLOAT_TYPE *result)
{
#ifndef BUILD_NO_RAM_TRACKER
+11 -11
View File
@@ -60,9 +60,9 @@ const __FlashStringHelper* toString(UnaryOperator op);
class RulesCalculate_t {
private:
double globalstack[STACK_SIZE]{};
double *sp = globalstack - 1;
const double *sp_max = &globalstack[STACK_SIZE - 1];
ESPEASY_RULES_FLOAT_TYPE globalstack[STACK_SIZE]{};
ESPEASY_RULES_FLOAT_TYPE *sp = globalstack - 1;
const ESPEASY_RULES_FLOAT_TYPE *sp_max = &globalstack[STACK_SIZE - 1];
// Check if it matches part of a number (identifier)
// @param oc Previous character
@@ -74,16 +74,16 @@ private:
bool is_unary_operator(char c);
CalculateReturnCode push(double value);
CalculateReturnCode push(ESPEASY_RULES_FLOAT_TYPE value);
double pop();
ESPEASY_RULES_FLOAT_TYPE pop();
double apply_operator(char op,
double first,
double second);
ESPEASY_RULES_FLOAT_TYPE apply_operator(char op,
ESPEASY_RULES_FLOAT_TYPE first,
ESPEASY_RULES_FLOAT_TYPE second);
double apply_unary_operator(char op,
double first);
ESPEASY_RULES_FLOAT_TYPE apply_unary_operator(char op,
ESPEASY_RULES_FLOAT_TYPE first);
// char * next_token(char *linep);
@@ -105,7 +105,7 @@ public:
RulesCalculate_t();
CalculateReturnCode doCalculate(const char *input,
double *result);
ESPEASY_RULES_FLOAT_TYPE *result);
// Try to replace multi byte operators with single character ones.
// For example log, sin, cos, tan.
+47 -25
View File
@@ -31,7 +31,7 @@ String toString(const float& value, unsigned int decimalPlaces)
}
}
#endif // ifndef LIMIT_BUILD_SIZE
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
// This has been fixed in ESP32 code, not (yet) in ESP8266 code
// https://github.com/espressif/arduino-esp32/pull/6138/files
// #ifdef ESP8266
@@ -43,9 +43,9 @@ String toString(const float& value, unsigned int decimalPlaces)
String sValue(dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf));
free(buf);
// #else
// String sValue = String(value, decimalPlaces);
// #endif
#else
String sValue = String(value, decimalPlaces);
#endif
sValue.trim();
return sValue;
@@ -89,7 +89,33 @@ String ll2String(int64_t value, uint8_t base) {
}
}
String doubleToString(const double& value, unsigned int decimalPlaces, bool trimTrailingZeros) {
String trimTrailingZeros(const String& value) {
String res(value);
int dot_pos = res.lastIndexOf('.');
if (dot_pos != -1) {
bool someTrimmed = false;
for (int i = res.length() - 1; i > dot_pos && res[i] == '0'; --i) {
someTrimmed = true;
res[i] = ' ';
}
if (someTrimmed) {
res.trim();
}
if (res.endsWith(F("."))) {
res[dot_pos] = ' ';
res.trim();
}
}
return res;
}
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
String doubleToString(const double& value, unsigned int decimalPlaces, bool trimTrailingZeros_b) {
// This has been fixed in ESP32 code, not (yet) in ESP8266 code
// https://github.com/espressif/arduino-esp32/pull/6138/files
// #ifdef ESP8266
@@ -114,29 +140,25 @@ String doubleToString(const double& value, unsigned int decimalPlaces, bool trim
// #endif
res.trim();
if (trimTrailingZeros) {
int dot_pos = res.lastIndexOf('.');
if (dot_pos != -1) {
bool someTrimmed = false;
for (int i = res.length() - 1; i > dot_pos && res[i] == '0'; --i) {
someTrimmed = true;
res[i] = ' ';
}
if (someTrimmed) {
res.trim();
}
if (res.endsWith(F("."))) {
res[dot_pos] = ' ';
res.trim();
}
}
if (trimTrailingZeros_b) {
return trimTrailingZeros(res);
}
return res;
}
#endif
String floatToString(const float& value,
unsigned int decimalPlaces,
bool trimTrailingZeros_b)
{
const String res = toString(value, decimalPlaces);
if (trimTrailingZeros_b) {
return trimTrailingZeros(res);
}
return res;
}
/********************************************************************************************\
Check if valid float and convert string to float.
@@ -28,8 +28,16 @@ String ull2String(uint64_t value,
String ll2String(int64_t value,
uint8_t base = 10);
String trimTrailingZeros(const String& value);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
String doubleToString(const double& value,
unsigned int decimalPlaces = 2,
bool trimTrailingZeros = false);
#endif
String floatToString(const float& value,
unsigned int decimalPlaces = 2,
bool trimTrailingZeros = false);
#endif // ifndef HELPERS_STRINGCONVERTER_NUMERICAL_H
+18 -2
View File
@@ -80,7 +80,7 @@ String parseTemplate_padded(String& tmpString, uint8_t minimal_lineSize, bool us
unsigned int varNum;
if (validUIntFromString(valueName, varNum)) {
unsigned char nr_decimals = maxNrDecimals_double(getCustomFloatVar(varNum));
unsigned char nr_decimals = maxNrDecimals_fpType(getCustomFloatVar(varNum));
bool trimTrailingZeros = true;
if (devNameEqInt) {
@@ -90,7 +90,11 @@ String parseTemplate_padded(String& tmpString, uint8_t minimal_lineSize, bool us
// There is some formatting here, so do not throw away decimals
trimTrailingZeros = false;
}
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
String value = doubleToString(getCustomFloatVar(varNum), nr_decimals, trimTrailingZeros);
#else
String value = floatToString(getCustomFloatVar(varNum), nr_decimals, trimTrailingZeros);
#endif
transformValue(
newString,
minimal_lineSize,
@@ -332,7 +336,7 @@ void transformValue(
if (valueFormat.length() > 0) // do the checks only if a Format is defined to optimize loop
{
int logicVal = 0;
double valFloat = 0.0;
ESPEASY_RULES_FLOAT_TYPE valFloat{};
if (validDoubleFromString(value, valFloat))
{
@@ -428,7 +432,11 @@ void transformValue(
break;
}
bool trimTrailingZeros = false;
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
value = doubleToString(valFloat, y, trimTrailingZeros);
#else
value = floatToString(valFloat, y, trimTrailingZeros);
#endif
int indexDot = value.indexOf('.');
if (indexDot == -1) {
@@ -441,10 +449,18 @@ void transformValue(
break;
}
case 'F': // FLOOR (round down)
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
value = static_cast<int>(floor(valFloat));
#else
value = static_cast<int>(floorf(valFloat));
#endif
break;
case 'E': // CEILING (round up)
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
value = static_cast<int>(ceil(valFloat));
#else
value = static_cast<int>(ceilf(valFloat));
#endif
break;
default:
value = F("ERR");
+6 -2
View File
@@ -274,8 +274,12 @@ void SystemVariables::parseSystemVariables(String& s, boolean useURLencode)
key += '%';
if (s.indexOf(key) != -1) {
const bool trimTrailingZeros = true;
const String value = doubleToString(getCustomFloatVar(i), 6, trimTrailingZeros);
const bool trimTrailingZeros = true;
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
const String value = doubleToString(getCustomFloatVar(i), 6, trimTrailingZeros);
#else
const String value = floatToString(getCustomFloatVar(i), 6, trimTrailingZeros);
#endif
repl(key, value, s, useURLencode);
}
}
+20 -5
View File
@@ -269,13 +269,28 @@ void P002_data_struct::webformLoad(struct EventStruct *event)
addFormTextBox(F("query-input widenumber"),
label,
getPluginCustomArgName(varNr),
_multipoint.size() > line_nr ? doubleToString(static_cast<double>(_multipoint[line_nr]._adc), _nrDecimals,
true) : EMPTY_STRING,
_multipoint.size() > line_nr ?
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
doubleToString
#else
floatToString
#endif
(static_cast<ESPEASY_RULES_FLOAT_TYPE>(_multipoint[line_nr]._adc),
_nrDecimals,
true) : EMPTY_STRING,
0);
html_add_estimate_symbol();
addTextBox(getPluginCustomArgName(varNr + 1),
_multipoint.size() > line_nr ? doubleToString(static_cast<double>(_multipoint[line_nr]._value), _nrDecimals,
true) : EMPTY_STRING,
_multipoint.size() > line_nr ?
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
doubleToString
#else
floatToString
#endif
(static_cast<ESPEASY_RULES_FLOAT_TYPE>(_multipoint[line_nr]._value),
_nrDecimals,
true) : EMPTY_STRING,
0,
false,
false,
@@ -950,7 +965,7 @@ int P002_data_struct::computeADC_to_bin(const int& currentValue) const
formula.replace(F("%value%"), toString(calibrated_value, _nrDecimals));
double result = 0;
ESPEASY_RULES_FLOAT_TYPE result{};
if (!isError(RulesCalculate.doCalculate(parseTemplate(formula).c_str(), &result))) {
calibrated_value = result;
+2 -2
View File
@@ -173,9 +173,9 @@ bool P008_data_struct::plugin_once_a_second(struct EventStruct *event) {
// uint64_t outvalue = castHexAsDec(invalue);
// info.reserve(40);
// info += F("Test castHexAsDec(");
// info += (double)invalue;
// info += (ESPEASY_RULES_FLOAT_TYPE)invalue;
// info += F(") => ");
// info += (double)outvalue;
// info += (ESPEASY_RULES_FLOAT_TYPE)outvalue;
// addLog(LOG_LEVEL_INFO, info);
}
}
+15 -15
View File
@@ -80,39 +80,39 @@ unsigned long P032_data_struct::read_adc(unsigned char aCMD)
void P032_data_struct::readout() {
unsigned long D1 = 0, D2 = 0;
double dT;
double Offset;
double SENS;
ESPEASY_RULES_FLOAT_TYPE dT;
ESPEASY_RULES_FLOAT_TYPE Offset;
ESPEASY_RULES_FLOAT_TYPE SENS;
D2 = read_adc(MS5xxx_CMD_ADC_D2 + MS5xxx_CMD_ADC_4096);
D1 = read_adc(MS5xxx_CMD_ADC_D1 + MS5xxx_CMD_ADC_4096);
// calculate 1st order pressure and temperature (MS5611 1st order algorithm)
dT = D2 - ms5611_prom[5] * static_cast<double>(1 << 8);
Offset = ms5611_prom[2] * static_cast<double>(1 << 16) + dT * ms5611_prom[4] / static_cast<double>(1 << 7);
SENS = ms5611_prom[1] * static_cast<double>(1 << 15) + dT * ms5611_prom[3] / static_cast<double>(1 << 8);
ms5611_temperature = (2000 + (dT * ms5611_prom[6]) / static_cast<double>(1 << 23));
dT = D2 - ms5611_prom[5] * static_cast<ESPEASY_RULES_FLOAT_TYPE>(1 << 8);
Offset = ms5611_prom[2] * static_cast<ESPEASY_RULES_FLOAT_TYPE>(1 << 16) + dT * ms5611_prom[4] / static_cast<ESPEASY_RULES_FLOAT_TYPE>(1 << 7);
SENS = ms5611_prom[1] * static_cast<ESPEASY_RULES_FLOAT_TYPE>(1 << 15) + dT * ms5611_prom[3] / static_cast<ESPEASY_RULES_FLOAT_TYPE>(1 << 8);
ms5611_temperature = (2000 + (dT * ms5611_prom[6]) / static_cast<ESPEASY_RULES_FLOAT_TYPE>(1 << 23));
// perform higher order corrections
double T2 = 0., OFF2 = 0., SENS2 = 0.;
ESPEASY_RULES_FLOAT_TYPE T2 = 0., OFF2 = 0., SENS2 = 0.;
if (ms5611_temperature < 2000) {
T2 = dT * dT / static_cast<double>(1 << 31);
const double temp_20deg = ms5611_temperature - 2000;
OFF2 = 5.0 * temp_20deg * temp_20deg / static_cast<double>(1 << 1);
SENS2 = 5.0 * temp_20deg * temp_20deg / static_cast<double>(1 << 2);
T2 = dT * dT / static_cast<ESPEASY_RULES_FLOAT_TYPE>(1 << 31);
const ESPEASY_RULES_FLOAT_TYPE temp_20deg = ms5611_temperature - 2000;
OFF2 = 5.0 * temp_20deg * temp_20deg / static_cast<ESPEASY_RULES_FLOAT_TYPE>(1 << 1);
SENS2 = 5.0 * temp_20deg * temp_20deg / static_cast<ESPEASY_RULES_FLOAT_TYPE>(1 << 2);
if (ms5611_temperature < -1500) {
const double temp_min15deg = ms5611_temperature + 1500;
const ESPEASY_RULES_FLOAT_TYPE temp_min15deg = ms5611_temperature + 1500;
OFF2 += 7.0 * temp_min15deg * temp_min15deg;
SENS2 += 11.0 * temp_min15deg * temp_min15deg / static_cast<double>(1 << 1);
SENS2 += 11.0 * temp_min15deg * temp_min15deg / static_cast<ESPEASY_RULES_FLOAT_TYPE>(1 << 1);
}
}
ms5611_temperature -= T2;
Offset -= OFF2;
SENS -= SENS2;
ms5611_pressure = (((D1 * SENS) / static_cast<double>(1 << 21) - Offset) / static_cast<double>(1 << 15));
ms5611_pressure = (((D1 * SENS) / static_cast<ESPEASY_RULES_FLOAT_TYPE>(1 << 21) - Offset) / static_cast<ESPEASY_RULES_FLOAT_TYPE>(1 << 15));
}
+2 -2
View File
@@ -40,8 +40,8 @@ public:
uint8_t i2cAddress;
unsigned int ms5611_prom[8] = { 0 };
double ms5611_pressure = 0;
double ms5611_temperature = 0;
ESPEASY_RULES_FLOAT_TYPE ms5611_pressure = 0;
ESPEASY_RULES_FLOAT_TYPE ms5611_temperature = 0;
};
#endif // ifdef USES_P032
#endif // ifndef PLUGINSTRUCTS_P032_DATA_STRUCT_H
+4 -4
View File
@@ -665,13 +665,13 @@ String P037_data_struct::mapValue(const String& input, const String& attribute)
}
case 1: // % => percentage of mapping
{
double inputDouble;
double mappingDouble;
ESPEASY_RULES_FLOAT_TYPE inputDouble;
ESPEASY_RULES_FLOAT_TYPE mappingDouble;
if (validDoubleFromString(input, inputDouble) &&
validDoubleFromString(valu, mappingDouble)) {
if (compareDoubleValues('>', mappingDouble, 0.0)) {
double resultDouble = (100.0 / mappingDouble) * inputDouble; // Simple calculation to percentage
ESPEASY_RULES_FLOAT_TYPE resultDouble = (static_cast<ESPEASY_RULES_FLOAT_TYPE>(100) / mappingDouble) * inputDouble; // Simple calculation to percentage
int8_t decimals = 0;
int8_t dotPos = input.indexOf('.');
@@ -774,7 +774,7 @@ bool P037_data_struct::checkFilters(const String& key, const String& value, int8
String filters = P037_FILTER_LIST;
String valueData = value;
String fltKey, fltIndex, filterData, fltOper;
double from, to, doubleValue;
ESPEASY_RULES_FLOAT_TYPE from, to, doubleValue;
int8_t rangeSeparator;
bool accept = true;
bool matchTopicId = true;
+1 -1
View File
@@ -90,7 +90,7 @@ static const uint8_t DefaultCharTable[42] PROGMEM = {
// - pos 25 - exclamation mark "!" B01101011
// - pos 26 - question mark "?" B01101001
// - pos 27 - single quote "'" B00000010
// - pos 28 - double quote '"' B00100010
// - pos 28 - ESPEASY_RULES_FLOAT_TYPE quote '"' B00100010
// - pos 29 - left sharp bracket "<" B01000010
// - pos 30 - right sharp bracket ">" B01100000
// - pos 31 - backslash "\" B00010011
+3 -3
View File
@@ -250,7 +250,7 @@ bool P082_data_struct::storeCurPos(unsigned int maxAge_msec) {
// Return the distance in meters compared to last stored position.
// @retval -1 when no fix.
double P082_data_struct::distanceSinceLast(unsigned int maxAge_msec) {
ESPEASY_RULES_FLOAT_TYPE P082_data_struct::distanceSinceLast(unsigned int maxAge_msec) {
if (!hasFix(maxAge_msec)) {
return -1.0;
}
@@ -451,8 +451,8 @@ bool P082_data_struct::webformLoad_show_stats(struct EventStruct *event, uint8_t
}
bool show_custom = false;
double dist_p2p = 0.0;
double dist_stddev = 0.0;
ESPEASY_RULES_FLOAT_TYPE dist_p2p{};
ESPEASY_RULES_FLOAT_TYPE dist_stddev{};
if (gps != nullptr) {
switch (query_type) {
+6 -6
View File
@@ -86,7 +86,7 @@ struct P082_data_struct : public PluginTaskData_base {
// Return the distance in meters compared to last stored position.
// @retval -1 when no fix.
double distanceSinceLast(unsigned int maxAge_msec);
ESPEASY_RULES_FLOAT_TYPE distanceSinceLast(unsigned int maxAge_msec);
// Return the GPS time stamp, which is in UTC.
// @param age is the time in msec since the last update of the time +
@@ -131,11 +131,11 @@ public:
TinyGPSPlus *gps = nullptr;
ESPeasySerial *easySerial = nullptr;
double _last_lat = 0.0;
double _last_lng = 0.0;
double _ref_lat = 0.0;
double _ref_lng = 0.0;
double _distance = 0.0;
ESPEASY_RULES_FLOAT_TYPE _last_lat{};
ESPEASY_RULES_FLOAT_TYPE _last_lng{};
ESPEASY_RULES_FLOAT_TYPE _ref_lat{};
ESPEASY_RULES_FLOAT_TYPE _ref_lng{};
ESPEASY_RULES_FLOAT_TYPE _distance{};
unsigned long _pps_time = 0;
+3 -3
View File
@@ -338,9 +338,9 @@ struct P104_bargraph_struct {
P104_bargraph_struct() = delete; // Not used, so leave out explicitly
P104_bargraph_struct(uint8_t _graph) : graph(_graph) {}
double value = 0.0;
double max = 0.0;
double min = 0.0;
ESPEASY_RULES_FLOAT_TYPE value{};
ESPEASY_RULES_FLOAT_TYPE max{};
ESPEASY_RULES_FLOAT_TYPE min{};
uint8_t graph;
uint8_t barType = 0u;
uint8_t direction = 0u;
+2
View File
@@ -413,9 +413,11 @@ void addHtmlFloat(const float& value, unsigned int nrDecimals) {
addHtml(toString(value, nrDecimals));
}
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
void addHtmlFloat(const double& value, unsigned int nrDecimals) {
addHtml(doubleToString(value, nrDecimals));
}
#endif
void addEncodedHtml(const __FlashStringHelper * html) {
+2
View File
@@ -127,7 +127,9 @@ void addHtmlInt(uint32_t int_val);
void addHtmlInt(int64_t int_val);
void addHtmlInt(uint64_t int_val);
void addHtmlFloat(const float& value, unsigned int nrDecimals = 2u);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
void addHtmlFloat(const double& value, unsigned int nrDecimals = 2u);
#endif
void addEncodedHtml(const __FlashStringHelper * html);
void addEncodedHtml(const String& html);