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 = "";
|
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
|
* Lightweight String to Float, because atof() or strtof() takes 10KB
|
||||||
*
|
*
|
||||||
* To remove code, exponents are not parsed
|
* To remove code, exponents are not parsed
|
||||||
* (commented out below, just in case we need them after all)
|
* (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/
|
// 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;
|
const char* p = s;
|
||||||
float value = 0.;
|
double value = 0.;
|
||||||
int32_t sign = +1;
|
int32_t sign = +1;
|
||||||
float factor;
|
double factor;
|
||||||
|
uint32_t base = 10; // support hex mode if start with Ox or OX
|
||||||
// unsigned int expo;
|
// unsigned int expo;
|
||||||
|
|
||||||
while (isspace(*p)){ // skip any leading white-spaces
|
while (isspace(*p)){ // skip any leading white-spaces
|
||||||
|
@ -45,22 +56,30 @@ float json_strtof(const char* s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case '-': sign = -1;
|
case '-': sign = -1; // no break on purpose
|
||||||
case '+': p++;
|
case '+': p++;
|
||||||
default : break;
|
default : break;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((unsigned int)(*p - '0') < 10u) {
|
if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { // detect hex mode
|
||||||
value = value*10 + (*p++ - '0');
|
base = 16;
|
||||||
|
p += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t v; // temp nibble value
|
||||||
|
while ((v = asc2byte(*p)) >= 0) {
|
||||||
|
value = value * base + v;
|
||||||
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*p == '.' ) {
|
if (*p == '.' ) {
|
||||||
factor = 1.0f;
|
factor = 1.0f;
|
||||||
|
|
||||||
p++;
|
p++;
|
||||||
while ((unsigned int)(*p - '0') < 10u) {
|
while ((v = asc2byte(*p)) >= 0) {
|
||||||
factor *= 0.1f;
|
factor /= base;
|
||||||
value += (*p++ - '0') * factor;
|
value += v * factor;
|
||||||
|
p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,9 @@ public:
|
||||||
JsonParserObject getObject(void) const;
|
JsonParserObject getObject(void) const;
|
||||||
JsonParserArray getArray(void) const;
|
JsonParserArray getArray(void) const;
|
||||||
|
|
||||||
|
// general parser from string to int/hex/float
|
||||||
|
static double json_strtof(const char* s);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// the following should be 'protected' but then it can't be accessed by iterators
|
// the following should be 'protected' but then it can't be accessed by iterators
|
||||||
const jsmntok_t * t;
|
const jsmntok_t * t;
|
||||||
|
|
|
@ -191,6 +191,9 @@ public:
|
||||||
int32_t getInt(void) const;
|
int32_t getInt(void) const;
|
||||||
uint32_t getUInt(void) const;
|
uint32_t getUInt(void) const;
|
||||||
bool getBool(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;
|
const SBuffer * getRaw(void) const;
|
||||||
|
|
||||||
// always return a point to a string, if not defined then empty string.
|
// 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
|
// 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 {
|
float Z_attribute::getFloat(void) const {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Za_type::Za_bool:
|
case Za_type::Za_bool:
|
||||||
|
|
|
@ -235,7 +235,7 @@ void ZbApplyMultiplier(double &val_d, int8_t multiplier) {
|
||||||
// Write Tuya-Moes attribute
|
// Write Tuya-Moes attribute
|
||||||
//
|
//
|
||||||
bool ZbTuyaWrite(SBuffer & buf, const Z_attribute & attr) {
|
bool ZbTuyaWrite(SBuffer & buf, const Z_attribute & attr) {
|
||||||
double val_d = attr.getFloat();
|
double val_d = attr.getOptimisticDouble();
|
||||||
const char * val_str = attr.getStr();
|
const char * val_str = attr.getStr();
|
||||||
|
|
||||||
if (attr.key_is_str) { return false; } // couldn't find attr if so skip
|
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
|
// Send Attribute Write, apply mutlipliers before
|
||||||
//
|
//
|
||||||
bool ZbAppendWriteBuf(SBuffer & buf, const Z_attribute & attr, bool prepend_status_ok) {
|
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();
|
const char * val_str = attr.getStr();
|
||||||
|
|
||||||
if (attr.key_is_str) { return false; } // couldn't find attr if so skip
|
if (attr.key_is_str) { return false; } // couldn't find attr if so skip
|
||||||
|
|
Loading…
Reference in New Issue