[Build] Reduce ESP8266 and ESP32-C6 DisplayB build size

This commit is contained in:
TD-er committed 2026-09-11 18:14:19 +02:00
1 parent f6bd2ea643
commit 6dfd71a4a0
25 files changed
+352 -126

No files matched your search

+1 -1
View File
@@ -278,7 +278,7 @@ float Adafruit_BME680::readAltitude(float seaLevel) {
// http://forums.adafruit.com/viewtopic.php?f=22&t=58064
float atmospheric = readPressure() / 100.0F;
return 44330.0 * (1.0 - pow(atmospheric / seaLevel, 0.1903));
return 44330.0f * (1.0f - powf(atmospheric / seaLevel, 0.1903f));
}
/*!
+1 -1
View File
@@ -291,7 +291,7 @@ float Adafruit_BMP3XX::readAltitude(float seaLevel) {
// http://forums.adafruit.com/viewtopic.php?f=22&t=58064
float atmospheric = readPressure() / 100.0F;
return 44330.0 * (1.0 - pow(atmospheric / seaLevel, 0.1903));
return 44330.0f * (1.0f - powf(atmospheric / seaLevel, 0.1903f));
}
/**************************************************************************/
@@ -39,7 +39,7 @@ void setup() {
for (int i=0; i<256; i++) {
float x = i;
x /= 255;
x = pow(x, 2.5);
x = powf(x, 2.5f);
x *= 255;
if (commonAnode) {
+7 -7
View File
@@ -218,12 +218,12 @@ public:
static float ExponentialIn(float unitValue)
{
return (pow(2, 10.0f * (unitValue - 1.0f)));
return (powf(2, 10.0f * (unitValue - 1.0f)));
}
static float ExponentialOut(float unitValue)
{
return (-pow(2, -10.0f * unitValue) + 1.0f);
return (-powf(2, -10.0f * unitValue) + 1.0f);
}
static float ExponentialInOut(float unitValue)
@@ -231,12 +231,12 @@ public:
unitValue *= 2.0f;
if (unitValue < 1.0f)
{
return (0.5f * pow(2, 10.0f * (unitValue - 1.0f)));
return (0.5f * powf(2, 10.0f * (unitValue - 1.0f)));
}
else
{
unitValue -= 1.0f;
return (0.5f * (-pow(2, -10.0f * unitValue) + 2.0f));
return (0.5f * (-powf(2, -10.0f * unitValue) + 2.0f));
}
}
@@ -245,12 +245,12 @@ public:
unitValue *= 2.0f;
if (unitValue < 1.0f)
{
return (0.5f * (-pow(2, -10.0f * unitValue) + 1.0f));
return (0.5f * (-powf(2, -10.0f * unitValue) + 1.0f));
}
else
{
unitValue -= 2.0f;
return (0.5f * (pow(2, 10.0f * unitValue) + 1.0f));
return (0.5f * (powf(2, 10.0f * unitValue) + 1.0f));
}
}
@@ -308,6 +308,6 @@ public:
static float Gamma(float unitValue)
{
return pow(unitValue, 1.0f / 0.45f);
return powf(unitValue, 1.0f / 0.45f);
}
};
@@ -703,7 +703,8 @@ double ADXL345::getRate() {
readFrom(ADXL345_BW_RATE, 1, &_b);
_b &= 0b00001111;
return (pow(2, ((int)_b) - 6)) * 6.25;
return (2 << (int)_b) * 0.09765625;
// return (pow(2, ((int)_b) - 6)) * 6.25;
}
void ADXL345::setRate(double rate) {
+1
View File
@@ -51,6 +51,7 @@ build_flags = ${esp32c6_common_LittleFS.build_flags}
-D PLUGIN_DISPLAY_B_COLLECTION
-D ST7789_EXTRA_INIT=1
-D P116_EXTRA_ST7789=1
-D FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE=0
[env:climate_A_ESP32c6_4M316k]
extends = esp32c6_common_LittleFS
+1
View File
@@ -288,6 +288,7 @@ platform = ${normal.platform}
platform_packages = ${normal.platform_packages}
build_flags = ${normal.build_flags}
${esp8266_4M1M.build_flags}
-D FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE=0
lib_ignore = ${normal.lib_ignore}
[env:normal_ESP8266_4M1M_VCC]
@@ -229,15 +229,15 @@ void NW004_data_struct_ETH_SPI::webform_load(EventStruct *event)
FormSelectorOptions selector(NR_ELEMENTS(ids), options, ids);
auto params = NW004_makeWebFormItemParams(NW004_KEY_ETH_PHY_TYPE);
params._defaultIntValue = static_cast<int>(EthPhyType_t::notSet);
showFormSelector(*_kvs, selector, params);
params._defaultValue.setInt(static_cast<int>(EthPhyType_t::notSet));
showFormSelector(*_kvs, selector, std::move(params));
}
{
auto params = NW004_makeWebFormItemParams(NW004_KEY_ETH_PHY_ADDR);
params._min = -1;
params._max = 127;
params._defaultIntValue = 1;
showWebformItem(*_kvs, params);
params._defaultValue.setInt(1);
showWebformItem(*_kvs, std::move(params));
addFormNote(F("I&sup2;C-address of Ethernet PHY"));
}
{
@@ -540,8 +540,8 @@ void NW005_data_struct_PPP_modem::webform_load(EventStruct *event)
{
auto params = NW005_makeWebFormItemParams(NW005_KEY_PIN_RESET_DELAY);
params._max = 2000;
params._defaultIntValue = 200;
showWebformItem(*_kvs, params);
params._defaultValue.setInt(200);
showWebformItem(*_kvs, std::move(params));
addUnit(F("ms"));
}
@@ -564,21 +564,21 @@ void NW005_data_struct_PPP_modem::webform_load(EventStruct *event)
{
auto params = NW005_makeWebFormItemParams(NW005_KEY_BAUDRATE);
params._max = 10000000;
params._defaultIntValue = 115200;
showWebformItem(*_kvs, params);
params._defaultValue.setInt(115200);
showWebformItem(*_kvs, std::move(params));
}
addFormSubHeader(F("Connection Settings"));
{
auto params = NW005_makeWebFormItemParams(NW005_KEY_APN);
params._maxLength = 64;
showWebformItem(*_kvs, params);
showWebformItem(*_kvs, std::move(params));
addFormNote(F("Optional, can be left empty"));
}
{
auto params = NW005_makeWebFormItemParams(NW005_KEY_SIM_PIN);
params._maxLength = 4;
showWebformItem(*_kvs, params);
showWebformItem(*_kvs, std::move(params));
addFormNote(F("Only numerical digits"));
}
+6 -6
View File
@@ -151,22 +151,22 @@ boolean Plugin_121(uint8_t function, struct EventStruct *event, String& string)
UserVar.setFloat(event->TaskIndex, 1, s_event.magnetic.y);
UserVar.setFloat(event->TaskIndex, 2, s_event.magnetic.z);
double heading = atan2(s_event.magnetic.y, s_event.magnetic.x);
ESPEASY_RULES_FLOAT_TYPE heading = atan2(s_event.magnetic.y, s_event.magnetic.x);
const double decl = PCONFIG_FLOAT(1);
const ESPEASY_RULES_FLOAT_TYPE decl = PCONFIG_FLOAT(1);
if (!essentiallyZero(decl)) {
heading += decl;
}
if (definitelyLessThan(heading, 0)) {
heading += TWO_PI;
heading += (ESPEASY_RULES_FLOAT_TYPE)TWO_PI;
} else
if (definitelyGreaterThan(heading, TWO_PI)) {
heading -= TWO_PI;
if (definitelyGreaterThan(heading, (ESPEASY_RULES_FLOAT_TYPE)TWO_PI)) {
heading -= (ESPEASY_RULES_FLOAT_TYPE)TWO_PI;
}
UserVar.setFloat(event->TaskIndex, 3, heading * M_PI_180);
UserVar.setFloat(event->TaskIndex, 3, heading * (ESPEASY_RULES_FLOAT_TYPE)M_PI_180);
success = true; // Assume we want to send out values to controllers
}
+1
View File
@@ -4114,6 +4114,7 @@ To create/register a plugin, you have to :
// ESPEASY_RULES_FLOAT_TYPE should be either double (default) or float.
// It is solely based on FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
// This can save about 9+ kByte in build size to use only float types
#ifdef ESPEASY_RULES_FLOAT_TYPE
#undef ESPEASY_RULES_FLOAT_TYPE
#endif
+119 -16
View File
@@ -6,9 +6,9 @@
#include "../Helpers/StringConverter.h"
#include "../Helpers/StringConverter_Numerical.h"
#define VALUE_STRUCT_SSO_FIRST_CHAR_INDEX 1
#define VALUE_STRUCT_SSO_FIRST_CHAR_INDEX 2
#define VALUE_STRUCT_SSO_FIRST_CHAR bytes_all[VALUE_STRUCT_SSO_FIRST_CHAR_INDEX]
#define VALUE_STRUCT_SSO_MAX_SIZE 14
#define VALUE_STRUCT_SSO_MAX_SIZE 13
const ValueStruct INVALID_VALUESTRUCT{};
@@ -17,9 +17,10 @@ const ValueStruct INVALID_VALUESTRUCT{};
// ********************************************************************************
ValueStruct::~ValueStruct()
{
if (!_isSSO &&
(static_cast<ValueStruct::ValueType>(_valueType) == ValueStruct::ValueType::String)
&& (str_val != nullptr)) {
if (!_isSSO && (str_val != nullptr) &&
((static_cast<ValueStruct::ValueType>(_valueType) == ValueStruct::ValueType::String) ||
(static_cast<ValueStruct::ValueType>(_valueType) == ValueStruct::ValueType::IP))
) {
free(str_val);
}
}
@@ -49,6 +50,37 @@ ValueStruct ValueStruct::makeBinFormatted(uint64_t val, uint8_t minNrDigits)
return res;
}
void ValueStruct::setInt(const uint64_t& val) { this->operator=(ValueStruct(val)); }
void ValueStruct::setInt(const int64_t& val) { this->operator=(ValueStruct(val)); }
void ValueStruct::setInt(int val) { this->operator=(ValueStruct(val)); }
#if defined(ESP32) && !defined(__riscv)
void ValueStruct::setInt(int32_t val) { this->operator=(ValueStruct(val)); }
#endif // if defined(ESP32) && !defined(__riscv)
void ValueStruct::setInt(uint32_t val) { this->operator=(ValueStruct(val)); }
#if defined(ESP32) && !defined(__riscv)
void ValueStruct::setInt(size_t val) { this->operator=(ValueStruct(val)); }
#endif // if defined(ESP32) && !defined(__riscv)
void ValueStruct::setIPAddress(const IPAddress& ip)
{
#ifdef ESP8266
this->operator=(ValueStruct(ip.toString()));
#endif
#ifdef ESP32
this->operator=(ValueStruct(ip.toString(true)));
#endif
_valueType = (uint64_t)ValueStruct::ValueType::IP;
}
void ValueStruct::setPreferredFormat(ValueStruct::PreferredFormat format)
{
const auto vtype = getValueType();
@@ -64,7 +96,7 @@ void ValueStruct::setCaseFormat(ValueStruct::CaseFormat caseFormat) { _caseForma
void ValueStruct::clear() {
if (!_isSSO
&& (getValueType() == ValueStruct::ValueType::String)
&& ((getValueType() == ValueStruct::ValueType::String) || (getValueType() == ValueStruct::ValueType::IP))
&& (str_val != nullptr)) {
free(str_val);
}
@@ -83,6 +115,16 @@ ValueStruct& ValueStruct::operator=(ValueStruct&& rhs)
ValueStruct& ValueStruct::deepCopy(const ValueStruct& rhs)
{
if (!rhs._isSSO && (rhs.getValueType() == ValueStruct::ValueType::IP))
{
IPAddress ip;
if (rhs.toIPAddress(ip)) {
this->setIPAddress(ip);
}
return *this;
}
if (!rhs._isSSO && (rhs.getValueType() == ValueStruct::ValueType::String))
{
this->operator=(ValueStruct(rhs.toString()));
@@ -100,8 +142,8 @@ ValueStruct::ValueStruct(const bool& val) :
_valueType((uint64_t)ValueStruct::ValueType::Bool),
_preferredFormat(0),
_caseFormat(0),
_trimTrailingZeros(0),
_size(1),
_trimTrailingZeros(0),
u64_val(val ? 1ull : 0ull)
{}
@@ -176,23 +218,34 @@ ValueStruct::ValueStruct(const float& val,
_valueType((uint64_t)ValueStruct::ValueType::Float),
_preferredFormat(0),
_caseFormat(0),
_trimTrailingZeros((uint64_t)trimTrailingZeros),
_nrDecimals((uint64_t)nrDecimals),
_size(sizeof(val) * 8),
_trimTrailingZeros((uint64_t)trimTrailingZeros),
f_val(val)
{}
ValueStruct::ValueStruct(const double& val,
uint8_t nrDecimals,
bool trimTrailingZeros) :
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
_isSSO(0),
_valueType((uint64_t)ValueStruct::ValueType::Double),
_preferredFormat(0),
_caseFormat(0),
_trimTrailingZeros((uint64_t)trimTrailingZeros),
_nrDecimals((uint64_t)nrDecimals),
_size(sizeof(val) * 8),
_trimTrailingZeros((uint64_t)trimTrailingZeros),
d_val(val)
#else // if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
_isSSO(0),
_valueType((uint64_t)ValueStruct::ValueType::Float),
_preferredFormat(0),
_caseFormat(0),
_nrDecimals((uint64_t)nrDecimals),
_size(sizeof(f_val) * 8),
_trimTrailingZeros((uint64_t)trimTrailingZeros),
f_val(val)
#endif // if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
{}
ValueStruct::ValueStruct(const char*val) :
@@ -311,13 +364,29 @@ ValueStruct ValueStruct::makeFromString(const String& val)
String trimmedVal(val);
trimmedVal.trim();
const bool b_true = trimmedVal.equalsIgnoreCase(F("true"));
const bool b_false = trimmedVal.equalsIgnoreCase(F("false"));
if (trimmedVal.isEmpty()) {
return ValueStruct(val);
}
if (b_true || b_false) {
const bool b_true = trimmedVal.equalsIgnoreCase(F("true"));
if (b_true || trimmedVal.equalsIgnoreCase(F("false"))) {
return ValueStruct(b_true);
}
{
// Check for IP before checking for other types,
// as it would otherwise be stored as a string, not IP type.
IPAddress ip;
if (ip.fromString(val))
{
ValueStruct v;
v.setIPAddress(ip);
return v;
}
}
if (ContainsAny(val, F(":#%[](){},\"'`"))) {
return ValueStruct(val);
}
@@ -330,7 +399,6 @@ ValueStruct ValueStruct::makeFromString(const String& val)
}
}
switch (detectedType)
{
case NumericalType::Not_a_number:
@@ -429,17 +497,22 @@ int64_t ValueStruct::toInt(int64_t defaultValue) const
break;
}
case ValueStruct::ValueType::Float:
#if !FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
case ValueStruct::ValueType::Double:
#endif
if (isValidFloat(f_val)) {
return roundf(f_val);
}
break;
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
case ValueStruct::ValueType::Double:
if (isValidDouble(d_val)) {
return round(d_val);
}
break;
#endif // if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
case ValueStruct::ValueType::String:
case ValueStruct::ValueType::FlashString:
@@ -448,12 +521,13 @@ int64_t ValueStruct::toInt(int64_t defaultValue) const
}
break;
case ValueStruct::ValueType::Unset:
case ValueStruct::ValueType::IP:
break;
}
return defaultValue;
}
double ValueStruct::toFloat() const
ESPEASY_RULES_FLOAT_TYPE ValueStruct::toFloat(ESPEASY_RULES_FLOAT_TYPE defaultValue) const
{
switch (getValueType())
{
@@ -475,14 +549,33 @@ double ValueStruct::toFloat() const
}
case ValueStruct::ValueType::Double:
{
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
return d_val;
#else
return f_val;
#endif // if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
}
case ValueStruct::ValueType::String:
case ValueStruct::ValueType::FlashString:
case ValueStruct::ValueType::IP:
case ValueStruct::ValueType::Unset:
break;
}
return 0.0;
return defaultValue;
}
bool ValueStruct::toIPAddress(IPAddress& ip) const
{
switch (getValueType())
{
case ValueStruct::ValueType::IP:
case ValueStruct::ValueType::String:
case ValueStruct::ValueType::FlashString:
return ip.fromString(this->toString());
default:
break;
}
return false;
}
size_t ValueStruct::print(Print& out) const
@@ -547,7 +640,14 @@ size_t ValueStruct::print(Print& out, ValueType& valueType, bool unformatted) co
}
return formatCase(out, String((const __FlashStringHelper *)str_val));
}
case ValueStruct::ValueType::IP:
{
return out.write((const uint8_t *)str_val, _size);
}
case ValueStruct::ValueType::Float:
#if !FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
case ValueStruct::ValueType::Double:
#endif
{
String res;
@@ -557,6 +657,7 @@ size_t ValueStruct::print(Print& out, ValueType& valueType, bool unformatted) co
}
return out.print(res);
}
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
case ValueStruct::ValueType::Double:
{
String res;
@@ -567,6 +668,7 @@ size_t ValueStruct::print(Print& out, ValueType& valueType, bool unformatted) co
}
return out.print(res);
}
#endif // if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
case ValueStruct::ValueType::Int:
{
if ((_size > 32) || _minNrDigits) {
@@ -607,7 +709,8 @@ bool ValueStruct::isEmpty() const
{
case ValueStruct::ValueType::String:
case ValueStruct::ValueType::FlashString:
return _size == 0;
case ValueStruct::ValueType::IP:
return _size == 0 || str_val == nullptr;
case ValueStruct::ValueType::Unset:
return true;
default: break;
+51 -31
View File
@@ -3,6 +3,8 @@
#include <WString.h>
#include <Print.h>
#include <IPAddress.h>
// ********************************************************************************
// ValueStruct
// ********************************************************************************
@@ -19,6 +21,7 @@ public:
Unset = 0,
String,
FlashString,
IP,
Float,
Double,
Int,
@@ -28,20 +31,20 @@ public:
};
#ifndef BUILD_NO_DEBUG
static const char* toShortStr(ValueType valueType)
{
static const char* shortStrings = "---\0Str\0Fla\0flt\0dbl\0int\0uin\0boo\0";
static const char*shortStrings = "---\0Str\0Fla\0IP\0\0flt\0dbl\0int\0uin\0boo\0";
constexpr uint8_t index_modulo = static_cast<uint8_t>(ValueType::Bool) + 1;
const uint8_t index = static_cast<uint8_t>(valueType) % index_modulo;
const uint8_t index = static_cast<uint8_t>(valueType) % index_modulo;
return shortStrings + 4*index;
return shortStrings + 4 * index;
}
#endif
#endif // ifndef BUILD_NO_DEBUG
enum class PreferredFormat : uint8_t {
Default = 0,
Dec,
Bin,
Hex
@@ -90,7 +93,6 @@ public:
uint8_t nrDecimals = 4,
bool trimTrailingZeros = false);
ValueStruct(const char*val);
ValueStruct(const String& val);
@@ -104,6 +106,20 @@ public:
static ValueStruct makeBinFormatted(uint64_t val,
uint8_t minNrDigits);
void setInt(const uint64_t& val);
void setInt(const int64_t& val);
void setInt(int val);
#if defined(ESP32) && !defined(__riscv)
void setInt(int32_t val);
#endif
void setInt(uint32_t val);
#if defined(ESP32) && !defined(__riscv)
void setInt(size_t val);
#endif
void setIPAddress(const IPAddress& ip);
ValueStruct::ValueType getValueType() const
{
if (_isSSO) { return ValueStruct::ValueType::String; }
@@ -143,35 +159,37 @@ public:
// If the given string is a numerical, try to detect:
// - preferred notation (Hex/Dec/Bin)
// - number of decimals
static ValueStruct makeFromString(const __FlashStringHelper *val);
static ValueStruct makeFromString(const String& val);
static ValueStruct makeFromString(const __FlashStringHelper *val);
static ValueStruct makeFromString(const String& val);
String toString(bool unformatted = false) const;
String toString(bool unformatted = false) const;
String toString(ValueType& valueType,
bool unformatted = false) const;
String toString(ValueType& valueType,
bool unformatted = false) const;
int64_t toInt(int64_t defaultValue = 0) const;
int64_t toInt(int64_t defaultValue = 0) const;
double toFloat() const;
ESPEASY_RULES_FLOAT_TYPE toFloat(ESPEASY_RULES_FLOAT_TYPE defaultValue = 0) const;
size_t print(Print& out) const;
bool toIPAddress(IPAddress& ip) const;
bool isEmpty() const;
size_t print(Print& out) const;
bool isSet() const { return getValueType() != ValueStruct::ValueType::Unset; }
bool isEmpty() const;
bool equals(const __FlashStringHelper *cmdStr,
bool ignoreCase = false) const;
bool equals(const String& cmdStr,
bool ignoreCase = false) const;
bool isSet() const { return getValueType() != ValueStruct::ValueType::Unset; }
bool equalsIgnoreCase(const __FlashStringHelper *cmdStr) const { return equals(cmdStr, true); }
bool equals(const __FlashStringHelper *cmdStr,
bool ignoreCase = false) const;
bool equals(const String& cmdStr,
bool ignoreCase = false) const;
bool equalsIgnoreCase(const String& cmdStr) const { return equals(cmdStr, true); }
bool equalsIgnoreCase(const __FlashStringHelper *cmdStr) const { return equals(cmdStr, true); }
bool equalsIgnoreCase(const String& cmdStr) const { return equals(cmdStr, true); }
#ifndef BUILD_NO_DEBUG
String debug() const;
String debug() const;
#endif
private:
@@ -191,22 +209,24 @@ private:
// and decrease max. nr of SSO bytes (VALUE_STRUCT_SSO_MAX_SIZE)
uint64_t _isSSO : 1;
uint64_t _valueType : 3;
uint64_t _valueType : 4;
uint64_t _preferredFormat : 2;
uint64_t _caseFormat : 2;
uint64_t _minNrDigits : 7; // For printing ints with leading zeroes
// --- End of 1st byte
// --- End of 2nd byte
uint64_t _trimTrailingZeros : 1;
uint64_t _minNrDigits : 7; // For printing ints with leading zeroes
uint64_t _nrDecimals : 8;
uint64_t _size : 16; // Length of string or nr of bits
uint64_t unused : 24;
uint64_t _trimTrailingZeros : 1;
uint64_t unused : 23;
union {
void *str_val;
float f_val;
double d_val;
void *str_val;
float f_val;
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
double d_val;
#endif
int64_t i64_val;
uint64_t u64_val;
+13
View File
@@ -41,6 +41,19 @@ int maxNrDecimals_fpType(const float& value)
return res;
}
int quick_pow10(uint8_t n)
{
static int pow10[] = {
1, 10, 100, 1000, 10000,
100000, 1000000, 10000000, 100000000, 1000000000
};
constexpr uint8_t max_n = NR_ELEMENTS(pow10) - 1;
if (n <= max_n) return pow10[n];
return pow10[max_n - 1];
}
uint64_t computeDecimalFactorForDecimals(int nrDecimals)
{
uint64_t factor = 1;
+95 -27
View File
@@ -15,49 +15,117 @@ int maxNrDecimals_fpType(const double& value);
#endif
int maxNrDecimals_fpType(const float& value);
#ifdef ESP32
constexpr int maxNrDecimals_fpType_constexpr(const ESPEASY_RULES_FLOAT_TYPE& value)
{
# if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
int res = ESPEASY_DOUBLE_NR_DECIMALS;
# else
int res = ESPEASY_FLOAT_NR_DECIMALS;
# endif // if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
ESPEASY_RULES_FLOAT_TYPE factor = 1;
while ((value / factor) > 10 && res > 2) {
factor *= 10.0f;
--res;
}
return res;
}
#endif // ifdef ESP32
#ifdef ESP8266
constexpr unsigned maxNrDecimals_fpType_constexpr_(ESPEASY_RULES_FLOAT_TYPE value, ESPEASY_RULES_FLOAT_TYPE factor, unsigned res)
{
return ((value / factor) > 10 && res > 2)
? maxNrDecimals_fpType_constexpr_(value, factor * 10.0f, res - 1)
: res;
}
constexpr int maxNrDecimals_fpType_constexpr(const ESPEASY_RULES_FLOAT_TYPE& value)
{
return maxNrDecimals_fpType_constexpr_(
value,
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
1.0, ESPEASY_DOUBLE_NR_DECIMALS
#else
1.0f, ESPEASY_FLOAT_NR_DECIMALS
#endif
);
}
#endif // ifdef ESP8266
int quick_pow10(uint8_t n);
uint64_t computeDecimalFactorForDecimals(int nrDecimals);
// 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);
bool approximatelyEqual(const double& a,
const double& b);
#endif // if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
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 estimatedEpsilon);
#endif
bool approximatelyEqual(const float& a, const float& b, float estimatedEpsilon);
bool approximatelyEqual(const double& a,
const double& b,
double estimatedEpsilon);
#endif // if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool approximatelyEqual(const float& a,
const float& b,
float estimatedEpsilon);
#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);
bool definitelyGreaterThan(const double& a,
const double& b);
#endif // if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
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 estimatedEpsilon);
#endif
bool definitelyGreaterThan(const float& a, const float& b, float estimatedEpsilon);
bool definitelyGreaterThan(const double& a,
const double& b,
double estimatedEpsilon);
#endif // if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool definitelyGreaterThan(const float& a,
const float& b,
float estimatedEpsilon);
#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);
bool definitelyLessThan(const double& a,
const double& b);
#endif // if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
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 estimatedEpsilon);
#endif
bool definitelyLessThan(const float& a, const float& b, float estimatedEpsilon);
bool definitelyLessThan(const double& a,
const double& b,
double estimatedEpsilon);
#endif // if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool definitelyLessThan(const float& a,
const float& b,
float estimatedEpsilon);
#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);
bool essentiallyEqual(const double& a,
const double& b);
#endif // if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
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 estimatedEpsilon);
#endif
bool essentiallyEqual(const float& a, const float& b, float estimatedEpsilon);
bool essentiallyEqual(const double& a,
const double& b,
double estimatedEpsilon);
#endif // if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool essentiallyEqual(const float& a,
const float& b,
float estimatedEpsilon);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool essentiallyZero(const double& a);
bool essentiallyZero(const double& a);
#endif
bool essentiallyZero(const float& a);
bool essentiallyZero(const float& a);
ESPEASY_RULES_FLOAT_TYPE mapADCtoFloat(ESPEASY_RULES_FLOAT_TYPE float_value,
ESPEASY_RULES_FLOAT_TYPE adc1,
@@ -66,4 +134,4 @@ ESPEASY_RULES_FLOAT_TYPE mapADCtoFloat(ESPEASY_RULES_FLOAT_TYPE float_value,
ESPEASY_RULES_FLOAT_TYPE out2);
#endif // HELPERS_ESPEASY_MATH_H
#endif // HELPERS_ESPEASY_MATH_H
+3
View File
@@ -203,6 +203,9 @@ void KeyValueWriter_JSON::writeValue(const ValueStruct& val, bool forceString)
return;
}
break;
case ValueStruct::ValueType::IP:
pr.print(to_json_value(str, true));
return;
}
pr.print(to_json_value(str));
}
+6 -1
View File
@@ -15,10 +15,11 @@ bool isValidFloat(float f) {
return !isnan(f) && !isinf(f);
#endif
}
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool isValidDouble(ESPEASY_RULES_FLOAT_TYPE f) {
return !isnan(f) && !isinf(f);
}
#endif
bool validIntFromString(const String& tBuf, int32_t& result) {
NumericalType detectedType;
@@ -144,6 +145,7 @@ bool validDoubleFromString(const String& tBuf, ESPEASY_RULES_FLOAT_TYPE& result)
}
bool validDoubleFromString(const String& tBuf, ESPEASY_RULES_FLOAT_TYPE& result, int& nrDecimals) {
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
nrDecimals = -1;
#if defined(CORE_POST_2_5_0) || defined(ESP32)
@@ -180,6 +182,9 @@ bool validDoubleFromString(const String& tBuf, ESPEASY_RULES_FLOAT_TYPE& result,
return res;
#endif // if defined(CORE_POST_2_5_0) || defined(ESP32)
#else
return validFloatFromString(tBuf, result);
#endif
}
bool mustConsiderAsString(NumericalType detectedType) {
+2
View File
@@ -8,7 +8,9 @@
\*********************************************************************************************/
bool isValidFloat(float f);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
bool isValidDouble(ESPEASY_RULES_FLOAT_TYPE f);
#endif
bool validIntFromString(const String& tBuf, int32_t& result);
+1 -1
View File
@@ -1615,7 +1615,7 @@ void parseStandardConversions(String& s, bool useURLencode) {
#undef SMART_CONV
#if FEATURE_STRING_VARIABLES
double tmp{};
ESPEASY_RULES_FLOAT_TYPE tmp{};
#define SMART_CONV(T, FUN) \
while (getConvertArgumentStr((T), data)) { repl(data, (FUN)); }
SMART_CONV(F("%c_isnum%"), String(validDoubleFromString(getCustomStringVar(data.str1), tmp) ? 1 : 0))
+6 -4
View File
@@ -231,18 +231,20 @@ String SystemVariables::getSystemVariable(SystemVariables::Enum enumval) {
#ifndef LIMIT_BUILD_SIZE
case S_PI: {
constexpr ESPEASY_RULES_FLOAT_TYPE _pi = M_PI;
constexpr int maxNrDecimals = maxNrDecimals_fpType_constexpr(_pi);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
return doubleToString(_pi, maxNrDecimals_fpType(_pi));
return doubleToString(_pi, maxNrDecimals);
#else // if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
return toString(_pi, maxNrDecimals_fpType(_pi));
return floatToString(_pi, maxNrDecimals);
#endif // if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
}
case S_E: {
constexpr ESPEASY_RULES_FLOAT_TYPE _e = M_E;
constexpr int maxNrDecimals = maxNrDecimals_fpType_constexpr(_e);
#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
return doubleToString(_e, maxNrDecimals_fpType(_e));
return doubleToString(_e, maxNrDecimals);
#else // if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
return toString(_e, maxNrDecimals_fpType(_e));
return floatToString(_e, maxNrDecimals);
#endif // if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
}
#endif // ifndef LIMIT_BUILD_SIZE
+11 -1
View File
@@ -182,7 +182,8 @@ bool ESPEasy_key_value_store::load(
// Read next block
loadNextFromFile = true;
} else {
bufPos += 4;
bufPos += 4;
// TODO TD-er: Use getUint16FromBigEndianByteStream
bytesLeftPartialString = (buffer[bufPos] << 8) | buffer[bufPos + 1];
bufPos += 2;
@@ -1029,8 +1030,17 @@ void ESPEasy_key_value_store::setValue(const KVS_StorageType::Enum& storageType,
GET_4BYTE_INT_TYPE_FROM_STRING(int32_type, int32_t)
GET_4BYTE_INT_TYPE_FROM_STRING(uint32_type, uint32_t)
case KVS_StorageType::Enum::double_type:
# if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
setValue(key, value.toDouble());
# else
{
// Don't use the String::toDouble() function, but we still need to store it as double in the KVS
const double value_d(value.toFloat());
setValue(key, value_d);
}
# endif // if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE
break;
case KVS_StorageType::Enum::float_type:
setValue(key, value.toFloat());
break;
+2 -2
View File
@@ -899,8 +899,8 @@ void P073_data_struct::getDisplayLimits(int32_t& lLimit,
}
# endif // if P073_USE_74HC595
dgts -= offset; // Subtract an offset, used for extra symbol
lLimit = -pow10(dgts - 1); // Lowest value we can display - 1
uLimit = pow10(dgts); // Highest value we can display + 1
lLimit = -quick_pow10(dgts - 1); // Lowest value we can display - 1
uLimit = quick_pow10(dgts); // Highest value we can display + 1
// TODO disable log
// addLog(LOG_LEVEL_INFO, strformat(F("P073: limits: %d digits(%d), lower: %d, upper: %d"), dgts, offset, lLimit, uLimit));
}
+2 -2
View File
@@ -937,8 +937,8 @@ void P157_data_struct::getDisplayLimits(int32_t& lLimit,
uint8_t dgts = min((uint8_t)8, bufLen);
dgts -= offset; // Subtract an offset, used for extra symbol
lLimit = -pow10(dgts - 1); // Lowest value we can display - 1
uLimit = pow10(dgts); // Highest value we can display + 1
lLimit = -quick_pow10(dgts - 1); // Lowest value we can display - 1
uLimit = quick_pow10(dgts); // Highest value we can display + 1
// TODO disable log
// addLog(LOG_LEVEL_INFO, strformat(F("P157: limits: %d digits(%d), lower: %d, upper: %d"), dgts, offset, lLimit, uLimit));
}
@@ -45,7 +45,7 @@ void WebFormItemParams::checkRanges()
}
bool showWebformItem(const ESPEasy_key_value_store& store,
WebFormItemParams params)
WebFormItemParams&& params)
{
params.checkRanges();
String id = params._id.isEmpty() ? concat(F("KVS_ID_"), params._key) : params._id;
@@ -56,9 +56,9 @@ bool showWebformItem(const ESPEasy_key_value_store& store,
{
IPAddress value;
if (!store.getValue(params._key, value) && !params._defaultStringValue.isEmpty())
if (!store.getValue(params._key, value) && !params._defaultValue.isEmpty())
{
value.fromString(params._defaultStringValue);
params._defaultValue.toIPAddress(value);
}
addFormIPBox(
params._label,
@@ -73,7 +73,7 @@ bool showWebformItem(const ESPEasy_key_value_store& store,
if (!store.getValueAsString(params._key, value))
{
value = params._defaultStringValue;
value = params._defaultValue.toString();
}
if (params._password) {
@@ -111,7 +111,7 @@ bool showWebformItem(const ESPEasy_key_value_store& store,
{
int64_t value;
if (!store.getValueAsInt(params._key, value)) { value = params._defaultIntValue; }
if (!store.getValueAsInt(params._key, value)) { value = params._defaultValue.toInt(); }
addFormNumericBox(
params._label,
id,
@@ -142,7 +142,7 @@ bool showWebformItem(const ESPEasy_key_value_store& store,
{
float value{};
if (!store.getValue(params._key, value)) { value = params._defaultFloatValue; }
if (!store.getValue(params._key, value)) { value = params._defaultValue.toFloat(); }
addFormFloatNumberBox(
params._label,
id,
@@ -165,7 +165,7 @@ bool showWebformItem(const ESPEasy_key_value_store& store,
{
bool value{};
if (!store.getValue(params._key, value)) { value = params._defaultIntValue != 0; }
if (!store.getValue(params._key, value)) { value = params._defaultValue.toInt() != 0; }
addFormCheckBox(
params._label,
id,
@@ -185,7 +185,7 @@ void showFormSelector(const ESPEasy_key_value_store& store,
{
int64_t value{};
if (!store.getValueAsInt(params._key, value)) { value = params._defaultIntValue; }
if (!store.getValueAsInt(params._key, value)) { value = params._defaultValue.toInt(); }
selector.addFormSelector(params._label, params._id, value);
}
@@ -40,15 +40,11 @@ struct WebFormItemParams {
bool _password{};
String _pattern;
int64_t _defaultIntValue{};
double _defaultFloatValue{};
String _defaultStringValue;
ValueStruct _defaultValue;
};
bool showWebformItem(const ESPEasy_key_value_store& store,
WebFormItemParams params);
WebFormItemParams&& params);
void showFormSelector(const ESPEasy_key_value_store& store,
const FormSelectorOptions & selector,