Skip to content

Commit c06e8e9

Browse files
committed
v3.27
1 parent a71132e commit c06e8e9

File tree

7 files changed

+95
-30
lines changed

7 files changed

+95
-30
lines changed

NEWTAGS.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ e3dc/raw/TAG_BAT_DATA/TAG_BAT_RSOC
2727
The tag names are used to build the topic names.
2828
Raw data is only published via MQTT.
2929

30+
To limit the amount of raw data, a configuration entry can be created with a regular expression that describes the topics to be published:
31+
```
32+
RAW_TOPIC_REGEX=raw/(TAG_DCDC_DATA|TAG_BAT_DATA)/.*
33+
```
34+
3035
### Configuration of Tags
3136

3237
All tags that are listed in RscpTags.h and have "REQ" in their name can be used.
@@ -154,4 +159,14 @@ ADD_NEW_REQUEST=TAG_DCDC_REQ_DATA:TAG_DCDC_REQ_P_DCL-1
154159
ADD_NEW_REQUEST=TAG_DCDC_REQ_DATA:TAG_DCDC_REQ_ON_GRID-1
155160
ADD_NEW_REQUEST=TAG_DCDC_REQ_DATA:TAG_DCDC_REQ_DERATING-1
156161
ADD_NEW_REQUEST=TAG_DCDC_REQ_DATA:TAG_DCDC_REQ_DERATING_VALUE-1
162+
163+
# Wallbox & Emergency Power
164+
ADD_NEW_REQUEST=0:TAG_EMS_REQ_GET_EP_WALLBOX_ALLOW-0
165+
ADD_NEW_REQUEST=0:TAG_EMS_REQ_GET_MAX_EP_WALLBOX_POWER_W-0
166+
ADD_NEW_REQUEST=0:TAG_EMS_REQ_GET_MIN_EP_WALLBOX_POWER_W-0
167+
ADD_NEW_REQUEST=0:TAG_EMS_REQ_GET_EP_WALLBOX_ENERGY-0
168+
ADD_NEW_REQUEST=0:TAG_EMS_REQ_EP_DELAY-0
169+
170+
# System Specifications
171+
ADD_NEW_REQUEST_AT_START=0:TAG_EMS_REQ_GET_SYS_SPECS-0
157172
```

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ or to show the help page
155155
If everything works properly, you will see something like this:
156156

157157
```
158-
rscp2mqtt [3.26]
158+
rscp2mqtt [3.27]
159159
E3DC system >192.168.178.111:5033< user: >your E3DC user<
160160
MQTT broker >localhost:1883< qos = >0< retain = >✗< tls >✗< client id >✗< prefix >e3dc<
161161
Requesting PVI ✓ | PM (0) | DCB ✓ (1 battery string) | Wallbox ✗ | Interval 2 | Autorefresh ✓ | Raw data ✗ | Logging OFF

RELEASE.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
## Release Notes
22

3+
### Release v3.27 (24.07.2024)
4+
5+
Bug fixes:
6+
- Issue #81: Raw data mode: Possible segmentation fault due to a memory leak
7+
38
### Release v3.26 (14.07.2024)
49

510
Features:

RscpMqttConfig.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ typedef struct _config_t {
9898
char true_value[5];
9999
char false_value[6];
100100
bool raw_mode;
101+
char *raw_topic_regex;
101102
} config_t;
102103

103104
#endif

RscpMqttMain.cpp

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include <regex>
2222
#include <mutex>
2323

24-
#define RSCP2MQTT_VERSION "3.26"
24+
#define RSCP2MQTT_VERSION "3.27"
2525

2626
#define AES_KEY_SIZE 32
2727
#define AES_BLOCK_SIZE 32
@@ -505,7 +505,7 @@ void publishImmediately(char *t, char *p, bool influx) {
505505
char topic[TOPIC_SIZE];
506506

507507
snprintf(topic, TOPIC_SIZE, "%s/%s", cfg.prefix, t);
508-
if (mosq) mosquitto_publish(mosq, NULL, topic, strlen(p), p, cfg.mqtt_qos, cfg.mqtt_retain);
508+
if (mosq && (mosquitto_pub_topic_check(topic) == MOSQ_ERR_SUCCESS) && p && strlen(p)) mosquitto_publish(mosq, NULL, topic, strlen(p), p, cfg.mqtt_qos, cfg.mqtt_retain);
509509
#ifdef INFLUXDB
510510
if (cfg.influxdb_on && curl && influx) {
511511
char buffer[CURL_BUFFER_SIZE];
@@ -867,17 +867,22 @@ void pushAdditionalTag(uint32_t req_container, uint32_t req_tag, int req_index,
867867
}
868868

869869
bool updateRawData(char *topic, char *payload) {
870-
for (std::vector<RSCP_MQTT::mqtt_data_t>::iterator it = RSCP_MQTT::rawData.begin(); it != RSCP_MQTT::rawData.end(); ++it) {
871-
if (!strcmp(it->topic, topic)) {
872-
if (strcmp(it->payload, payload)) strcpy(it->payload, payload);
873-
return(true);
870+
if (topic && payload) {
871+
for (std::vector<RSCP_MQTT::mqtt_data_t>::iterator it = RSCP_MQTT::rawData.begin(); it != RSCP_MQTT::rawData.end(); ++it) {
872+
if (!strcmp(it->topic, topic)) {
873+
if (strcmp(it->payload, payload)) {
874+
if (strlen(it->payload) != strlen(payload)) it->payload = (char *)realloc(it->payload, strlen(payload) + 1);
875+
strcpy(it->payload, payload);
876+
}
877+
return(true);
878+
}
874879
}
875880
}
876881
return(false);
877882
}
878883

879884
void mergeRawData(char *topic, char *payload) {
880-
if (!updateRawData(topic, payload)) {
885+
if (topic && payload && !updateRawData(topic, payload)) {
881886
RSCP_MQTT::mqtt_data_t v;
882887
v.topic = strdup(topic);
883888
v.payload = strdup(payload);
@@ -2094,29 +2099,31 @@ void createRequest(SRscpFrameBuffer * frameBuffer) {
20942099
}
20952100

20962101
void publishRaw(RscpProtocol *protocol, SRscpValue *response, char *topic) {
2097-
char *payload_new = (char *)malloc(PAYLOAD_SIZE * sizeof(char));
2102+
char *payload_new = (char *)malloc(PAYLOAD_SIZE * sizeof(char) + 1);
20982103
char *payload_old = readRawData(topic);
2104+
memset(payload_new, 0, sizeof(payload_new));
20992105
preparePayload(protocol, response, &payload_new);
2100-
if (payload_old && strcmp(payload_old, payload_new)) {
2106+
if (payload_old && payload_new && strcmp(payload_new, "") && strcmp(payload_old, payload_new)) {
21012107
publishImmediately(topic, payload_new, false);
21022108
updateRawData(topic, payload_new);
2103-
} else if (!payload_old) {
2109+
} else if (!payload_old && payload_new && strcmp(payload_new, "")) {
21042110
publishImmediately(topic, payload_new, false);
21052111
mergeRawData(topic, payload_new);
21062112
}
21072113
if (payload_new) free(payload_new);
2108-
return;
2109-
}
2114+
return;
2115+
}
21102116

21112117
void handleRaw(RscpProtocol *protocol, SRscpValue *response, uint32_t *cache, int level) {
21122118
int l = level + 1;
21132119
char topic[TOPIC_SIZE];
2120+
memset(topic, 0, sizeof(topic));
21142121

21152122
if (response->dataType == RSCP::eTypeError) return;
21162123

21172124
if (!l && (response->dataType != RSCP::eTypeContainer)) {
21182125
sprintf(topic, "raw/%s", tagName(RSCP_TAGS::RscpTagsOverview, response->tag));
2119-
publishRaw(protocol, response, topic);
2126+
if (!cfg.raw_topic_regex || std::regex_match(topic, std::regex(cfg.raw_topic_regex))) publishRaw(protocol, response, topic);
21202127
return;
21212128
}
21222129
std::vector<SRscpValue> data = protocol->getValueAsContainer(response);
@@ -2131,11 +2138,13 @@ void handleRaw(RscpProtocol *protocol, SRscpValue *response, uint32_t *cache, in
21312138
strcpy(topic, "raw");
21322139
for (int i = 0; i < RECURSION_MAX_LEVEL; i++) {
21332140
if (cache[i]) {
2134-
strcat(topic, "/");
2135-
strcat(topic, tagName(RSCP_TAGS::RscpTagsOverview, cache[i]));
2141+
if (strlen(topic) + strlen(tagName(RSCP_TAGS::RscpTagsOverview, cache[i])) + 2 < TOPIC_SIZE) {
2142+
strcat(topic, "/");
2143+
strcat(topic, tagName(RSCP_TAGS::RscpTagsOverview, cache[i]));
2144+
} else logMessageByTag(response->tag, data[i].tag, 0, __LINE__, (char *)"Error: Topic name too long. Container >%s< Tag >%s< [%d]\n");
21362145
}
21372146
}
2138-
publishRaw(protocol, &data[i], topic);
2147+
if (!cfg.raw_topic_regex || std::regex_match(topic, std::regex(cfg.raw_topic_regex))) publishRaw(protocol, &data[i], topic);
21392148
}
21402149
}
21412150
}
@@ -2185,8 +2194,8 @@ int handleResponseValue(RscpProtocol *protocol, SRscpValue *response) {
21852194

21862195
if (cfg.raw_mode) {
21872196
for (int i = 0; i < RECURSION_MAX_LEVEL; i++) cache[i] = 0;
2188-
handleRaw(protocol, response, cache, -1);
2189-
}
2197+
if (mosq) handleRaw(protocol, response, cache, -1);
2198+
}
21902199

21912200
// check the SRscpValue TAG to detect which response it is
21922201
switch (response->tag) {
@@ -2740,7 +2749,7 @@ static void mainLoop(void) {
27402749
if (mosq) {
27412750
char topic[TOPIC_SIZE];
27422751
snprintf(topic, TOPIC_SIZE, "%s/rscp2mqtt/status", cfg.prefix);
2743-
mosquitto_threaded_set(mosq, true);
2752+
// mosquitto_threaded_set(mosq, true); // necessary?
27442753
if (cfg.mqtt_tls && cfg.mqtt_tls_password) {
27452754
if (mosquitto_tls_set(mosq, cfg.mqtt_tls_cafile, cfg.mqtt_tls_capath, cfg.mqtt_tls_certfile, cfg.mqtt_tls_keyfile, mqttCallbackTlsPassword) != MOSQ_ERR_SUCCESS) {
27462755
logMessage(cfg.logfile, (char *)__FILE__, __LINE__, (char *)"Error: Unable to set TLS options.\n");
@@ -2755,8 +2764,10 @@ static void mainLoop(void) {
27552764
if (cfg.mqtt_auth && strcmp(cfg.mqtt_user, "") && strcmp(cfg.mqtt_password, "")) mosquitto_username_pw_set(mosq, cfg.mqtt_user, cfg.mqtt_password);
27562765
mosquitto_will_set(mosq, topic, strlen("disconnected"), "disconnected", cfg.mqtt_qos, cfg.mqtt_retain);
27572766
if (!mosquitto_connect(mosq, cfg.mqtt_host, cfg.mqtt_port, 10)) {
2758-
std::thread th(mqttListener, mosq);
2759-
th.detach();
2767+
if (!cfg.once) {
2768+
std::thread th(mqttListener, mosq);
2769+
th.detach();
2770+
}
27602771
if (cfg.verbose) logMessage(cfg.logfile, (char *)__FILE__, __LINE__, (char *)"Success: MQTT broker connected.\n");
27612772
} else {
27622773
logMessage(cfg.logfile, (char *)__FILE__, __LINE__, (char *)"Error: MQTT broker connection failed.\n");
@@ -2935,6 +2946,7 @@ int main(int argc, char *argv[]) {
29352946
strcpy(cfg.true_value, "true");
29362947
strcpy(cfg.false_value, "false");
29372948
cfg.raw_mode = false;
2949+
cfg.raw_topic_regex = NULL;
29382950

29392951
// signal handler
29402952
signal(SIGINT, signal_handler);
@@ -3109,6 +3121,8 @@ int main(int argc, char *argv[]) {
31093121
#endif
31103122
else if ((strcasecmp(key, "RAW_MODE") == 0) && (strcasecmp(value, "true") == 0))
31113123
cfg.raw_mode = true;
3124+
else if (strcasecmp(key, "RAW_TOPIC_REGEX") == 0)
3125+
cfg.raw_topic_regex = strdup(value);
31123126
else if (strncasecmp(key, "ADD_NEW_REQUEST", strlen("ADD_NEW_REQUEST")) == 0) {
31133127
int order = 0;
31143128
int index = -1;
@@ -3467,6 +3481,10 @@ int main(int argc, char *argv[]) {
34673481
RSCP_MQTT::IdlePeriodCache.clear();
34683482
RSCP_MQTT::ErrorCache.clear();
34693483

3484+
// MQTT disconnect
3485+
mosquitto_disconnect(mosq);
3486+
mosq = NULL;
3487+
34703488
// MQTT cleanup
34713489
mosquitto_lib_cleanup();
34723490

@@ -3486,6 +3504,7 @@ int main(int argc, char *argv[]) {
34863504
if (cfg.mqtt_tls_certfile) free(cfg.mqtt_tls_certfile);
34873505
if (cfg.mqtt_tls_keyfile) free(cfg.mqtt_tls_keyfile);
34883506
if (cfg.mqtt_tls_password) free(cfg.mqtt_tls_password);
3507+
if (cfg.raw_topic_regex) free(cfg.raw_topic_regex);
34893508

34903509
exit(EXIT_SUCCESS);
34913510
}

WALLBOX.md

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,45 +58,68 @@ The following topics are sent to the MQTT broker:
5858
| Wallbox Power L3 * | e3dc/wallbox/power/L3 | [W] |
5959
| Wallbox SOC * | e3dc/wallbox/soc | [%] |
6060

61-
*) If more than one wallbox exists, topics are extended by the number of the wallbox (1..8), e.g. e3dc/wallbox/1/charging, e3dc/wallbox/2/charging, ...
61+
*) If more than one wallbox exists (maximum 8), topics are extended by the number of the wallbox (1..8), e.g. e3dc/wallbox/1/charging, e3dc/wallbox/2/charging, ... e3dc/wallbox/8/charging
62+
63+
**) The value is required to be able to calculate the daily value.
6264

6365
### Wallbox Control
6466

65-
In addition, these topics can be published to control the wallboxes:
67+
In addition, the following topics can be published to control the wallboxes:
6668

6769
Sun Mode (true/1/false/0)
6870
```
71+
# if one wallbox is available
6972
mosquitto_pub -h localhost -p 1883 -t "e3dc/set/wallbox/sun_mode" -m true
70-
# or
73+
#
74+
# or if more than one wallbox is available
7175
mosquitto_pub -h localhost -p 1883 -t "e3dc/set/wallbox/1/sun_mode" -m true # for the first wallbox
76+
mosquitto_pub -h localhost -p 1883 -t "e3dc/set/wallbox/2/sun_mode" -m true # for the second wallbox
77+
# ...
78+
mosquitto_pub -h localhost -p 1883 -t "e3dc/set/wallbox/8/sun_mode" -m true # for the eighth wallbox
7279
```
7380

7481
Suspend charging (true/1/false/0)
7582
```
7683
mosquitto_pub -h localhost -p 1883 -t "e3dc/set/wallbox/suspended" -m true
77-
# or
84+
#
85+
# or if more than one wallbox is available
7886
mosquitto_pub -h localhost -p 1883 -t "e3dc/set/wallbox/1/suspended" -m true # for the first wallbox
87+
mosquitto_pub -h localhost -p 1883 -t "e3dc/set/wallbox/2/suspended" -m true # for the second wallbox
88+
# ...
89+
mosquitto_pub -h localhost -p 1883 -t "e3dc/set/wallbox/8/suspended" -m true # for the eighth wallbox
7990
```
8091

8192
Toggle suspend charging
8293
```
83-
mosquitto_pub -h localhost -p 1883 -t"e3dc/set/wallbox/toggle" -m 1
84-
# or
94+
mosquitto_pub -h localhost -p 1883 -t "e3dc/set/wallbox/toggle" -m 1
95+
#
96+
# or if more than one wallbox is available
8597
mosquitto_pub -h localhost -p 1883 -t "e3dc/set/wallbox/1/toggle" -m 1 # for the first wallbox
98+
mosquitto_pub -h localhost -p 1883 -t "e3dc/set/wallbox/2/toggle" -m 1 # for the second wallbox
99+
# ...
100+
mosquitto_pub -h localhost -p 1883 -t "e3dc/set/wallbox/8/toggle" -m 1 # for the eighth wallbox
86101
```
87102

88103
Set max current (1..32 A)
89104
```
90105
mosquitto_pub -h localhost -p 1883 -t"e3dc/set/wallbox/max_current" -m 16
91-
# or
106+
#
107+
# or if more than one wallbox is available
92108
mosquitto_pub -h localhost -p 1883 -t "e3dc/set/wallbox/1/max_current" -m 16 # for the first wallbox
109+
mosquitto_pub -h localhost -p 1883 -t "e3dc/set/wallbox/2/max_current" -m 16 # for the second wallbox
110+
# ...
111+
mosquitto_pub -h localhost -p 1883 -t "e3dc/set/wallbox/8/max_current" -m 16 # for the eighth wallbox
93112
```
94113

95114
Set number of phases (1/3)
96115
```
97116
mosquitto_pub -h localhost -p 1883 -t "e3dc/set/wallbox/number_phases" -m 1
98-
# or
117+
#
118+
# or if more than one wallbox is available
99119
mosquitto_pub -h localhost -p 1883 -t "e3dc/set/wallbox/1/number_phases" -m 1 # for the first wallbox
120+
mosquitto_pub -h localhost -p 1883 -t "e3dc/set/wallbox/2/number_phases" -m 1 # for the second wallbox
121+
# ...
122+
mosquitto_pub -h localhost -p 1883 -t "e3dc/set/wallbox/8/number_phases" -m 1 # for the eighth wallbox
100123
```
101124

102125
The following settings apply to all available wallboxes:

config.template

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ DCB_REQUESTS=true
8383

8484
#-Raw Data Mode
8585
RAW_MODE=false
86+
#-- filter topics to be published (optional, only one entry possible!)
87+
RAW_TOPIC_REGEX=raw/TAG_DCDC_DATA/.*
8688

8789
#-Additional Tags and Topics
8890
#--please look at NEWTAGS.md

0 commit comments

Comments
 (0)