mirror of https://github.com/arendst/Tasmota.git
Merge pull request #11201 from s-hadinger/zigbee_str_as_num
Zigbee allow numbers as string
This commit is contained in:
commit
2e7cf79111
|
@ -26,18 +26,29 @@
|
|||
|
||||
const char * k_current_json_buffer = "";
|
||||
|
||||
// returns nibble value or -1 if not an hex digit
|
||||
static int32_t asc2byte(char chr) {
|
||||
if (chr >= '0' && chr <= '9') { return chr - '0'; }
|
||||
else if (chr >= 'A' && chr <= 'F') { return chr + 10 - 'A'; }
|
||||
else if (chr >= 'a' && chr <= 'f') { return chr + 10 - 'a'; }
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Lightweight String to Float, because atof() or strtof() takes 10KB
|
||||
*
|
||||
* To remove code, exponents are not parsed
|
||||
* (commented out below, just in case we need them after all)
|
||||
*
|
||||
* Moved to double to be able to parse 32 bits int as well without loss in accuracy
|
||||
\*********************************************************************************************/
|
||||
// Inspired from https://searchcode.com/codesearch/view/22115068/
|
||||
float json_strtof(const char* s) {
|
||||
double JsonParserToken::json_strtof(const char* s) {
|
||||
const char* p = s;
|
||||
float value = 0.;
|
||||
double value = 0.;
|
||||
int32_t sign = +1;
|
||||
float factor;
|
||||
double factor;
|
||||
uint32_t base = 10; // support hex mode if start with Ox or OX
|
||||
// unsigned int expo;
|
||||
|
||||
while (isspace(*p)){ // skip any leading white-spaces
|
||||
|
@ -45,22 +56,30 @@ float json_strtof(const char* s) {
|
|||
}
|
||||
|
||||
switch (*p) {
|
||||
case '-': sign = -1;
|
||||
case '-': sign = -1; // no break on purpose
|
||||
case '+': p++;
|
||||
default : break;
|
||||
}
|
||||
|
||||
while ((unsigned int)(*p - '0') < 10u) {
|
||||
value = value*10 + (*p++ - '0');
|
||||
if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { // detect hex mode
|
||||
base = 16;
|
||||
p += 2;
|
||||
}
|
||||
|
||||
int32_t v; // temp nibble value
|
||||
while ((v = asc2byte(*p)) >= 0) {
|
||||
value = value * base + v;
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p == '.' ) {
|
||||
factor = 1.0f;
|
||||
|
||||
p++;
|
||||
while ((unsigned int)(*p - '0') < 10u) {
|
||||
factor *= 0.1f;
|
||||
value += (*p++ - '0') * factor;
|
||||
while ((v = asc2byte(*p)) >= 0) {
|
||||
factor /= base;
|
||||
value += v * factor;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -114,6 +114,9 @@ public:
|
|||
JsonParserObject getObject(void) const;
|
||||
JsonParserArray getArray(void) const;
|
||||
|
||||
// general parser from string to int/hex/float
|
||||
static double json_strtof(const char* s);
|
||||
|
||||
public:
|
||||
// the following should be 'protected' but then it can't be accessed by iterators
|
||||
const jsmntok_t * t;
|
||||
|
|
|
@ -191,6 +191,9 @@ public:
|
|||
int32_t getInt(void) const;
|
||||
uint32_t getUInt(void) const;
|
||||
bool getBool(void) const;
|
||||
// optimistically try to get any value as literal or in string - double to not lose precision for 32 bits
|
||||
double getOptimisticDouble(void) const;
|
||||
//
|
||||
const SBuffer * getRaw(void) const;
|
||||
|
||||
// always return a point to a string, if not defined then empty string.
|
||||
|
@ -437,6 +440,17 @@ JsonGeneratorArray & Z_attribute::newJsonArray(void) {
|
|||
}
|
||||
|
||||
// get num values
|
||||
double Z_attribute::getOptimisticDouble(void) const {
|
||||
switch (type) {
|
||||
case Za_type::Za_bool:
|
||||
case Za_type::Za_uint: return (double) val.uval32;
|
||||
case Za_type::Za_int: return (double) val.ival32;
|
||||
case Za_type::Za_float: return (double) val.fval;
|
||||
case Za_type::Za_str: return JsonParserToken::json_strtof(val.sval);
|
||||
default: return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
float Z_attribute::getFloat(void) const {
|
||||
switch (type) {
|
||||
case Za_type::Za_bool:
|
||||
|
|
|
@ -235,7 +235,7 @@ void ZbApplyMultiplier(double &val_d, int8_t multiplier) {
|
|||
// Write Tuya-Moes attribute
|
||||
//
|
||||
bool ZbTuyaWrite(SBuffer & buf, const Z_attribute & attr) {
|
||||
double val_d = attr.getFloat();
|
||||
double val_d = attr.getOptimisticDouble();
|
||||
const char * val_str = attr.getStr();
|
||||
|
||||
if (attr.key_is_str) { return false; } // couldn't find attr if so skip
|
||||
|
@ -294,7 +294,7 @@ bool ZbTuyaWrite(SBuffer & buf, const Z_attribute & attr) {
|
|||
// Send Attribute Write, apply mutlipliers before
|
||||
//
|
||||
bool ZbAppendWriteBuf(SBuffer & buf, const Z_attribute & attr, bool prepend_status_ok) {
|
||||
double val_d = attr.getFloat();
|
||||
double val_d = attr.getOptimisticDouble();
|
||||
const char * val_str = attr.getStr();
|
||||
|
||||
if (attr.key_is_str) { return false; } // couldn't find attr if so skip
|
||||
|
|
Loading…
Reference in New Issue