Skip to content

Commit

Permalink
v1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
pvtom committed Sep 22, 2024
1 parent dbb4c09 commit 794f081
Show file tree
Hide file tree
Showing 10 changed files with 671 additions and 371 deletions.
7 changes: 3 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
FROM alpine

# Install packages
RUN apk --no-cache add \
bash \
g++ \
make
RUN apk --no-cache add bash g++ make

RUN mkdir -p /tmp/rscp2rest
COPY ./ /tmp/rscp2rest
WORKDIR /tmp/rscp2rest
RUN make

RUN mkdir -p /opt/rscp2rest
RUN mkdir -p /opt/rscp2rest/public
RUN cp -a rscp2p /opt/rscp2rest
RUN cp -a restserver.js /opt/rscp2rest
RUN cp -a startup.sh /opt/rscp2rest
RUN cp -a config.min /opt/rscp2rest
RUN cp -a public/* /opt/rscp2rest/public
RUN chown -R nobody:99 /opt/rscp2rest

FROM node:20-alpine
Expand Down
652 changes: 325 additions & 327 deletions KEYS.md

Large diffs are not rendered by default.

12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,17 @@ curl -k https://<your server>:3300/data/<key>/raw
Examples:
```
# JSON
curl http://<your server>:3300/data/e3dc_pvi_frequency
curl http://<your server>:3300/data/pvi_frequency
{
"e3dc_pvi_frequency": {
"pvi_frequency": {
"value": "50.00",
"unit": "Hz",
"timestamp": "2024-09-12T22:08:00+02:00"
}
}
# RAW
curl http://<your server>:3300/data/e3dc_pvi_frequency/raw
curl http://<your server>:3300/data/pvi_frequency/raw
50.00
```

Expand All @@ -91,7 +91,7 @@ curl -X POST -H "Content-Type: application/json" -d '{"key":"<key>","value":"<va
```
Example:
```
curl -X POST -H "Content-Type: application/json" -d '{"key":"e3dc_ems_weather_regulation","value":"true"}' http://<your server>:3300/data
curl -X POST -H "Content-Type: application/json" -d '{"key":"ems_weather_regulation","value":"true"}' http://<your server>:3300/data
```

### DELETE Requests
Expand All @@ -101,6 +101,10 @@ DELETE removes data records from the cache. This can be useful for deleting old
curl -X DELETE http://<your server>:3300/data/<key>
```

## Website

To get an overview of the data, a small website is available at http://<your server>:3300/

## Libraries and Licenses

- The RSCP example application comes from E3/DC. According to E3/DC it can be distributed under the following conditions: `The authors or copyright holders, and in special E3/DC can not be held responsible for any damage caused by the software. Usage of the software is at your own risk. It may not be issued in copyright terms as a separate work.`
Expand Down
2 changes: 1 addition & 1 deletion RscpConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ typedef struct _config_t {
char e3dc_user[128];
char e3dc_password[128];
char aes_password[128];
char prefix[25];
char *prefix;
int history_start_year;
char *logfile;
char *historyfile;
Expand Down
44 changes: 30 additions & 14 deletions RscpMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
#include <mutex>
#include <fcntl.h>

#define RSCP2P "1.0"
#define RSCP2P_LONG "1.0.3.30"
#define RSCP2P "1.1"
#define RSCP2P_LONG "1.1.3.30"

#define AES_KEY_SIZE 32
#define AES_BLOCK_SIZE 32
Expand All @@ -29,7 +29,6 @@
#define DEFAULT_INTERVAL_MIN 1
#define DEFAULT_INTERVAL_MAX 300
#define IDLE_PERIOD_CACHE_SIZE 14
#define DEFAULT_PREFIX "e3dc"
#define RECURSION_MAX_LEVEL 7

#define CHARGE_LOCK_TRUE "today:charge:true:00:00-23:59"
Expand Down Expand Up @@ -166,7 +165,8 @@ int storeMQTTReceivedValue(std::vector<RSCP_MQTT::rec_cache_t> & c, char *topic_
mqttRcvd = true;

for (std::vector<RSCP_MQTT::rec_cache_t>::iterator it = c.begin(); it != c.end(); ++it) {
snprintf(topic, TOPIC_SIZE, "%s_%s", cfg.prefix, it->topic);
if (cfg.prefix) snprintf(topic, TOPIC_SIZE, "%s_%s", cfg.prefix, it->topic);
else strcpy(topic, it->topic);
if (!strcmp(topic, topic_in) && it->done) {
if (std::regex_match(payload, std::regex(it->regex_true))) {
if (strcmp(it->value_true, "")) strncpy(it->payload, it->value_true, PAYLOAD_SIZE);
Expand Down Expand Up @@ -208,7 +208,7 @@ void fifoListener() {
read(fd, fifo, 1024);
if (strlen(fifo)) {
if (sscanf(fifo, "%127[^=]=%127[^\n]", key, value) == 2) {
if (strstr(key, cfg.prefix)) {
if (!cfg.prefix || (strstr(key, cfg.prefix))) {
storeMQTTReceivedValue(RSCP_MQTT::RscpMqttReceiveCache, key, value);
if (cfg.verbose) logMessage(cfg.logfile, (char *)__FILE__, __LINE__, (char *)"fifoListener: >%s< >%s< received\n", key, value);
}
Expand Down Expand Up @@ -468,7 +468,11 @@ int handleMQTTIdlePeriods(std::vector<RSCP_MQTT::idle_period_t> & v) {

while (!v.empty()) {
e = v.back();
snprintf(topic, TOPIC_SIZE, "%s/idle_period/%s/%s", cfg.prefix, RSCP_MQTT::days[e.day].c_str(), e.type?"discharge":"charge");
if (cfg.prefix) {
snprintf(topic, TOPIC_SIZE, "%s/idle_period/%s/%s", cfg.prefix, RSCP_MQTT::days[e.day].c_str(), e.type?"discharge":"charge");
} else {
snprintf(topic, TOPIC_SIZE, "idle_period/%s/%s", RSCP_MQTT::days[e.day].c_str(), e.type?"discharge":"charge");
}
snprintf(payload, PAYLOAD_SIZE, "%s:%02d:%02d-%02d:%02d", e.active?"true":"false", e.starthour, e.startminute, e.endhour, e.endminute);
sprintf(fifo, "$=%s=%s=%s=$\n", topic, payload, "");
writeFifo(fifo, false);
Expand All @@ -487,11 +491,19 @@ int handleMQTTErrorMessages(std::vector<RSCP_MQTT::error_t> & v) {

while (!v.empty()) {
e = v.back();
snprintf(topic, TOPIC_SIZE, "%s/error_message/%d/meta", cfg.prefix, ++i);
if (cfg.prefix) {
snprintf(topic, TOPIC_SIZE, "%s/error_message/%d/meta", cfg.prefix, ++i);
} else {
snprintf(topic, TOPIC_SIZE, "error_message/%d/meta", ++i);
}
snprintf(payload, PAYLOAD_SIZE, "type %d code %d source %s", e.type, e.code, e.source);
sprintf(fifo, "$=%s=%s=%s=$\n", topic, payload, "");
writeFifo(fifo, false);
snprintf(topic, TOPIC_SIZE, "%s/error_message/%d", cfg.prefix, i);
if (cfg.prefix) {
snprintf(topic, TOPIC_SIZE, "%s/error_message/%d", cfg.prefix, i);
} else {
snprintf(topic, TOPIC_SIZE, "error_message/%d", i);
}
sprintf(fifo, "$=%s=%s=%s=$\n", topic, e.message, "");
writeFifo(fifo, false);
v.pop_back();
Expand Down Expand Up @@ -817,7 +829,7 @@ int handleImmediately(RscpProtocol *protocol, SRscpValue *response, uint32_t con
break;
}
}
sprintf(fifo, "$=%s=%s=%s=$\n", topic, payload, "");
sprintf(fifo, "$=%s=%s=%s=$\n", topic, payload, it->unit);
writeFifo(fifo, false);
}
}
Expand Down Expand Up @@ -2613,6 +2625,7 @@ static void mainLoop(void) {
}
publishImmediately((char *)"rscp2p/version", (char *)RSCP2P);
publishImmediately((char *)"rscp2p/long_version", (char *)RSCP2P_LONG);
refreshCache(RSCP_MQTT::RscpMqttCache, (char *)".*");
if (cfg.once) go = false;
}
sleep(1);
Expand Down Expand Up @@ -2690,7 +2703,7 @@ int main(int argc, char *argv[]) {
cfg.statistic_values = true;
cfg.wallbox = false;
cfg.auto_refresh = false;
strcpy(cfg.prefix, DEFAULT_PREFIX);
cfg.prefix = NULL;
cfg.history_start_year = curr_year - 1;
cfg.mqtt_pub = true;
cfg.logfile = NULL;
Expand Down Expand Up @@ -2723,7 +2736,7 @@ int main(int argc, char *argv[]) {
else if (strcasecmp(key, "E3DC_AES_PASSWORD") == 0)
strcpy(cfg.aes_password, value);
else if (strcasecmp(key, "PREFIX") == 0)
strncpy(cfg.prefix, value, 24);
cfg.prefix = strdup(value);
else if (strcasecmp(key, "HISTORY_START_YEAR") == 0)
cfg.history_start_year = atoi(value);
else if (strcasecmp(key, "LOGFILE") == 0) {
Expand Down Expand Up @@ -2863,7 +2876,7 @@ int main(int argc, char *argv[]) {
env = getenv("E3DC_AES_PASSWORD");
if (env) strcpy(cfg.aes_password, env);
env = getenv("PREFIX");
if (env) strncpy(cfg.prefix, env, 24);
if (env) cfg.prefix = strdup(env);
env = getenv("HISTORY_START_YEAR");
if (env) cfg.history_start_year = atoi(env);
env = getenv("INTERVAL");
Expand Down Expand Up @@ -2932,8 +2945,10 @@ int main(int argc, char *argv[]) {
exit(EXIT_FAILURE);
}

addPrefix(RSCP_MQTT::RscpMqttCache, cfg.prefix);
addPrefix(RSCP_MQTT::RscpMqttCacheTempl, cfg.prefix);
if (cfg.prefix) {
addPrefix(RSCP_MQTT::RscpMqttCache, cfg.prefix);
addPrefix(RSCP_MQTT::RscpMqttCacheTempl, cfg.prefix);
}

// Additional Tags
sort(RSCP_MQTT::AdditionalTags.begin(), RSCP_MQTT::AdditionalTags.end(), RSCP_MQTT::compareAdditionalTags);
Expand Down Expand Up @@ -3107,6 +3122,7 @@ int main(int argc, char *argv[]) {
if (cfg.logfile) free(cfg.logfile);
if (cfg.historyfile) free(cfg.historyfile);
if (cfg.raw_topic_regex) free(cfg.raw_topic_regex);
if (cfg.prefix) free(cfg.prefix);

exit(EXIT_SUCCESS);
}
14 changes: 7 additions & 7 deletions RscpMapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,15 +177,15 @@ cache_t cache[] = {
{ 0, 0, IDX_LIMIT_DISCHARGE_BY_HOME_POWER, "limit/discharge/by_home_power", "0", F_AUTO, UNIT_W, 1, 0, false, false, false },
{ 0, 0, IDX_BATTERY_STATE, "battery/state", "", F_AUTO, UNIT_NONE, 1, 0, false, false, false },
{ 0, 0, IDX_GRID_STATE, "grid/state", "", F_AUTO, UNIT_NONE, 1, 0, false, false, false },
{ 0, 0, IDX_SOLAR_POWER_MAX, "solar/power_max", "", F_AUTO, UNIT_W, 1, 0, false, false, false },
{ 0, 0, IDX_HOME_POWER_MIN, "home/power_min", "", F_AUTO, UNIT_W, 1, 0, false, false, false },
{ 0, 0, IDX_HOME_POWER_MAX, "home/power_max", "", F_AUTO, UNIT_W, 1, 0, false, false, false },
{ 0, 0, IDX_GRID_POWER_MIN, "grid/power_min", "", F_AUTO, UNIT_W, 1, 0, false, false, false },
{ 0, 0, IDX_GRID_POWER_MAX, "grid/power_max", "", F_AUTO, UNIT_W, 1, 0, false, false, false },
{ 0, 0, IDX_SOLAR_POWER_MAX, "solar/power_max", "0", F_AUTO, UNIT_W, 1, 0, false, false, false },
{ 0, 0, IDX_HOME_POWER_MIN, "home/power_min", "0", F_AUTO, UNIT_W, 1, 0, false, false, false },
{ 0, 0, IDX_HOME_POWER_MAX, "home/power_max", "0", F_AUTO, UNIT_W, 1, 0, false, false, false },
{ 0, 0, IDX_GRID_POWER_MIN, "grid/power_min", "0", F_AUTO, UNIT_W, 1, 0, false, false, false },
{ 0, 0, IDX_GRID_POWER_MAX, "grid/power_max", "0", F_AUTO, UNIT_W, 1, 0, false, false, false },
{ 0, 0, IDX_BATTERY_SOC_MIN, "battery/soc_min", "", F_AUTO, UNIT_PERCENT, 1, 0, false, false, false },
{ 0, 0, IDX_BATTERY_SOC_MAX, "battery/soc_max", "", F_AUTO, UNIT_PERCENT, 1, 0, false, false, false },
{ 0, 0, IDX_GRID_IN_DURATION, "grid_in_limit_duration", "", F_AUTO, UNIT_MIN, 1, 0, false, false, false },
{ 0, 0, IDX_SUN_DURATION, "sunshine_duration", "", F_AUTO, UNIT_MIN, 1, 0, false, false, false },
{ 0, 0, IDX_GRID_IN_DURATION, "grid_in_limit_duration", "0", F_AUTO, UNIT_MIN, 1, 0, false, false, false },
{ 0, 0, IDX_SUN_DURATION, "sunshine_duration", "0", F_AUTO, UNIT_MIN, 1, 0, false, false, false },
{ 0, TAG_INFO_SW_RELEASE, 0, "system/software", "", F_AUTO, UNIT_NONE, 1, 0, false, false, false },
{ 0, TAG_INFO_PRODUCTION_DATE, 0, "system/production_date", "", F_AUTO, UNIT_NONE, 1, 0, false, false, false },
{ 0, TAG_INFO_SERIAL_NUMBER, 0, "system/serial_number", "", F_AUTO, UNIT_NONE, 1, 0, false, false, false },
Expand Down
1 change: 0 additions & 1 deletion config.min
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ E3DC_PORT=5033
INTERVAL=2
LOG_MODE=OFF
LOGFILE=/tmp/rscp2mqtt.log
PREFIX=e3dc
AUTO_REFRESH=true
DAILY_VALUES=true
STATISTIC_VALUES=true
Expand Down
21 changes: 8 additions & 13 deletions config.template
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,10 @@ HST_REQUESTS=true
DAILY_VALUES=true
#--Publish statistic values
STATISTIC_VALUES=true
#--Save values as retained topics for setup during restart
RETAIN_FOR_SETUP=true

#-Topics
#--Topic prefix (max 24 characters), default is e3dc
PREFIX=e3dc
#-Keys
#--Key prefix, default is no prefix
#PREFIX=e3dc

#-Payload
#--Boolean values true/false or 1/0
Expand All @@ -61,12 +59,9 @@ DCB_REQUESTS=true

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

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

#-Battery SOC Limiter
SOC_LIMITER=true
LIMIT_CHARGE_SOC=0
Expand All @@ -81,8 +76,8 @@ LIMIT_DISCHARGE_BY_HOME_POWER=0
WALLBOX=true
WB_INDEX=0

#-Forced Topics
#-Forced Keys
#--will be published with every cycle
FORCE_PUB=e3dc/[a-z]+/power
FORCE_PUB=e3dc/battery/soc
FORCE_PUB=e3dc/pvi/.*/string_[1,2]
FORCE_PUB=[a-z]+/power
FORCE_PUB=battery/soc
FORCE_PUB=pvi/.*/string_[1,2]
Loading

0 comments on commit 794f081

Please sign in to comment.