Skip to content

Commit c9f1e36

Browse files
committed
Add Modbus
OpenDTU is extended by a Modbus server. The Modbus server serves TCP at port 502. At Modbus ID 1 the server mimicks the Modbus registers in the original DTUPro. At Modbus ID 125 the server serves a SunSpec compatible pseudo inverter that provides the OpenDTU aggregated data from all registered inverters. The OpenDTU Modbus sources were imspired by : https://github.com/ArekKubacki/OpenDTU. See tbnobody#582 for the orignal pull request. The Modbus library used for Modbus communication is: https://github.com/eModbus/eModbus. Documentation for the library is here: https://emodbus.github.io/. The library was choosen over full featured libraries to achieve a lower memory footprint. fixes tbnobody#582 Signed-off-by: Bobby Noelte <[email protected]>
1 parent 1258865 commit c9f1e36

File tree

13 files changed

+1010
-0
lines changed

13 files changed

+1010
-0
lines changed

include/Configuration.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ struct CONFIG_T {
8484
double Latitude;
8585
uint8_t SunsetType;
8686
} Ntp;
87+
struct {
88+
bool Enabled;
89+
uint32_t Port;
90+
uint32_t IDDTUPro;
91+
uint32_t IDTotal;
92+
} Modbus;
8793

8894
struct {
8995
bool Enabled;

include/ModbusDtu.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
#pragma once
3+
4+
#include <TaskSchedulerDeclarations.h>
5+
6+
// eModbus
7+
#include "ModbusServerTCPasync.h"
8+
9+
class ModbusDtuClass {
10+
public:
11+
ModbusDtuClass();
12+
void init(Scheduler& scheduler);
13+
14+
private:
15+
void loop();
16+
17+
Task _loopTask;
18+
};
19+
20+
ModbusMessage OpenDTUTotal(ModbusMessage request);
21+
ModbusMessage DTUPro(ModbusMessage request);
22+
23+
extern ModbusDtuClass ModbusDtu;
24+
extern ModbusServerTCPasync ModbusServer;

include/ModbusSettings.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
#pragma once
3+
4+
class ModbusSettingsClass {
5+
public:
6+
ModbusSettingsClass();
7+
void init();
8+
9+
void performConfig();
10+
11+
private:
12+
void start();
13+
14+
void stop();
15+
};
16+
17+
extern ModbusSettingsClass ModbusSettings;

include/WebApi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "WebApi_inverter.h"
1313
#include "WebApi_limit.h"
1414
#include "WebApi_maintenance.h"
15+
#include "WebApi_modbus.h"
1516
#include "WebApi_mqtt.h"
1617
#include "WebApi_network.h"
1718
#include "WebApi_ntp.h"
@@ -50,6 +51,7 @@ class WebApiClass {
5051
WebApiInverterClass _webApiInverter;
5152
WebApiLimitClass _webApiLimit;
5253
WebApiMaintenanceClass _webApiMaintenance;
54+
WebApiModbusClass _webApiModbus;
5355
WebApiMqttClass _webApiMqtt;
5456
WebApiNetworkClass _webApiNetwork;
5557
WebApiNtpClass _webApiNtp;

include/WebApi_modbus.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
#pragma once
3+
4+
#include <ESPAsyncWebServer.h>
5+
#include <TaskSchedulerDeclarations.h>
6+
7+
class WebApiModbusClass {
8+
public:
9+
void init(AsyncWebServer& server, Scheduler& scheduler);
10+
11+
private:
12+
void onModbusStatus(AsyncWebServerRequest* request);
13+
void onModbusAdminGet(AsyncWebServerRequest* request);
14+
void onModbusAdminPost(AsyncWebServerRequest* request);
15+
};

include/defaults.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@
3030
#define NTP_LATITUDE 51.1657f
3131
#define NTP_SUNSETTYPE 1U
3232

33+
#define MODBUS_ENABLED false
34+
#define MODBUS_PORT 502
35+
#define MODBUS_ID_DTUPRO 1
36+
#define MODBUS_ID_TOTAL 125
37+
3338
#define MQTT_ENABLED false
3439
#define MQTT_HOST ""
3540
#define MQTT_PORT 1883U

platformio.ini

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,17 @@ build_flags =
3535
build_unflags =
3636
-std=gnu++11
3737

38+
; Ignore dependencies of eModbus as they are fulfilled by other library variants
39+
lib_ignore =
40+
AsyncTCP
41+
ESPAsyncTCP
42+
custom-Ethernet
43+
3844
lib_deps =
3945
mathieucarbou/ESP Async WebServer @ 2.8.1
4046
bblanchon/ArduinoJson @ ^6.21.5
4147
https://github.com/bertmelis/espMqttClient.git#v1.6.0
48+
https://github.com/eModbus/eModbus.git
4249
nrf24/RF24 @ ^1.4.8
4350
olikraus/U8g2 @ ^2.35.15
4451
buelowp/sunset @ ^1.1.7

src/Configuration.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ bool ConfigurationClass::write()
5858
ntp["longitude"] = config.Ntp.Longitude;
5959
ntp["sunsettype"] = config.Ntp.SunsetType;
6060

61+
JsonObject modbus = doc.createNestedObject("modbus");
62+
modbus["enabled"] = config.Modbus.Enabled;
63+
modbus["port"] = config.Modbus.Port;
64+
modbus["id_dtupro"] = config.Modbus.IDDTUPro;
65+
modbus["id_total"] = config.Modbus.IDTotal;
66+
6167
JsonObject mqtt = doc.createNestedObject("mqtt");
6268
mqtt["enabled"] = config.Mqtt.Enabled;
6369
mqtt["hostname"] = config.Mqtt.Hostname;
@@ -227,6 +233,12 @@ bool ConfigurationClass::read()
227233
config.Ntp.Longitude = ntp["longitude"] | NTP_LONGITUDE;
228234
config.Ntp.SunsetType = ntp["sunsettype"] | NTP_SUNSETTYPE;
229235

236+
JsonObject modbus = doc["modbus"];
237+
config.Modbus.Enabled = modbus["enabled"] | MODBUS_ENABLED;
238+
config.Modbus.Port = modbus["port"] | MODBUS_PORT;
239+
config.Modbus.IDDTUPro = modbus["id_dtupro"] | MODBUS_ID_DTUPRO;
240+
config.Modbus.IDTotal = modbus["id_total"] | MODBUS_ID_TOTAL;
241+
230242
JsonObject mqtt = doc["mqtt"];
231243
config.Mqtt.Enabled = mqtt["enabled"] | MQTT_ENABLED;
232244
strlcpy(config.Mqtt.Hostname, mqtt["hostname"] | MQTT_HOST, sizeof(config.Mqtt.Hostname));

0 commit comments

Comments
 (0)