mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 00:09:51 +03:00
Render values in Web natively #70
This commit is contained in:
@@ -39,7 +39,8 @@ static const __FlashStringHelper * DeviceValueUOM_s[] __attribute__((__aligned__
|
||||
F_(kb),
|
||||
F_(seconds),
|
||||
F_(dbm),
|
||||
F_(num)
|
||||
F_(num),
|
||||
F_(bool)
|
||||
|
||||
};
|
||||
|
||||
@@ -543,7 +544,7 @@ std::string EMSdevice::get_value_uom(const char * key) {
|
||||
for (const auto & dv : devicevalues_) {
|
||||
if (dv.full_name != nullptr) {
|
||||
if (uuid::read_flash_string(dv.full_name) == p) {
|
||||
// ignore TIME since "minutes" is already included
|
||||
// ignore TIME since "minutes" is already added to the string value
|
||||
if ((dv.uom == DeviceValueUOM::NONE) || (dv.uom == DeviceValueUOM::MINUTES)) {
|
||||
break;
|
||||
}
|
||||
@@ -555,37 +556,34 @@ std::string EMSdevice::get_value_uom(const char * key) {
|
||||
return std::string{}; // not found
|
||||
}
|
||||
|
||||
// prepare array of device values, as 3 elements serialized (name, value, uom) in array to send to Web UI
|
||||
// returns number of elements
|
||||
bool EMSdevice::generate_values_json_web(JsonObject & json) {
|
||||
// prepare array of device values used for the Web UI
|
||||
// v = value, u=uom, n=name, c=cmd
|
||||
void EMSdevice::generate_values_json_web(JsonObject & json) {
|
||||
json["name"] = to_string_short();
|
||||
JsonArray data = json.createNestedArray("data");
|
||||
|
||||
uint8_t num_elements = 0;
|
||||
|
||||
for (const auto & dv : devicevalues_) {
|
||||
// ignore if full_name empty
|
||||
if (dv.full_name != nullptr) {
|
||||
JsonObject obj; // create the object, if needed
|
||||
|
||||
// handle Booleans (true, false)
|
||||
if ((dv.type == DeviceValueType::BOOL) && Helpers::hasValue(*(uint8_t *)(dv.value_p), EMS_VALUE_BOOL)) {
|
||||
// see if we have options for the bool's
|
||||
if (dv.options_size == 2) {
|
||||
data.add(*(uint8_t *)(dv.value_p) ? dv.options[0] : dv.options[1]);
|
||||
} else {
|
||||
// always render booleans as on or off
|
||||
data.add(*(uint8_t *)(dv.value_p) ? F_(on) : F_(off));
|
||||
}
|
||||
obj = data.createNestedObject();
|
||||
obj["v"] = *(bool *)(dv.value_p);
|
||||
}
|
||||
|
||||
// handle TEXT strings
|
||||
else if ((dv.type == DeviceValueType::TEXT) && (Helpers::hasValue((char *)(dv.value_p)))) {
|
||||
data.add((char *)(dv.value_p));
|
||||
obj = data.createNestedObject();
|
||||
obj["v"] = (char *)(dv.value_p);
|
||||
}
|
||||
|
||||
// handle ENUMs
|
||||
else if ((dv.type == DeviceValueType::ENUM) && Helpers::hasValue(*(uint8_t *)(dv.value_p))) {
|
||||
if (*(uint8_t *)(dv.value_p) < dv.options_size) {
|
||||
data.add(dv.options[*(uint8_t *)(dv.value_p)]);
|
||||
obj = data.createNestedObject();
|
||||
obj["v"] = dv.options[*(uint8_t *)(dv.value_p)];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -596,83 +594,55 @@ bool EMSdevice::generate_values_json_web(JsonObject & json) {
|
||||
// the nested if's is necessary due to the way the ArduinoJson templates are pre-processed by the compiler
|
||||
uint8_t divider = (dv.options_size == 1) ? Helpers::atoint(uuid::read_flash_string(dv.options[0]).c_str()) : 0;
|
||||
|
||||
// INT
|
||||
if ((dv.type == DeviceValueType::INT) && Helpers::hasValue(*(int8_t *)(dv.value_p))) {
|
||||
if (divider) {
|
||||
data.add(Helpers::round2(*(int8_t *)(dv.value_p), divider));
|
||||
} else {
|
||||
data.add(*(int8_t *)(dv.value_p));
|
||||
}
|
||||
obj = data.createNestedObject();
|
||||
obj["v"] = (divider) ? Helpers::round2(*(int8_t *)(dv.value_p), divider) : *(int8_t *)(dv.value_p);
|
||||
} else if ((dv.type == DeviceValueType::UINT) && Helpers::hasValue(*(uint8_t *)(dv.value_p))) {
|
||||
if (divider) {
|
||||
data.add(Helpers::round2(*(uint8_t *)(dv.value_p), divider));
|
||||
} else {
|
||||
data.add(*(uint8_t *)(dv.value_p));
|
||||
}
|
||||
obj = data.createNestedObject();
|
||||
obj["v"] = (divider) ? Helpers::round2(*(uint8_t *)(dv.value_p), divider) : *(uint8_t *)(dv.value_p);
|
||||
} else if ((dv.type == DeviceValueType::SHORT) && Helpers::hasValue(*(int16_t *)(dv.value_p))) {
|
||||
if (divider) {
|
||||
data.add(Helpers::round2(*(int16_t *)(dv.value_p), divider));
|
||||
} else {
|
||||
data.add(*(int16_t *)(dv.value_p));
|
||||
}
|
||||
obj = data.createNestedObject();
|
||||
obj["v"] = (divider) ? Helpers::round2(*(int16_t *)(dv.value_p), divider) : *(int16_t *)(dv.value_p);
|
||||
} else if ((dv.type == DeviceValueType::USHORT) && Helpers::hasValue(*(uint16_t *)(dv.value_p))) {
|
||||
if (divider) {
|
||||
data.add(Helpers::round2(*(uint16_t *)(dv.value_p), divider));
|
||||
} else {
|
||||
data.add(*(uint16_t *)(dv.value_p));
|
||||
}
|
||||
obj = data.createNestedObject();
|
||||
obj["v"] = (divider) ? Helpers::round2(*(uint16_t *)(dv.value_p), divider) : *(uint16_t *)(dv.value_p);
|
||||
} else if ((dv.type == DeviceValueType::ULONG) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
|
||||
if (divider) {
|
||||
data.add(Helpers::round2(*(uint32_t *)(dv.value_p), divider));
|
||||
} else {
|
||||
data.add(*(uint32_t *)(dv.value_p));
|
||||
}
|
||||
obj = data.createNestedObject();
|
||||
obj["v"] = (divider) ? Helpers::round2(*(uint32_t *)(dv.value_p), divider) : *(uint32_t *)(dv.value_p);
|
||||
} else if ((dv.type == DeviceValueType::TIME) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
|
||||
uint32_t time_value = *(uint32_t *)(dv.value_p);
|
||||
time_value = (divider) ? time_value / divider : time_value; // sometimes we need to divide by 60
|
||||
char time_s[40];
|
||||
snprintf_P(time_s, 40, PSTR("%d days %d hours %d minutes"), (time_value / 1440), ((time_value % 1440) / 60), (time_value % 60));
|
||||
data.add(time_s);
|
||||
obj = data.createNestedObject();
|
||||
obj["v"] = (divider) ? time_value / divider : time_value; // sometimes we need to divide by 60
|
||||
}
|
||||
}
|
||||
|
||||
// check if we've added a data element by comparing the size
|
||||
// then add the remaining elements
|
||||
uint8_t sz = data.size();
|
||||
if (sz > num_elements) {
|
||||
// check if we've added a data element then add the remaining elements
|
||||
if (obj.containsKey("v")) {
|
||||
// add the unit of measure (uom)
|
||||
if (dv.uom == DeviceValueUOM::MINUTES) {
|
||||
data.add(nullptr); // use null for time/date
|
||||
} else {
|
||||
data.add(uom_to_string(dv.uom));
|
||||
}
|
||||
obj["u"] = dv.uom;
|
||||
|
||||
// add name, prefixing the tag if it exists
|
||||
if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) {
|
||||
data.add(dv.full_name);
|
||||
obj["n"] = dv.full_name;
|
||||
} else {
|
||||
char name[50];
|
||||
snprintf_P(name, sizeof(name), "(%s) %s", tag_to_string(dv.tag).c_str(), uuid::read_flash_string(dv.full_name).c_str());
|
||||
data.add(name);
|
||||
obj["n"] = name;
|
||||
}
|
||||
|
||||
// add the name of the Command function if it exists
|
||||
if (dv.has_cmd) {
|
||||
if (dv.tag >= DeviceValueTAG::TAG_HC1) {
|
||||
data.add(tag_to_string(dv.tag) + "/" + uuid::read_flash_string(dv.short_name));
|
||||
obj["c"] = tag_to_string(dv.tag) + "/" + uuid::read_flash_string(dv.short_name);
|
||||
} else {
|
||||
data.add(dv.short_name);
|
||||
obj["c"] = dv.short_name;
|
||||
}
|
||||
} else {
|
||||
data.add("");
|
||||
obj["c"] = "";
|
||||
}
|
||||
|
||||
num_elements = sz + 3; // increase count by 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (num_elements != 0);
|
||||
}
|
||||
|
||||
bool EMSdevice::get_value_info(JsonObject & root, const char * cmd, const int8_t id) {
|
||||
@@ -778,9 +748,7 @@ bool EMSdevice::get_value_info(JsonObject & root, const char * cmd, const int8_t
|
||||
break;
|
||||
case DeviceValueType::BOOL: {
|
||||
if (Helpers::hasValue(*(uint8_t *)(dv.value_p), EMS_VALUE_BOOL)) {
|
||||
if (dv.options_size == 2) {
|
||||
json[value] = (bool)(*(uint8_t *)(dv.value_p)) ? dv.options[0] : dv.options[1];
|
||||
} else if (Mqtt::bool_format() == BOOL_FORMAT_ONOFF) {
|
||||
if (Mqtt::bool_format() == BOOL_FORMAT_ONOFF) {
|
||||
json[value] = (bool)(*(uint8_t *)(dv.value_p)) ? F_(on) : F_(off);
|
||||
} else if (Mqtt::bool_format() == BOOL_FORMAT_ONOFF_CAP) {
|
||||
json[value] = (bool)(*(uint8_t *)(dv.value_p)) ? F_(ON) : F_(OFF);
|
||||
@@ -794,10 +762,8 @@ bool EMSdevice::get_value_info(JsonObject & root, const char * cmd, const int8_t
|
||||
json[min] = 0;
|
||||
json[max] = 1;
|
||||
JsonArray enum_ = json.createNestedArray(F_(enum));
|
||||
if (dv.options_size == 2) {
|
||||
enum_.add(dv.options[1]);
|
||||
enum_.add(dv.options[0]);
|
||||
} else if (Mqtt::bool_format() == BOOL_FORMAT_ONOFF) {
|
||||
|
||||
if (Mqtt::bool_format() == BOOL_FORMAT_ONOFF) {
|
||||
enum_.add(F_(off));
|
||||
enum_.add(F_(on));
|
||||
} else if (Mqtt::bool_format() == BOOL_FORMAT_ONOFF_CAP) {
|
||||
@@ -885,31 +851,26 @@ bool EMSdevice::generate_values_json(JsonObject & root, const uint8_t tag_filter
|
||||
|
||||
// handle Booleans (true, false)
|
||||
if ((dv.type == DeviceValueType::BOOL) && Helpers::hasValue(*(uint8_t *)(dv.value_p), EMS_VALUE_BOOL)) {
|
||||
// see if we have options for the bool's
|
||||
if (dv.options_size == 2 && Mqtt::bool_format() != BOOL_FORMAT_10) {
|
||||
json[name] = *(uint8_t *)(dv.value_p) ? dv.options[0] : dv.options[1];
|
||||
// see how to render the value depending on the setting
|
||||
// when in console mode we always use on and off
|
||||
if ((Mqtt::bool_format() == BOOL_FORMAT_ONOFF) || console) {
|
||||
// on or off as strings
|
||||
json[name] = *(uint8_t *)(dv.value_p) ? F_(on) : F_(off);
|
||||
has_value = true;
|
||||
} else if (Mqtt::bool_format() == BOOL_FORMAT_ONOFF_CAP) {
|
||||
// on or off as strings
|
||||
json[name] = *(uint8_t *)(dv.value_p) ? F_(ON) : F_(OFF);
|
||||
has_value = true;
|
||||
} else if (Mqtt::bool_format() == BOOL_FORMAT_TRUEFALSE) {
|
||||
// true or false values (as real booleans, not strings)
|
||||
json[name] = (bool)(*(uint8_t *)(dv.value_p)) ? true : false;
|
||||
has_value = true;
|
||||
} else {
|
||||
// see how to render the value depending on the setting
|
||||
// when in console mode we always use on and off
|
||||
if ((Mqtt::bool_format() == BOOL_FORMAT_ONOFF) || console) {
|
||||
// on or off as strings
|
||||
json[name] = *(uint8_t *)(dv.value_p) ? F_(on) : F_(off);
|
||||
has_value = true;
|
||||
} else if (Mqtt::bool_format() == BOOL_FORMAT_ONOFF_CAP) {
|
||||
// on or off as strings
|
||||
json[name] = *(uint8_t *)(dv.value_p) ? F_(ON) : F_(OFF);
|
||||
has_value = true;
|
||||
} else if (Mqtt::bool_format() == BOOL_FORMAT_TRUEFALSE) {
|
||||
// true or false values (as real booleans, not strings)
|
||||
json[name] = (bool)(*(uint8_t *)(dv.value_p)) ? true : false;
|
||||
has_value = true;
|
||||
} else {
|
||||
// numerical 1 or 0
|
||||
json[name] = (uint8_t)(*(uint8_t *)(dv.value_p)) ? 1 : 0;
|
||||
has_value = true;
|
||||
}
|
||||
// numerical 1 or 0
|
||||
json[name] = (uint8_t)(*(uint8_t *)(dv.value_p)) ? 1 : 0;
|
||||
has_value = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// handle TEXT strings
|
||||
|
||||
Reference in New Issue
Block a user