Skip to content

Commit

Permalink
- Added JsonPath for MQTT Topics hoylabs#2 + hoylabs#3
Browse files Browse the repository at this point in the history
- Added PinMapping Configuration for TemperatureMeter
- Added MQTT Topic temperaturemeter/temperature1 for TemperatureMeter
  • Loading branch information
s-t-e-f-a-n committed Aug 7, 2023
1 parent 94a93a0 commit 1ffb8b6
Show file tree
Hide file tree
Showing 16 changed files with 152 additions and 73 deletions.
50 changes: 49 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,55 @@
"new": "cpp",
"ostream": "cpp",
"sstream": "cpp",
"streambuf": "cpp"
"streambuf": "cpp",
"array": "cpp",
"atomic": "cpp",
"bitset": "cpp",
"cctype": "cpp",
"chrono": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"condition_variable": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"list": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"functional": "cpp",
"iterator": "cpp",
"map": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"regex": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"stdexcept": "cpp",
"thread": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp"
},
"cmake.configureOnOpen": true
}
4 changes: 3 additions & 1 deletion include/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,9 @@ struct CONFIG_T {
char PowerMeter_MqttTopicPowerMeter1[MQTT_MAX_TOPIC_STRLEN + 1];
char PowerMeter_MqttTopicPowerMeter2[MQTT_MAX_TOPIC_STRLEN + 1];
char PowerMeter_MqttTopicPowerMeter3[MQTT_MAX_TOPIC_STRLEN + 1];
char PowerMeter_MqttJsonPath[POWERMETER_MAX_HTTP_JSON_PATH_STRLEN + 1];
char PowerMeter_MqttJsonPath1[POWERMETER_MAX_HTTP_JSON_PATH_STRLEN + 1];
char PowerMeter_MqttJsonPath2[POWERMETER_MAX_HTTP_JSON_PATH_STRLEN + 1];
char PowerMeter_MqttJsonPath3[POWERMETER_MAX_HTTP_JSON_PATH_STRLEN + 1];
uint32_t PowerMeter_SdmBaudrate;
uint32_t PowerMeter_SdmAddress;
uint32_t PowerMeter_HttpInterval;
Expand Down
1 change: 1 addition & 0 deletions include/PinMapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ struct PinMapping_t {
int8_t victron_rx;
int8_t victron2_tx;
int8_t victron2_rx;
int8_t ow;
int8_t battery_rx;
int8_t battery_tx;
int8_t huawei_miso;
Expand Down
24 changes: 2 additions & 22 deletions include/TemperatureMeter.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,13 @@
class TemperatureMeterClass {
public:
void init();
//void mqtt();
void mqtt();
void loop();
void readTemperatureMeter();

float TempVal = 0.0;

//void onMqttMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total);
//float getPowerTotal(bool forceUpdate = true);
//uint32_t getLastPowerMeterUpdate();

private:
//uint32_t _interval;
uint32_t _lastTemperatureMeterCheck;
// Used in Power limiter for safety check
//uint32_t _lastPowerMeterUpdate;

//float _powerMeter1Power = 0.0;
//float _powerMeter2Power = 0.0;
//float _powerMeter3Power = 0.0;
//float _powerMeter1Voltage = 0.0;
//float _powerMeter2Voltage = 0.0;
//float _powerMeter3Voltage = 0.0;
//float _powerMeterImport = 0.0;
//float _powerMeterExport = 0.0;

//bool mqttInitDone = false;

void readTemperatureMeter();
};

extern TemperatureMeterClass TemperatureMeter;
1 change: 1 addition & 0 deletions platformio_override.ini
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ build_flags = ${env.build_flags}
-DVICTRON_PIN_RX=3
-DVICTRON2_PIN_TX=17
-DVICTRON2_PIN_RX=16
-DOW_PIN=15
; -DHUAWEI_PIN_MISO=12
; -DHUAWEI_PIN_MOSI=13
; -DHUAWEI_PIN_SCLK=26
Expand Down
8 changes: 6 additions & 2 deletions src/Configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,9 @@ bool ConfigurationClass::write()
powermeter["mqtt_topic_powermeter_1"] = config.PowerMeter_MqttTopicPowerMeter1;
powermeter["mqtt_topic_powermeter_2"] = config.PowerMeter_MqttTopicPowerMeter2;
powermeter["mqtt_topic_powermeter_3"] = config.PowerMeter_MqttTopicPowerMeter3;
powermeter["mqtt_json_path"] = config.PowerMeter_MqttJsonPath;
powermeter["mqtt_json_path_1"] = config.PowerMeter_MqttJsonPath1;
powermeter["mqtt_json_path_2"] = config.PowerMeter_MqttJsonPath2;
powermeter["mqtt_json_path_3"] = config.PowerMeter_MqttJsonPath3;
powermeter["sdmbaudrate"] = config.PowerMeter_SdmBaudrate;
powermeter["sdmaddress"] = config.PowerMeter_SdmAddress;
powermeter["http_individual_requests"] = config.PowerMeter_HttpIndividualRequests;
Expand Down Expand Up @@ -342,7 +344,9 @@ bool ConfigurationClass::read()
strlcpy(config.PowerMeter_MqttTopicPowerMeter1, powermeter["mqtt_topic_powermeter_1"] | "", sizeof(config.PowerMeter_MqttTopicPowerMeter1));
strlcpy(config.PowerMeter_MqttTopicPowerMeter2, powermeter["mqtt_topic_powermeter_2"] | "", sizeof(config.PowerMeter_MqttTopicPowerMeter2));
strlcpy(config.PowerMeter_MqttTopicPowerMeter3, powermeter["mqtt_topic_powermeter_3"] | "", sizeof(config.PowerMeter_MqttTopicPowerMeter3));
strlcpy(config.PowerMeter_MqttJsonPath, powermeter["mqtt_json_path"] | "", sizeof(config.PowerMeter_MqttJsonPath));
strlcpy(config.PowerMeter_MqttJsonPath1, powermeter["mqtt_json_path_1"] | "", sizeof(config.PowerMeter_MqttJsonPath1));
strlcpy(config.PowerMeter_MqttJsonPath2, powermeter["mqtt_json_path_2"] | "", sizeof(config.PowerMeter_MqttJsonPath2));
strlcpy(config.PowerMeter_MqttJsonPath3, powermeter["mqtt_json_path_3"] | "", sizeof(config.PowerMeter_MqttJsonPath3));
config.PowerMeter_SdmBaudrate = powermeter["sdmbaudrate"] | POWERMETER_SDMBAUDRATE;
config.PowerMeter_SdmAddress = powermeter["sdmaddress"] | POWERMETER_SDMADDRESS;
config.PowerMeter_HttpIndividualRequests = powermeter["http_individual_requests"] | false;
Expand Down
7 changes: 5 additions & 2 deletions src/HttpPowerMeter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,15 +191,18 @@ bool HttpPowerMeterClass::httpRequest(const char* url, Auth authType, const char
float HttpPowerMeterClass::getFloatValueByJsonPath(const char* jsonString, const char* jsonPath, float& value)
{
FirebaseJson firebaseJson;
firebaseJson.setJsonData(jsonString);
if (!firebaseJson.setJsonData(jsonString)) {
MessageOutput.printf("getFloatValueByJsonPath: Error setJsonData of jsonString: %s\r\n", jsonString);
}

FirebaseJsonData firebaseJsonResult;
if (!firebaseJson.get(firebaseJsonResult, jsonPath)) {
MessageOutput.printf("getFloatValueByJsonPath: Error get of jsonPath: %s\r\n", jsonPath);
firebaseJson.clear();
return false;
}

value = firebaseJsonResult.to<float>();

firebaseJson.clear();

return true;
Expand Down
8 changes: 8 additions & 0 deletions src/PinMapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@
#define VICTRON2_PIN_RX -1
#endif

#ifndef OW_PIN
#define OW_PIN -1
#endif

#ifndef PYLONTECH_PIN_RX
#define PYLONTECH_PIN_RX -1
#endif
Expand Down Expand Up @@ -178,6 +182,8 @@ PinMappingClass::PinMappingClass()
_pinMapping.victron2_tx = VICTRON2_PIN_TX;
_pinMapping.victron2_rx = VICTRON2_PIN_RX;

_pinMapping.ow = OW_PIN;

_pinMapping.battery_rx = PYLONTECH_PIN_RX;
_pinMapping.battery_tx = PYLONTECH_PIN_TX;

Expand Down Expand Up @@ -254,6 +260,8 @@ bool PinMappingClass::init(const String& deviceMapping)
_pinMapping.victron2_rx = doc[i]["victron"]["rx2"] | VICTRON2_PIN_RX;
_pinMapping.victron2_tx = doc[i]["victron"]["tx2"] | VICTRON2_PIN_TX;

_pinMapping.ow = doc[i]["temperature"]["ow"] | OW_PIN;

_pinMapping.battery_rx = doc[i]["battery"]["rx"] | PYLONTECH_PIN_RX;
_pinMapping.battery_tx = doc[i]["battery"]["tx"] | PYLONTECH_PIN_TX;

Expand Down
34 changes: 20 additions & 14 deletions src/PowerMeter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include "NetworkSettings.h"
#include "SDM.h"
#include "MessageOutput.h"
#include <FirebaseJson.h>
#include <ctime>
#include <SoftwareSerial.h>

Expand Down Expand Up @@ -73,36 +72,45 @@ void PowerMeterClass::init()

void PowerMeterClass::onMqttMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total)
{
MessageOutput.printf("_powerMeter1Power: %s von topic: %s", payload, topic);

CONFIG_T& config = Configuration.get();

if (!config.PowerMeter_Enabled || config.PowerMeter_Source != SOURCE_MQTT) {
return;
}

if (strcmp(topic, config.PowerMeter_MqttTopicPowerMeter1) == 0) {
if (strcmp(config.PowerMeter_MqttJsonPath,"") == 0) {
if (strcmp(config.PowerMeter_MqttJsonPath1,"") == 0) {
_powerMeter1Power = std::stof(std::string(reinterpret_cast<const char*>(payload), (unsigned int)len));
}
else {
HttpPowerMeter.getFloatValueByJsonPath( (const char*)payload, config.PowerMeter_MqttJsonPath, _powerMeter1Power);
if (!HttpPowerMeter.getFloatValueByJsonPath( std::string(reinterpret_cast<const char*>(payload), (unsigned int)len).c_str(), config.PowerMeter_MqttJsonPath1, _powerMeter1Power) ) {
MessageOutput.printf("PowerMeterClass getFloatValueByJsonPath Error: payload %s / len %d / JsonPath %s\r\n", payload, len, config.PowerMeter_MqttJsonPath1);
}
}

MessageOutput.printf("PowerMeterClass: _powerMeter1Power: %f\r\n", _powerMeter1Power);

}

if (strcmp(topic, config.PowerMeter_MqttTopicPowerMeter2) == 0) {
_powerMeter2Power = std::stof(std::string(reinterpret_cast<const char*>(payload), (unsigned int)len));
if (strcmp(config.PowerMeter_MqttJsonPath2,"") == 0) {
_powerMeter2Power = std::stof(std::string(reinterpret_cast<const char*>(payload), (unsigned int)len));
}
else {
if (!HttpPowerMeter.getFloatValueByJsonPath( std::string(reinterpret_cast<const char*>(payload), (unsigned int)len).c_str(), config.PowerMeter_MqttJsonPath2, _powerMeter2Power) ) {
MessageOutput.printf("PowerMeterClass getFloatValueByJsonPath Error: payload %s / len %d / JsonPath %s\r\n", payload, len, config.PowerMeter_MqttJsonPath2);
}
}
}

if (strcmp(topic, config.PowerMeter_MqttTopicPowerMeter3) == 0) {
_powerMeter3Power = std::stof(std::string(reinterpret_cast<const char*>(payload), (unsigned int)len));
if (strcmp(config.PowerMeter_MqttJsonPath3,"") == 0) {
_powerMeter3Power = std::stof(std::string(reinterpret_cast<const char*>(payload), (unsigned int)len));
}
else {
if (!HttpPowerMeter.getFloatValueByJsonPath( std::string(reinterpret_cast<const char*>(payload), (unsigned int)len).c_str(), config.PowerMeter_MqttJsonPath3, _powerMeter3Power) ) {
MessageOutput.printf("PowerMeterClass getFloatValueByJsonPath Error: payload %s / len %d / JsonPath %s\r\n", payload, len, config.PowerMeter_MqttJsonPath3);
}
}
}

MessageOutput.printf("PowerMeterClass: TotalPower: %5.2f\r\n", getPowerTotal());

_lastPowerMeterUpdate = millis();
}

Expand Down Expand Up @@ -158,8 +166,6 @@ void PowerMeterClass::loop()

readPowerMeter();

MessageOutput.printf("PowerMeterClass: TotalPower: %5.2f\r\n", getPowerTotal());

mqtt();

_lastPowerMeterCheck = millis();
Expand Down
37 changes: 16 additions & 21 deletions src/TemperatureMeter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
/*
* Copyright (C) 2023 s-c-h-m-i-t-t
*/
// https://github.com/PaulStoffregen/OneWire
// https://github.com/stickbreaker/OneWire
// https://github.com/lcapossio/fresca/tree/master


#include "TemperatureMeter.h"
Expand Down Expand Up @@ -40,7 +37,6 @@ void TemperatureMeterClass::init()
Configuration.write();
MessageOutput.print("No Temperature Sensor found: Disabled Confguration...");
}

}

void TemperatureMeterClass::loop(void)
Expand All @@ -53,33 +49,32 @@ void TemperatureMeterClass::loop(void)

if (millis() - _lastTemperatureMeterCheck > 1000) {

readTemperatureMeter();

_lastTemperatureMeterCheck = millis();

readTemperatureMeter();
mqtt();
}
}

void TemperatureMeterClass::readTemperatureMeter(void)
{
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
//MessageOutput.print("Requesting temperatures...");
sensors.requestTemperatures(); // Send the command to get temperatures
//MessageOutput.println("DONE");
// After we got the temperatures, we can print them here.
// We use the function ByIndex, and as an example get the temperature from the first sensor only.

TempVal = sensors.getTempCByIndex(0);

// Check if reading was successful
if (TempVal != DEVICE_DISCONNECTED_C)
{
//MessageOutput.print("Temperature for the device 1 (index 0) is: ");
//MessageOutput.println(TempVal);
}
else
{
MessageOutput.println("Error: Could not read temperature data");
}
if (TempVal == DEVICE_DISCONNECTED_C) { MessageOutput.println("Error: Could not read temperature data"); }
}

void TemperatureMeterClass::mqtt()
{
if (!MqttSettings.getConnected()) {
return;
} else {
String topic = "temperaturemeter";
MqttSettings.publish(topic + "/temperature1", String(TempVal));
}
}



8 changes: 6 additions & 2 deletions src/WebApi_powermeter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ void WebApiPowerMeterClass::onStatus(AsyncWebServerRequest* request)
root[F("mqtt_topic_powermeter_1")] = config.PowerMeter_MqttTopicPowerMeter1;
root[F("mqtt_topic_powermeter_2")] = config.PowerMeter_MqttTopicPowerMeter2;
root[F("mqtt_topic_powermeter_3")] = config.PowerMeter_MqttTopicPowerMeter3;
root[F("mqtt_json_path")] = config.PowerMeter_MqttJsonPath;
root[F("mqtt_json_path_1")] = config.PowerMeter_MqttJsonPath1;
root[F("mqtt_json_path_2")] = config.PowerMeter_MqttJsonPath2;
root[F("mqtt_json_path_3")] = config.PowerMeter_MqttJsonPath3;
root[F("sdmbaudrate")] = config.PowerMeter_SdmBaudrate;
root[F("sdmaddress")] = config.PowerMeter_SdmAddress;
root[F("http_individual_requests")] = config.PowerMeter_HttpIndividualRequests;
Expand Down Expand Up @@ -175,7 +177,9 @@ void WebApiPowerMeterClass::onAdminPost(AsyncWebServerRequest* request)
strlcpy(config.PowerMeter_MqttTopicPowerMeter1, root[F("mqtt_topic_powermeter_1")].as<String>().c_str(), sizeof(config.PowerMeter_MqttTopicPowerMeter1));
strlcpy(config.PowerMeter_MqttTopicPowerMeter2, root[F("mqtt_topic_powermeter_2")].as<String>().c_str(), sizeof(config.PowerMeter_MqttTopicPowerMeter2));
strlcpy(config.PowerMeter_MqttTopicPowerMeter3, root[F("mqtt_topic_powermeter_3")].as<String>().c_str(), sizeof(config.PowerMeter_MqttTopicPowerMeter3));
strlcpy(config.PowerMeter_MqttJsonPath, root[F("mqtt_json_path")].as<String>().c_str(), sizeof(config.PowerMeter_MqttJsonPath));
strlcpy(config.PowerMeter_MqttJsonPath1, root[F("mqtt_json_path_1")].as<String>().c_str(), sizeof(config.PowerMeter_MqttJsonPath1));
strlcpy(config.PowerMeter_MqttJsonPath2, root[F("mqtt_json_path_2")].as<String>().c_str(), sizeof(config.PowerMeter_MqttJsonPath2));
strlcpy(config.PowerMeter_MqttJsonPath3, root[F("mqtt_json_path_3")].as<String>().c_str(), sizeof(config.PowerMeter_MqttJsonPath3));
config.PowerMeter_SdmBaudrate = root[F("sdmbaudrate")].as<uint32_t>();
config.PowerMeter_SdmAddress = root[F("sdmaddress")].as<uint8_t>();
config.PowerMeter_HttpIndividualRequests = root[F("http_individual_requests")].as<bool>();
Expand Down
6 changes: 5 additions & 1 deletion webapp/src/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -513,14 +513,18 @@
"PowerMeterParameter": "Power Meter Parameter",
"PowerMeterSource": "Stromzählertyp",
"MQTT": "MQTT Konfiguration",
"typeMQTT": "MQTT",
"typeMQTT": "MQTT + optional JSON",
"typeSDM1ph": "SDM 1 phase (SDM120/220/230)",
"typeSDM3ph": "SDM 3 phase (SDM72/630)",
"typeHTTP": "HTTP(S) + JSON",
"typeSML": "SML (OBIS 16.7.0)",
"MqttTopicPowerMeter1": "MQTT topic - Stromzähler #1",
"MqttTopicPowerMeter2": "MQTT topic - Stromzähler #2 (Optional)",
"MqttTopicPowerMeter3": "MQTT topic - Stromzähler #3 (Optional)",
"mqttJsonPath1": "JSON Pfad #1 (Optional)",
"mqttJsonPath2": "JSON Pfad #2 (Optional)",
"mqttJsonPath3": "JSON Pfad #3 (Optional)",
"mqttJsonPathDescription": "JSON Pfad um den Leistungswert zu finden. Leer lassen, wenn er direkt über Topic ohne Json ausgegeben wird. Es verwendet die Selektions-Syntax von mobizt/FirebaseJson. Beispiele gibt es unten.",
"SDM": "SDM-Stromzähler Konfiguration",
"sdmbaudrate": "Baudrate",
"sdmaddress": "Modbus Adresse",
Expand Down
6 changes: 5 additions & 1 deletion webapp/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -504,14 +504,18 @@
"PowerMeterParameter": "Power Meter Parameter",
"PowerMeterSource": "Power Meter type",
"MQTT": "MQTT Parameter",
"typeMQTT": "MQTT",
"typeMQTT": "MQTT + optional JSON",
"typeSDM1ph": "SDM 1 phase (SDM120/220/230)",
"typeSDM3ph": "SDM 3 phase (SDM72/630)",
"typeHTTP": "HTTP(s) + JSON",
"typeSML": "SML (OBIS 16.7.0)",
"MqttTopicPowerMeter1": "MQTT topic - Power meter #1",
"MqttTopicPowerMeter2": "MQTT topic - Power meter #2",
"MqttTopicPowerMeter3": "MQTT topic - Power meter #3",
"mqttJsonPath1": "JSON path #1 (optional)",
"mqttJsonPath2": "JSON path #2 (optional)",
"mqttJsonPath3": "JSON path #3 (optional)",
"mqttJsonPathDescription": "JSON path to find the power value in the response. Leave empty if topic already is equal with power value. This uses the JSON path query syntax from mobizt/FirebaseJson. See below for some examples.",
"SDM": "SDM-Power Meter Parameter",
"sdmbaudrate": "Baudrate",
"sdmaddress": "Modbus Address",
Expand Down
Loading

0 comments on commit 1ffb8b6

Please sign in to comment.