mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-27 19:57:38 +00:00
Merge pull request #5574 from tonhuisman/bugfix/TaskValue-update-custom-format-uservar
[Bugfix] Include PLUGIN_FORMAT_USERVAR values for json updates
This commit is contained in:
+13
-34
@@ -7,6 +7,7 @@
|
||||
// #######################################################################################################
|
||||
|
||||
/** Changelog:
|
||||
* 2026-06-30 tonhuisman: Code optimization by moving ul2stringFixed to StringConverter_Numerical
|
||||
* 2025-01-12 tonhuisman: Add support for MQTT AutoDiscovery (not supported for Shift registers)
|
||||
* 2022-02-27 tonhuisman: Rename plugin title to Output - Shift registers (74HC595)
|
||||
* 2022-02-25 tonhuisman: Again rename commands, now using separate prefix shiftout and the rest of the previous command as subcommand.
|
||||
@@ -59,19 +60,6 @@
|
||||
|
||||
# include "./src/PluginStructs/P126_data_struct.h"
|
||||
|
||||
// TODO tonhuisman: ? Move to StringConverter ? though it is a bit specific, can also be used by P129
|
||||
String P126_ul2stringFixed(uint32_t value, uint8_t base) {
|
||||
uint64_t val = static_cast<uint64_t>(value);
|
||||
|
||||
val &= 0x0ffffffff; // Keep 32 bits
|
||||
val |= 0x100000000; // Set bit just left of 32 bits so we will see the leading zeroes
|
||||
String valStr = ull2String(val, base);
|
||||
|
||||
valStr.remove(0, 1); // Delete leading 1 we added
|
||||
valStr.toUpperCase(); // uppercase hex for readability
|
||||
return valStr;
|
||||
}
|
||||
|
||||
boolean Plugin_126(uint8_t function, struct EventStruct *event, String& string)
|
||||
{
|
||||
boolean success = false;
|
||||
@@ -286,15 +274,16 @@ boolean Plugin_126(uint8_t function, struct EventStruct *event, String& string)
|
||||
(P126_CONFIG_FLAGS_GET_OUTPUT_SELECTION == P126_OUTPUT_HEXBIN)) {
|
||||
string += '0';
|
||||
string += (P126_CONFIG_FLAGS_GET_VALUES_DISPLAY ? 'b' : 'x');
|
||||
string += P126_ul2stringFixed(UserVar.getUint32(event->TaskIndex, event->idx),
|
||||
# ifdef P126_SHOW_VALUES
|
||||
(P126_CONFIG_FLAGS_GET_VALUES_DISPLAY ? BIN :
|
||||
# endif // ifdef P126_SHOW_VALUES
|
||||
HEX
|
||||
# ifdef P126_SHOW_VALUES
|
||||
)
|
||||
# endif // ifdef P126_SHOW_VALUES
|
||||
);
|
||||
|
||||
string += ul2stringFixed(UserVar.getUint32(event->TaskIndex, event->idx),
|
||||
# ifdef P126_SHOW_VALUES
|
||||
(P126_CONFIG_FLAGS_GET_VALUES_DISPLAY ? BIN :
|
||||
# endif // ifdef P126_SHOW_VALUES
|
||||
HEX
|
||||
# ifdef P126_SHOW_VALUES
|
||||
)
|
||||
# endif // ifdef P126_SHOW_VALUES
|
||||
, 1 == event->ParN[event->idx]);
|
||||
}
|
||||
success = true;
|
||||
break;
|
||||
@@ -308,21 +297,15 @@ boolean Plugin_126(uint8_t function, struct EventStruct *event, String& string)
|
||||
const String abcd = F("ABCDEFGH"); // In case anyone dares to extend
|
||||
// VARS_PER_TASK to 8...
|
||||
const uint16_t endCheck = P126_CONFIG_CHIP_COUNT + (P126_CONFIG_CHIP_COUNT == 255 ? 3 : 4); // 4(.0) = nr of bytes in an uint32_t.
|
||||
const uint16_t maxVar = min(static_cast<uint8_t>(VARS_PER_TASK), static_cast<uint8_t>(ceil(P126_CONFIG_CHIP_COUNT / 4.0)));
|
||||
uint8_t dotInsert;
|
||||
uint8_t dotOffset;
|
||||
const uint16_t maxVar = min(static_cast<uint8_t>(VARS_PER_TASK), static_cast<uint8_t>(ceilf(P126_CONFIG_CHIP_COUNT / 4.0f)));
|
||||
|
||||
for (uint16_t varNr = 0; varNr < maxVar; ++varNr) {
|
||||
if (P126_CONFIG_FLAGS_GET_VALUES_DISPLAY) {
|
||||
label = F("Bin");
|
||||
state = F("0b");
|
||||
dotInsert = 10;
|
||||
dotOffset = 9;
|
||||
} else {
|
||||
label = F("Hex");
|
||||
state = F("0x");
|
||||
dotInsert = 4;
|
||||
dotOffset = 3;
|
||||
}
|
||||
label += strformat(F(" State_%s "), abcd.substring(varNr, varNr + 1).c_str());
|
||||
|
||||
@@ -331,11 +314,7 @@ boolean Plugin_126(uint8_t function, struct EventStruct *event, String& string)
|
||||
label += (P126_CONFIG_SHOW_OFFSET + (4 * varNr) + 1); // 4 = nr of bytes in an uint32_t.
|
||||
|
||||
if ((P126_CONFIG_SHOW_OFFSET + (4 * varNr) + 4) <= endCheck) { // Only show if still in range
|
||||
state += P126_ul2stringFixed(UserVar.getUint32(event->TaskIndex, varNr), P126_CONFIG_FLAGS_GET_VALUES_DISPLAY ? BIN : HEX);
|
||||
|
||||
for (uint8_t i = 0; i < 3; ++i, dotInsert += dotOffset) { // Insert readability separators
|
||||
state = state.substring(0, dotInsert) + '.' + state.substring(dotInsert);
|
||||
}
|
||||
state += ul2stringFixed(UserVar.getUint32(event->TaskIndex, varNr), P126_CONFIG_FLAGS_GET_VALUES_DISPLAY ? BIN : HEX, true);
|
||||
pluginWebformShowValue(event->TaskIndex, VARS_PER_TASK + varNr, label, state, true);
|
||||
}
|
||||
}
|
||||
|
||||
+22
-42
@@ -7,6 +7,7 @@
|
||||
// #######################################################################################################
|
||||
|
||||
/** Changelog:
|
||||
* 2026-06-30 tonhuisman: Code optimization by moving ul2stringFixed to StringConverter_Numerical
|
||||
* 2025-06-14 tonhuisman: Add support for Custom Value Type per task value
|
||||
* 2025-01-12 tonhuisman: Add support for MQTT AutoDiscovery (not supported for Shift registers)
|
||||
* 2023-01-04 tonhuisman: Use DIRECT_pin GPIO functions for faster GPIO handling (mostly on ESP32), string optimization
|
||||
@@ -43,19 +44,6 @@
|
||||
|
||||
# include "./src/PluginStructs/P129_data_struct.h"
|
||||
|
||||
// TODO tonhuisman: ? Move to StringConverter ? though it is a bit specific, can also be used by P126
|
||||
String P129_ul2stringFixed(uint32_t value, uint8_t base) {
|
||||
// Set bit just left of 32 bits so we will see the leading zeroes
|
||||
const uint64_t val = static_cast<uint64_t>(value) | 0x100000000ull;
|
||||
|
||||
String valStr = ull2String(val, base).substring(1); // Delete leading 1 we added
|
||||
|
||||
if (base == HEX) {
|
||||
valStr.toUpperCase(); // uppercase hex for readability
|
||||
}
|
||||
return valStr;
|
||||
}
|
||||
|
||||
boolean Plugin_129(uint8_t function, struct EventStruct *event, String& string)
|
||||
{
|
||||
boolean success = false;
|
||||
@@ -146,7 +134,7 @@ boolean Plugin_129(uint8_t function, struct EventStruct *event, String& string)
|
||||
case PLUGIN_GET_DEVICEVALUECOUNT:
|
||||
{
|
||||
event->Par1 = min(static_cast<uint8_t>(VARS_PER_TASK),
|
||||
static_cast<uint8_t>(ceil(P129_CONFIG_CHIP_COUNT / 4.0f)));
|
||||
static_cast<uint8_t>(ceilf(P129_CONFIG_CHIP_COUNT / 4.0f)));
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
@@ -155,7 +143,7 @@ boolean Plugin_129(uint8_t function, struct EventStruct *event, String& string)
|
||||
{
|
||||
event->sensorType = static_cast<Sensor_VType>(
|
||||
min(static_cast<uint8_t>(VARS_PER_TASK),
|
||||
static_cast<uint8_t>(ceil(P129_CONFIG_CHIP_COUNT / 4.0f))));
|
||||
static_cast<uint8_t>(ceilf(P129_CONFIG_CHIP_COUNT / 4.0f))));
|
||||
event->idx = 0;
|
||||
success = true;
|
||||
break;
|
||||
@@ -187,6 +175,7 @@ boolean Plugin_129(uint8_t function, struct EventStruct *event, String& string)
|
||||
F("Number of chips (Q7 → DS)"), F("chipcnt"), P129_CONFIG_CHIP_COUNT);
|
||||
addUnit(concat(F("Daisychained 1.."), P129_MAX_CHIP_COUNT));
|
||||
# ifndef LIMIT_BUILD_SIZE
|
||||
|
||||
// addFormNote(F("Changing the number of chips will reload the page and update the Event configuration."));
|
||||
# endif // ifndef LIMIT_BUILD_SIZE
|
||||
}
|
||||
@@ -240,12 +229,12 @@ boolean Plugin_129(uint8_t function, struct EventStruct *event, String& string)
|
||||
if (i % 4 == 0) {
|
||||
bits = PCONFIG_ULONG(i / 4) & 0x0ffffffff;
|
||||
off = 0;
|
||||
# ifndef P129_DEBUG_LOG
|
||||
# ifdef P129_DEBUG_LOG
|
||||
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
addLog(LOG_LEVEL_INFO, strformat(F("74HC165 Reading from: %d, bits: %s"), i / 4, P129_ul2stringFixed(bits, BIN).c_str()));
|
||||
addLog(LOG_LEVEL_INFO, strformat(F("74HC165 Reading from: %d, bits: %s"), i / 4, ul2stringFixed(bits, BIN, false).c_str()));
|
||||
}
|
||||
# endif // ifndef P129_DEBUG_LOG
|
||||
# endif // ifdef P129_DEBUG_LOG
|
||||
}
|
||||
html_TR();
|
||||
addHtml(F("<td align =\"center\">"));
|
||||
@@ -310,15 +299,15 @@ boolean Plugin_129(uint8_t function, struct EventStruct *event, String& string)
|
||||
}
|
||||
PCONFIG_ULONG(i / 4) = bits;
|
||||
|
||||
# ifndef P129_DEBUG_LOG
|
||||
# ifdef P129_DEBUG_LOG
|
||||
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO) && ((i % 4 == 3) || (i == P129_CONFIG_CHIP_COUNT))) {
|
||||
addLog(LOG_LEVEL_INFO, strformat(F("74HC165 Writing to: %d, offset: %d, bits: %s"),
|
||||
i / 4,
|
||||
off * 8,
|
||||
P129_ul2stringFixed(bits, BIN).c_str()));
|
||||
ul2stringFixed(bits, BIN, false).c_str()));
|
||||
}
|
||||
# endif // ifndef P129_DEBUG_LOG
|
||||
# endif // ifdef P129_DEBUG_LOG
|
||||
off++;
|
||||
}
|
||||
success = true;
|
||||
@@ -391,15 +380,16 @@ boolean Plugin_129(uint8_t function, struct EventStruct *event, String& string)
|
||||
(P129_CONFIG_FLAGS_GET_OUTPUT_SELECTION == P129_OUTPUT_HEXBIN)) {
|
||||
string += '0';
|
||||
string += (P129_CONFIG_FLAGS_GET_VALUES_DISPLAY ? 'b' : 'x');
|
||||
string += P129_ul2stringFixed(UserVar.getUint32(event->TaskIndex, event->idx),
|
||||
# ifdef P129_SHOW_VALUES
|
||||
(P129_CONFIG_FLAGS_GET_VALUES_DISPLAY ? BIN :
|
||||
# endif // ifdef P129_SHOW_VALUES
|
||||
HEX
|
||||
# ifdef P129_SHOW_VALUES
|
||||
)
|
||||
# endif // ifdef P129_SHOW_VALUES
|
||||
);
|
||||
|
||||
string += ul2stringFixed(UserVar.getUint32(event->TaskIndex, event->idx),
|
||||
# ifdef P129_SHOW_VALUES
|
||||
(P129_CONFIG_FLAGS_GET_VALUES_DISPLAY ? BIN :
|
||||
# endif // ifdef P129_SHOW_VALUES
|
||||
HEX
|
||||
# ifdef P129_SHOW_VALUES
|
||||
)
|
||||
# endif // ifdef P129_SHOW_VALUES
|
||||
, 1 == event->ParN[event->idx]);
|
||||
}
|
||||
success = true;
|
||||
break;
|
||||
@@ -412,21 +402,15 @@ boolean Plugin_129(uint8_t function, struct EventStruct *event, String& string)
|
||||
state.reserve(40);
|
||||
const String abcd = F("ABCDEFGH"); // In case anyone dares to extend VARS_PER_TASK to 8...
|
||||
const uint16_t endCheck = P129_CONFIG_CHIP_COUNT + 4; // 4(.0) = nr of bytes in an uint32_t.
|
||||
const uint16_t maxVar = min(static_cast<uint8_t>(VARS_PER_TASK), static_cast<uint8_t>(ceil(P129_CONFIG_CHIP_COUNT / 4.0f)));
|
||||
uint8_t dotInsert;
|
||||
uint8_t dotOffset;
|
||||
const uint16_t maxVar = min(static_cast<uint8_t>(VARS_PER_TASK), static_cast<uint8_t>(ceilf(P129_CONFIG_CHIP_COUNT / 4.0f)));
|
||||
|
||||
for (uint16_t varNr = 0; varNr < maxVar; ++varNr) {
|
||||
if (P129_CONFIG_FLAGS_GET_VALUES_DISPLAY) {
|
||||
label = F("Bin");
|
||||
state = F("0b");
|
||||
dotInsert = 10;
|
||||
dotOffset = 9;
|
||||
} else {
|
||||
label = F("Hex");
|
||||
state = F("0x");
|
||||
dotInsert = 4;
|
||||
dotOffset = 3;
|
||||
}
|
||||
label += strformat(F(" State_%s "), abcd.substring(varNr, varNr + 1).c_str());
|
||||
|
||||
@@ -435,11 +419,7 @@ boolean Plugin_129(uint8_t function, struct EventStruct *event, String& string)
|
||||
label += (P129_CONFIG_SHOW_OFFSET + (4 * varNr) + 1); // 4 = nr of bytes in an uint32_t.
|
||||
|
||||
if ((P129_CONFIG_SHOW_OFFSET + (4 * varNr) + 4) <= endCheck) { // Only show if still in range
|
||||
state += P129_ul2stringFixed(UserVar.getUint32(event->TaskIndex, varNr), P129_CONFIG_FLAGS_GET_VALUES_DISPLAY ? BIN : HEX);
|
||||
|
||||
for (uint8_t i = 0; i < 3; ++i, dotInsert += dotOffset) { // Insert readability separators
|
||||
state = state.substring(0, dotInsert) + '.' + state.substring(dotInsert);
|
||||
}
|
||||
state += ul2stringFixed(UserVar.getUint32(event->TaskIndex, varNr), P129_CONFIG_FLAGS_GET_VALUES_DISPLAY ? BIN : HEX, true);
|
||||
pluginWebformShowValue(event->TaskIndex, VARS_PER_TASK + varNr, label, state, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,6 +95,42 @@ String ll2String(int64_t value, uint8_t base) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* format an uint32_t with 0-prefixed in the provided base of 2, 16 and insert an optional dot as separator for each byte
|
||||
* separator only applied for base 2 and 16
|
||||
*/
|
||||
String ul2stringFixed(uint32_t value, uint8_t base, bool dotSeparator) {
|
||||
// Set bit just left of 32 bits so we will see the leading zeroes
|
||||
const uint64_t val = static_cast<uint64_t>(value) | 0x100000000ull;
|
||||
|
||||
String valStr = ull2String(val, base).substring(1); // Delete leading 1 we added
|
||||
|
||||
if (base == HEX) {
|
||||
valStr.toUpperCase(); // uppercase hex for readability
|
||||
}
|
||||
|
||||
if (dotSeparator) {
|
||||
uint8_t dotInsert{};
|
||||
uint8_t dotOffset{};
|
||||
|
||||
if (BIN == base) {
|
||||
dotInsert = 10;
|
||||
dotOffset = 9;
|
||||
} else
|
||||
if (HEX == base) {
|
||||
dotInsert += 4;
|
||||
dotOffset = 3;
|
||||
}
|
||||
|
||||
if (dotInsert) {
|
||||
for (uint8_t i = 0; i < 3; ++i, dotInsert += dotOffset) { // Insert readability separators
|
||||
valStr = valStr.substring(0, dotInsert) + '.' + valStr.substring(dotInsert);
|
||||
}
|
||||
}
|
||||
}
|
||||
return valStr;
|
||||
}
|
||||
|
||||
String trimTrailingZeros(const String& value) {
|
||||
String res(value);
|
||||
int dot_pos = res.lastIndexOf('.');
|
||||
|
||||
@@ -35,6 +35,11 @@ String ull2String(uint64_t value,
|
||||
String ll2String(int64_t value,
|
||||
uint8_t base = 10);
|
||||
|
||||
String ul2stringFixed(uint32_t value,
|
||||
uint8_t base,
|
||||
bool dotSeparator);
|
||||
|
||||
|
||||
String trimTrailingZeros(const String& value);
|
||||
|
||||
String toStringNoZero(int64_t value);
|
||||
|
||||
@@ -35,7 +35,7 @@ bool P126_data_struct::plugin_init(struct EventStruct *event) {
|
||||
}
|
||||
|
||||
const uint16_t maxVar = min(static_cast<uint8_t>(VARS_PER_TASK),
|
||||
static_cast<uint8_t>(ceil((P126_CONFIG_CHIP_COUNT - P126_CONFIG_SHOW_OFFSET) / 4.0)));
|
||||
static_cast<uint8_t>(ceilf((P126_CONFIG_CHIP_COUNT - P126_CONFIG_SHOW_OFFSET) / 4.0f)));
|
||||
uint32_t par;
|
||||
|
||||
for (uint16_t varNr = 0; varNr < maxVar; ++varNr) {
|
||||
|
||||
@@ -519,6 +519,29 @@ void handle_json()
|
||||
#endif // if FEATURE_STRING_VARIABLES
|
||||
uom);
|
||||
}
|
||||
|
||||
if (Device[DeviceIndex].HasFormatUserVar) {
|
||||
struct EventStruct TempEvent(TaskIndex);
|
||||
|
||||
for (uint8_t x = 0; x < valueCount; x++)
|
||||
{
|
||||
String value;
|
||||
TempEvent.idx = x;
|
||||
TempEvent.ParN[x] = 1; // Get formatted version of the value
|
||||
PluginCall(PLUGIN_FORMAT_USERVAR, &TempEvent, value);
|
||||
|
||||
if (!value.isEmpty()) {
|
||||
handle_json_stream_task_value_data(taskValueWriter.get(),
|
||||
VARS_PER_TASK + x + 1,
|
||||
Cache.getTaskDeviceValueName(TaskIndex, x),
|
||||
255,
|
||||
value,
|
||||
EMPTY_STRING,
|
||||
EMPTY_STRING);
|
||||
}
|
||||
}
|
||||
// FIXME tonhuisman: HasFormatUserVar is not really compatible with Derived Values...
|
||||
}
|
||||
#if FEATURE_STRING_VARIABLES
|
||||
|
||||
if (Settings.ShowDerivedTaskValues(TaskIndex)) {
|
||||
|
||||
Reference in New Issue
Block a user