powermeter refactor: instanciate power meters with config
instead of reading the main config's powermeter struct(s), the individual power meters now are instanciated using a copy of their respective config. this allows to instanciate different power meters with different configs. as a first step, this simplifies instanciating power meters for test purposes.
This commit is contained in:
parent
3f2d9d38fa
commit
b891a4c1a3
@ -14,6 +14,9 @@ using Unit_t = PowerMeterHttpJsonValue::Unit;
|
|||||||
|
|
||||||
class PowerMeterHttpJson : public PowerMeterProvider {
|
class PowerMeterHttpJson : public PowerMeterProvider {
|
||||||
public:
|
public:
|
||||||
|
explicit PowerMeterHttpJson(PowerMeterHttpJsonConfig const& cfg)
|
||||||
|
: _cfg(cfg) { }
|
||||||
|
|
||||||
bool init() final;
|
bool init() final;
|
||||||
void loop() final;
|
void loop() final;
|
||||||
float getPowerTotal() const final;
|
float getPowerTotal() const final;
|
||||||
@ -24,6 +27,8 @@ public:
|
|||||||
poll_result_t poll();
|
poll_result_t poll();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
PowerMeterHttpJsonConfig const _cfg;
|
||||||
|
|
||||||
uint32_t _lastPoll;
|
uint32_t _lastPoll;
|
||||||
|
|
||||||
power_values_t _powerValues;
|
power_values_t _powerValues;
|
||||||
|
|||||||
@ -5,10 +5,14 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "HttpGetter.h"
|
#include "HttpGetter.h"
|
||||||
|
#include "Configuration.h"
|
||||||
#include "PowerMeterSml.h"
|
#include "PowerMeterSml.h"
|
||||||
|
|
||||||
class PowerMeterHttpSml : public PowerMeterSml {
|
class PowerMeterHttpSml : public PowerMeterSml {
|
||||||
public:
|
public:
|
||||||
|
explicit PowerMeterHttpSml(PowerMeterHttpSmlConfig const& cfg)
|
||||||
|
: _cfg(cfg) { }
|
||||||
|
|
||||||
bool init() final;
|
bool init() final;
|
||||||
void loop() final;
|
void loop() final;
|
||||||
|
|
||||||
@ -17,6 +21,8 @@ public:
|
|||||||
String poll();
|
String poll();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
PowerMeterHttpSmlConfig const _cfg;
|
||||||
|
|
||||||
uint32_t _lastPoll = 0;
|
uint32_t _lastPoll = 0;
|
||||||
|
|
||||||
std::unique_ptr<HttpGetter> _upHttpGetter;
|
std::unique_ptr<HttpGetter> _upHttpGetter;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Configuration.h"
|
||||||
#include "PowerMeterProvider.h"
|
#include "PowerMeterProvider.h"
|
||||||
#include <espMqttClient.h>
|
#include <espMqttClient.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -8,6 +9,9 @@
|
|||||||
|
|
||||||
class PowerMeterMqtt : public PowerMeterProvider {
|
class PowerMeterMqtt : public PowerMeterProvider {
|
||||||
public:
|
public:
|
||||||
|
explicit PowerMeterMqtt(PowerMeterMqttConfig const& cfg)
|
||||||
|
: _cfg(cfg) { }
|
||||||
|
|
||||||
~PowerMeterMqtt();
|
~PowerMeterMqtt();
|
||||||
|
|
||||||
bool init() final;
|
bool init() final;
|
||||||
@ -21,6 +25,8 @@ private:
|
|||||||
uint8_t const* payload, size_t len, size_t index,
|
uint8_t const* payload, size_t len, size_t index,
|
||||||
size_t total, float* targetVariable);
|
size_t total, float* targetVariable);
|
||||||
|
|
||||||
|
PowerMeterMqttConfig const _cfg;
|
||||||
|
|
||||||
float _powerValueOne = 0;
|
float _powerValueOne = 0;
|
||||||
float _powerValueTwo = 0;
|
float _powerValueTwo = 0;
|
||||||
float _powerValueThree = 0;
|
float _powerValueThree = 0;
|
||||||
|
|||||||
@ -2,11 +2,21 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include "Configuration.h"
|
||||||
#include "PowerMeterProvider.h"
|
#include "PowerMeterProvider.h"
|
||||||
#include "SDM.h"
|
#include "SDM.h"
|
||||||
|
|
||||||
class PowerMeterSerialSdm : public PowerMeterProvider {
|
class PowerMeterSerialSdm : public PowerMeterProvider {
|
||||||
public:
|
public:
|
||||||
|
enum class Phases {
|
||||||
|
One,
|
||||||
|
Three
|
||||||
|
};
|
||||||
|
|
||||||
|
PowerMeterSerialSdm(Phases phases, PowerMeterSerialSdmConfig const& cfg)
|
||||||
|
: _phases(phases)
|
||||||
|
, _cfg(cfg) { }
|
||||||
|
|
||||||
~PowerMeterSerialSdm();
|
~PowerMeterSerialSdm();
|
||||||
|
|
||||||
bool init() final;
|
bool init() final;
|
||||||
@ -15,6 +25,9 @@ public:
|
|||||||
void doMqttPublish() const final;
|
void doMqttPublish() const final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Phases _phases;
|
||||||
|
PowerMeterSerialSdmConfig const _cfg;
|
||||||
|
|
||||||
uint32_t _lastPoll;
|
uint32_t _lastPoll;
|
||||||
|
|
||||||
float _phase1Power = 0.0;
|
float _phase1Power = 0.0;
|
||||||
|
|||||||
@ -26,20 +26,24 @@ void PowerMeterClass::updateSettings()
|
|||||||
|
|
||||||
if (_upProvider) { _upProvider.reset(); }
|
if (_upProvider) { _upProvider.reset(); }
|
||||||
|
|
||||||
auto const& config = Configuration.get();
|
auto const& pmcfg = Configuration.get().PowerMeter;
|
||||||
|
|
||||||
if (!config.PowerMeter.Enabled) { return; }
|
if (!pmcfg.Enabled) { return; }
|
||||||
|
|
||||||
switch(static_cast<PowerMeterProvider::Type>(config.PowerMeter.Source)) {
|
switch(static_cast<PowerMeterProvider::Type>(pmcfg.Source)) {
|
||||||
case PowerMeterProvider::Type::MQTT:
|
case PowerMeterProvider::Type::MQTT:
|
||||||
_upProvider = std::make_unique<PowerMeterMqtt>();
|
_upProvider = std::make_unique<PowerMeterMqtt>(pmcfg.Mqtt);
|
||||||
break;
|
break;
|
||||||
case PowerMeterProvider::Type::SDM1PH:
|
case PowerMeterProvider::Type::SDM1PH:
|
||||||
|
_upProvider = std::make_unique<PowerMeterSerialSdm>(
|
||||||
|
PowerMeterSerialSdm::Phases::One, pmcfg.SerialSdm);
|
||||||
|
break;
|
||||||
case PowerMeterProvider::Type::SDM3PH:
|
case PowerMeterProvider::Type::SDM3PH:
|
||||||
_upProvider = std::make_unique<PowerMeterSerialSdm>();
|
_upProvider = std::make_unique<PowerMeterSerialSdm>(
|
||||||
|
PowerMeterSerialSdm::Phases::Three, pmcfg.SerialSdm);
|
||||||
break;
|
break;
|
||||||
case PowerMeterProvider::Type::HTTP_JSON:
|
case PowerMeterProvider::Type::HTTP_JSON:
|
||||||
_upProvider = std::make_unique<PowerMeterHttpJson>();
|
_upProvider = std::make_unique<PowerMeterHttpJson>(pmcfg.HttpJson);
|
||||||
break;
|
break;
|
||||||
case PowerMeterProvider::Type::SERIAL_SML:
|
case PowerMeterProvider::Type::SERIAL_SML:
|
||||||
_upProvider = std::make_unique<PowerMeterSerialSml>();
|
_upProvider = std::make_unique<PowerMeterSerialSml>();
|
||||||
@ -48,7 +52,7 @@ void PowerMeterClass::updateSettings()
|
|||||||
_upProvider = std::make_unique<PowerMeterUdpSmaHomeManager>();
|
_upProvider = std::make_unique<PowerMeterUdpSmaHomeManager>();
|
||||||
break;
|
break;
|
||||||
case PowerMeterProvider::Type::HTTP_SML:
|
case PowerMeterProvider::Type::HTTP_SML:
|
||||||
_upProvider = std::make_unique<PowerMeterHttpSml>();
|
_upProvider = std::make_unique<PowerMeterHttpSml>(pmcfg.HttpSml);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "Configuration.h"
|
|
||||||
#include "PowerMeterHttpJson.h"
|
#include "PowerMeterHttpJson.h"
|
||||||
#include "MessageOutput.h"
|
#include "MessageOutput.h"
|
||||||
#include <WiFiClientSecure.h>
|
#include <WiFiClientSecure.h>
|
||||||
@ -11,14 +10,12 @@
|
|||||||
|
|
||||||
bool PowerMeterHttpJson::init()
|
bool PowerMeterHttpJson::init()
|
||||||
{
|
{
|
||||||
auto const& config = Configuration.get();
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < POWERMETER_HTTP_JSON_MAX_VALUES; i++) {
|
for (uint8_t i = 0; i < POWERMETER_HTTP_JSON_MAX_VALUES; i++) {
|
||||||
auto const& valueConfig = config.PowerMeter.HttpJson.Values[i];
|
auto const& valueConfig = _cfg.Values[i];
|
||||||
|
|
||||||
_httpGetters[i] = nullptr;
|
_httpGetters[i] = nullptr;
|
||||||
|
|
||||||
if (i == 0 || (config.PowerMeter.HttpJson.IndividualRequests && valueConfig.Enabled)) {
|
if (i == 0 || (_cfg.IndividualRequests && valueConfig.Enabled)) {
|
||||||
_httpGetters[i] = std::make_unique<HttpGetter>(valueConfig.HttpRequest);
|
_httpGetters[i] = std::make_unique<HttpGetter>(valueConfig.HttpRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,8 +37,7 @@ bool PowerMeterHttpJson::init()
|
|||||||
|
|
||||||
void PowerMeterHttpJson::loop()
|
void PowerMeterHttpJson::loop()
|
||||||
{
|
{
|
||||||
auto const& config = Configuration.get();
|
if ((millis() - _lastPoll) < (_cfg.PollingInterval * 1000)) {
|
||||||
if ((millis() - _lastPoll) < (config.PowerMeter.HttpJson.PollingInterval * 1000)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +64,7 @@ PowerMeterHttpJson::poll_result_t PowerMeterHttpJson::poll()
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (uint8_t i = 0; i < POWERMETER_HTTP_JSON_MAX_VALUES; i++) {
|
for (uint8_t i = 0; i < POWERMETER_HTTP_JSON_MAX_VALUES; i++) {
|
||||||
auto const& cfg = Configuration.get().PowerMeter.HttpJson.Values[i];
|
auto const& cfg = _cfg.Values[i];
|
||||||
|
|
||||||
if (!cfg.Enabled) {
|
if (!cfg.Enabled) {
|
||||||
cache[i] = 0.0;
|
cache[i] = 0.0;
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#include "Configuration.h"
|
|
||||||
#include "PowerMeterHttpSml.h"
|
#include "PowerMeterHttpSml.h"
|
||||||
#include "MessageOutput.h"
|
#include "MessageOutput.h"
|
||||||
#include <WiFiClientSecure.h>
|
#include <WiFiClientSecure.h>
|
||||||
@ -8,9 +7,7 @@
|
|||||||
|
|
||||||
bool PowerMeterHttpSml::init()
|
bool PowerMeterHttpSml::init()
|
||||||
{
|
{
|
||||||
auto const& config = Configuration.get();
|
_upHttpGetter = std::make_unique<HttpGetter>(_cfg.HttpRequest);
|
||||||
|
|
||||||
_upHttpGetter = std::make_unique<HttpGetter>(config.PowerMeter.HttpSml.HttpRequest);
|
|
||||||
|
|
||||||
if (_upHttpGetter->init()) { return true; }
|
if (_upHttpGetter->init()) { return true; }
|
||||||
|
|
||||||
@ -24,8 +21,7 @@ bool PowerMeterHttpSml::init()
|
|||||||
|
|
||||||
void PowerMeterHttpSml::loop()
|
void PowerMeterHttpSml::loop()
|
||||||
{
|
{
|
||||||
auto const& config = Configuration.get();
|
if ((millis() - _lastPoll) < (_cfg.PollingInterval * 1000)) {
|
||||||
if ((millis() - _lastPoll) < (config.PowerMeter.HttpSml.PollingInterval * 1000)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#include "PowerMeterMqtt.h"
|
#include "PowerMeterMqtt.h"
|
||||||
#include "Configuration.h"
|
|
||||||
#include "MqttSettings.h"
|
#include "MqttSettings.h"
|
||||||
#include "MessageOutput.h"
|
#include "MessageOutput.h"
|
||||||
|
|
||||||
@ -18,10 +17,9 @@ bool PowerMeterMqtt::init()
|
|||||||
_mqttSubscriptions.push_back(topic);
|
_mqttSubscriptions.push_back(topic);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto const& config = Configuration.get();
|
subscribe(_cfg.Values[0].Topic, &_powerValueOne);
|
||||||
subscribe(config.PowerMeter.Mqtt.Values[0].Topic, &_powerValueOne);
|
subscribe(_cfg.Values[1].Topic, &_powerValueTwo);
|
||||||
subscribe(config.PowerMeter.Mqtt.Values[1].Topic, &_powerValueTwo);
|
subscribe(_cfg.Values[2].Topic, &_powerValueThree);
|
||||||
subscribe(config.PowerMeter.Mqtt.Values[2].Topic, &_powerValueThree);
|
|
||||||
|
|
||||||
return _mqttSubscriptions.size() > 0;
|
return _mqttSubscriptions.size() > 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#include "PowerMeterSerialSdm.h"
|
#include "PowerMeterSerialSdm.h"
|
||||||
#include "Configuration.h"
|
|
||||||
#include "PinMapping.h"
|
#include "PinMapping.h"
|
||||||
#include "MessageOutput.h"
|
#include "MessageOutput.h"
|
||||||
#include "SerialPortManager.h"
|
#include "SerialPortManager.h"
|
||||||
@ -61,13 +60,11 @@ void PowerMeterSerialSdm::loop()
|
|||||||
{
|
{
|
||||||
if (!_upSdm) { return; }
|
if (!_upSdm) { return; }
|
||||||
|
|
||||||
auto const& config = Configuration.get();
|
if ((millis() - _lastPoll) < (_cfg.PollingInterval * 1000)) {
|
||||||
|
|
||||||
if ((millis() - _lastPoll) < (config.PowerMeter.SerialSdm.PollingInterval * 1000)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t addr = config.PowerMeter.SerialSdm.Address;
|
uint8_t addr = _cfg.Address;
|
||||||
|
|
||||||
// reading takes a "very long" time as each readVal() is a synchronous
|
// reading takes a "very long" time as each readVal() is a synchronous
|
||||||
// exchange of serial messages. cache the values and write later to
|
// exchange of serial messages. cache the values and write later to
|
||||||
@ -81,7 +78,7 @@ void PowerMeterSerialSdm::loop()
|
|||||||
float energyImport = _upSdm->readVal(SDM_IMPORT_ACTIVE_ENERGY, addr);
|
float energyImport = _upSdm->readVal(SDM_IMPORT_ACTIVE_ENERGY, addr);
|
||||||
float energyExport = _upSdm->readVal(SDM_EXPORT_ACTIVE_ENERGY, addr);
|
float energyExport = _upSdm->readVal(SDM_EXPORT_ACTIVE_ENERGY, addr);
|
||||||
|
|
||||||
if (static_cast<PowerMeterProvider::Type>(config.PowerMeter.Source) == PowerMeterProvider::Type::SDM3PH) {
|
if (_phases == Phases::Three) {
|
||||||
phase2Power = _upSdm->readVal(SDM_PHASE_2_POWER, addr);
|
phase2Power = _upSdm->readVal(SDM_PHASE_2_POWER, addr);
|
||||||
phase3Power = _upSdm->readVal(SDM_PHASE_3_POWER, addr);
|
phase3Power = _upSdm->readVal(SDM_PHASE_3_POWER, addr);
|
||||||
phase2Voltage = _upSdm->readVal(SDM_PHASE_2_VOLTAGE, addr);
|
phase2Voltage = _upSdm->readVal(SDM_PHASE_2_VOLTAGE, addr);
|
||||||
|
|||||||
@ -188,25 +188,19 @@ void WebApiPowerMeterClass::onTestHttpJsonRequest(AsyncWebServerRequest* request
|
|||||||
|
|
||||||
char response[256];
|
char response[256];
|
||||||
|
|
||||||
auto powerMeterConfig = std::make_unique<CONFIG_T::PowerMeterConfig>();
|
auto powerMeterConfig = std::make_unique<PowerMeterHttpJsonConfig>();
|
||||||
JsonObject httpJson = root["http_json"];
|
Configuration.deserializePowerMeterHttpJsonConfig(root["http_json"].as<JsonObject>(),
|
||||||
powerMeterConfig->HttpJson.IndividualRequests = httpJson["individual_requests"].as<bool>();
|
*powerMeterConfig);
|
||||||
powerMeterConfig->VerboseLogging = true;
|
auto upMeter = std::make_unique<PowerMeterHttpJson>(*powerMeterConfig);
|
||||||
Configuration.deserializePowerMeterHttpJsonConfig(httpJson,
|
|
||||||
powerMeterConfig->HttpJson);
|
|
||||||
auto backup = std::make_unique<CONFIG_T::PowerMeterConfig>(Configuration.get().PowerMeter);
|
|
||||||
Configuration.get().PowerMeter = *powerMeterConfig;
|
|
||||||
auto upMeter = std::make_unique<PowerMeterHttpJson>();
|
|
||||||
upMeter->init();
|
upMeter->init();
|
||||||
auto res = upMeter->poll();
|
auto res = upMeter->poll();
|
||||||
Configuration.get().PowerMeter = *backup;
|
|
||||||
using values_t = PowerMeterHttpJson::power_values_t;
|
using values_t = PowerMeterHttpJson::power_values_t;
|
||||||
if (std::holds_alternative<values_t>(res)) {
|
if (std::holds_alternative<values_t>(res)) {
|
||||||
retMsg["type"] = "success";
|
retMsg["type"] = "success";
|
||||||
auto vals = std::get<values_t>(res);
|
auto vals = std::get<values_t>(res);
|
||||||
auto pos = snprintf(response, sizeof(response), "Result: %5.2fW", vals[0]);
|
auto pos = snprintf(response, sizeof(response), "Result: %5.2fW", vals[0]);
|
||||||
for (size_t i = 1; i < POWERMETER_HTTP_JSON_MAX_VALUES; ++i) {
|
for (size_t i = 1; i < vals.size(); ++i) {
|
||||||
if (!powerMeterConfig->HttpJson.Values[i].Enabled) { continue; }
|
if (!powerMeterConfig->Values[i].Enabled) { continue; }
|
||||||
pos += snprintf(response + pos, sizeof(response) - pos, ", %5.2fW", vals[i]);
|
pos += snprintf(response + pos, sizeof(response) - pos, ", %5.2fW", vals[i]);
|
||||||
}
|
}
|
||||||
snprintf(response + pos, sizeof(response) - pos, ", Total: %5.2f", upMeter->getPowerTotal());
|
snprintf(response + pos, sizeof(response) - pos, ", Total: %5.2f", upMeter->getPowerTotal());
|
||||||
@ -235,16 +229,12 @@ void WebApiPowerMeterClass::onTestHttpSmlRequest(AsyncWebServerRequest* request)
|
|||||||
|
|
||||||
char response[256];
|
char response[256];
|
||||||
|
|
||||||
auto powerMeterConfig = std::make_unique<CONFIG_T::PowerMeterConfig>();
|
auto powerMeterConfig = std::make_unique<PowerMeterHttpSmlConfig>();
|
||||||
Configuration.deserializePowerMeterHttpSmlConfig(root["http_sml"].as<JsonObject>(),
|
Configuration.deserializePowerMeterHttpSmlConfig(root["http_sml"].as<JsonObject>(),
|
||||||
powerMeterConfig->HttpSml);
|
*powerMeterConfig);
|
||||||
powerMeterConfig->VerboseLogging = true;
|
auto upMeter = std::make_unique<PowerMeterHttpSml>(*powerMeterConfig);
|
||||||
auto backup = std::make_unique<CONFIG_T::PowerMeterConfig>(Configuration.get().PowerMeter);
|
|
||||||
Configuration.get().PowerMeter = *powerMeterConfig;
|
|
||||||
auto upMeter = std::make_unique<PowerMeterHttpSml>();
|
|
||||||
upMeter->init();
|
upMeter->init();
|
||||||
auto res = upMeter->poll();
|
auto res = upMeter->poll();
|
||||||
Configuration.get().PowerMeter = *backup;
|
|
||||||
if (res.isEmpty()) {
|
if (res.isEmpty()) {
|
||||||
retMsg["type"] = "success";
|
retMsg["type"] = "success";
|
||||||
snprintf(response, sizeof(response), "Result: %5.2fW", upMeter->getPowerTotal());
|
snprintf(response, sizeof(response), "Result: %5.2fW", upMeter->getPowerTotal());
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user