Range mapped, documentation added
This commit is contained in:
+38
-16
@@ -19,7 +19,8 @@ struct MeterConfig {
|
||||
float currentValue;
|
||||
char name[32] = "";
|
||||
char unit[16] = "";
|
||||
float range = 100.0;
|
||||
float rangeMin = 0.0;
|
||||
float rangeMax = 100.0;
|
||||
};
|
||||
|
||||
struct MqttConfig {
|
||||
@@ -78,7 +79,8 @@ static void loadConfig() {
|
||||
meters[i].currentValue = m["current"] | 0.0f;
|
||||
strlcpy(meters[i].name, m["name"] | "", sizeof(meters[i].name));
|
||||
strlcpy(meters[i].unit, m["unit"] | "", sizeof(meters[i].unit));
|
||||
meters[i].range = m["range"] | 100.0f;
|
||||
meters[i].rangeMin = m["rangeMin"] | m["range"] | 0.0f;
|
||||
meters[i].rangeMax = m["rangeMax"] | m["range"] | 100.0f;
|
||||
}
|
||||
Serial.printf("[CFG] loaded hostname=%s meters=%d mqtt_en=%d\n", hostname, meterCount, mqttCfg.enabled);
|
||||
}
|
||||
@@ -103,7 +105,8 @@ static void saveConfig() {
|
||||
m["current"] = meters[i].currentValue;
|
||||
m["name"] = meters[i].name;
|
||||
m["unit"] = meters[i].unit;
|
||||
m["range"] = meters[i].range;
|
||||
m["rangeMin"] = meters[i].rangeMin;
|
||||
m["rangeMax"] = meters[i].rangeMax;
|
||||
}
|
||||
|
||||
File f = LittleFS.open("/config.json", "w");
|
||||
@@ -140,6 +143,20 @@ static void applyMeters() {
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Range mapping
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static float pctToPhysical(float pct, int idx) {
|
||||
return pct / 100.0f * (meters[idx].rangeMax - meters[idx].rangeMin) + meters[idx].rangeMin;
|
||||
}
|
||||
|
||||
static float physicalToPct(float physical, int idx) {
|
||||
float range = meters[idx].rangeMax - meters[idx].rangeMin;
|
||||
if (range == 0) return 0;
|
||||
return constrain((physical - meters[idx].rangeMin) / range * 100.0f, 0, 100);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// MQTT
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -166,10 +183,10 @@ static void mqttCallback(char* topic, byte* payload, unsigned int len) {
|
||||
String suffix = t.substring(slash);
|
||||
|
||||
if (suffix == "/current/set") {
|
||||
Serial.printf("[MQTT] set meter%d current=%.1f\n", idx, val);
|
||||
meters[idx].currentValue = val;
|
||||
Serial.printf("[MQTT] set meter%d physical=%.1f\n", idx, val);
|
||||
meters[idx].currentValue = physicalToPct(val, idx);
|
||||
if (meters[idx].pin > 0 && meters[idx].maxDuty > 0) {
|
||||
float pct = val / 100.0f * meters[idx].maxDuty / 100.0f;
|
||||
float pct = meters[idx].currentValue / 100.0f * meters[idx].maxDuty / 100.0f;
|
||||
ledcWrite(idx, constrain((int)(pct * 1023), 0, 1023));
|
||||
}
|
||||
saveConfig();
|
||||
@@ -181,7 +198,8 @@ static void mqttPublishCurrent(int idx) {
|
||||
if (!mqttCfg.enabled || !mqttClient.connected()) return;
|
||||
char topic[128], val[16];
|
||||
snprintf(topic, sizeof(topic), "%s/meter/%d/current", mqttCfg.prefix, idx);
|
||||
snprintf(val, sizeof(val), "%.1f", meters[idx].currentValue);
|
||||
float physical = pctToPhysical(meters[idx].currentValue, idx);
|
||||
snprintf(val, sizeof(val), "%.1f", physical);
|
||||
bool ok = mqttClient.publish(topic, val, true);
|
||||
Serial.printf("[MQTT] publish topic=%s val=%s ok=%d\n", topic, val, ok);
|
||||
}
|
||||
@@ -206,8 +224,8 @@ static void mqttPublishDiscovery() {
|
||||
doc["name"] = name;
|
||||
doc["state_topic"] = stat;
|
||||
doc["command_topic"] = stat + "/set";
|
||||
doc["min"] = 0;
|
||||
doc["max"] = 100;
|
||||
doc["min"] = meters[i].rangeMin;
|
||||
doc["max"] = meters[i].rangeMax;
|
||||
doc["step"] = 0.1;
|
||||
if (strlen(meters[i].unit) > 0)
|
||||
doc["unit_of_measurement"] = meters[i].unit;
|
||||
@@ -343,14 +361,16 @@ static void handleRoot() {
|
||||
|
||||
String nameVal = escHtml(meters[i].name);
|
||||
String unitVal = escHtml(meters[i].unit);
|
||||
char rangeStr[8];
|
||||
dtostrf(meters[i].range, 1, 1, rangeStr);
|
||||
char rMinStr[8], rMaxStr[8];
|
||||
dtostrf(meters[i].rangeMin, 1, 1, rMinStr);
|
||||
dtostrf(meters[i].rangeMax, 1, 1, rMaxStr);
|
||||
|
||||
meterRows += "<fieldset><legend>Meter " + String(i) + "</legend>";
|
||||
meterRows += "<div class=row><label>Pin</label><input name=m" + String(i) + "_pin type=number min=0 max=99 value=" + String(meters[i].pin) + "></div>";
|
||||
meterRows += "<div class=row><label>Name</label><input name=m" + String(i) + "_name value='" + nameVal + "'></div>";
|
||||
meterRows += "<div class=row><label>Unit</label><input name=m" + String(i) + "_unit value='" + unitVal + "'></div>";
|
||||
meterRows += "<div class=row><label>Range</label><input name=m" + String(i) + "_range type=number step=any min=0 value=" + String(rangeStr) + "></div>";
|
||||
meterRows += "<div class=row><label>Min</label><input name=m" + String(i) + "_rangeMin type=number step=any value=" + String(rMinStr) + "></div>";
|
||||
meterRows += "<div class=row><label>Max</label><input name=m" + String(i) + "_rangeMax type=number step=any value=" + String(rMaxStr) + "></div>";
|
||||
meterRows += "<div class=row><label>Max Duty</label><input name=m" + String(i) + "_maxD type=number step=any min=0 max=100 value=" + String(maxStr) + "></div>";
|
||||
meterRows += "<div class=slider-row>";
|
||||
meterRows += "<label>Output</label>";
|
||||
@@ -489,8 +509,10 @@ static void handleConfig() {
|
||||
strlcpy(newMeters[i].name, server.arg(pf + "name").c_str(), sizeof(newMeters[i].name));
|
||||
if (server.hasArg(pf + "unit"))
|
||||
strlcpy(newMeters[i].unit, server.arg(pf + "unit").c_str(), sizeof(newMeters[i].unit));
|
||||
if (server.hasArg(pf + "range"))
|
||||
newMeters[i].range = server.arg(pf + "range").toFloat();
|
||||
if (server.hasArg(pf + "rangeMin"))
|
||||
newMeters[i].rangeMin = server.arg(pf + "rangeMin").toFloat();
|
||||
if (server.hasArg(pf + "rangeMax"))
|
||||
newMeters[i].rangeMax = server.arg(pf + "rangeMax").toFloat();
|
||||
if (server.hasArg(pf + "maxD"))
|
||||
newMeters[i].maxDuty = server.arg(pf + "maxD").toFloat();
|
||||
if (server.hasArg(pf + "cur"))
|
||||
@@ -500,8 +522,8 @@ static void handleConfig() {
|
||||
meterCount = newCount;
|
||||
memcpy(meters, newMeters, sizeof(meters));
|
||||
for (int i = 0; i < meterCount; i++)
|
||||
Serial.printf("[HTTP] meter%d pin=%d name=%s unit=%s range=%.1f maxD=%.1f cur=%.1f\n",
|
||||
i, meters[i].pin, meters[i].name, meters[i].unit, meters[i].range, meters[i].maxDuty, meters[i].currentValue);
|
||||
Serial.printf("[HTTP] meter%d pin=%d name=%s unit=%s range=[%.1f,%.1f] maxD=%.1f cur=%.1f\n",
|
||||
i, meters[i].pin, meters[i].name, meters[i].unit, meters[i].rangeMin, meters[i].rangeMax, meters[i].maxDuty, meters[i].currentValue);
|
||||
|
||||
saveConfig();
|
||||
attachMeters();
|
||||
|
||||
Reference in New Issue
Block a user