Added option to output TCP requested modbus data to MQTT (#18231)

https://github.com/arendst/Tasmota/discussions/17369

Co-authored-by: JeroenSt <nospam@nospam.org>
This commit is contained in:
Jeroen 2023-03-21 09:39:32 +01:00 committed by GitHub
parent fbbb4eaf84
commit a68bc49cab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 26 additions and 7 deletions

View File

@ -81,12 +81,13 @@ void (*const ModbusBridgeCommand[])(void) PROGMEM = {
#define D_CMND_MODBUS_TCP_START "TCPStart"
#define D_CMND_MODBUS_TCP_CONNECT "TCPConnect"
#define D_CMND_MODBUS_TCP_MQTT "TCPMqtt"
const char kModbusBridgeCommands[] PROGMEM = "Modbus|" // Prefix
D_CMND_MODBUS_TCP_START "|" D_CMND_MODBUS_TCP_CONNECT "|" D_CMND_MODBUS_SEND "|" D_CMND_MODBUS_SETBAUDRATE "|" D_CMND_MODBUS_SETSERIALCONFIG;
D_CMND_MODBUS_TCP_START "|" D_CMND_MODBUS_TCP_CONNECT "|" D_CMND_MODBUS_TCP_MQTT "|" D_CMND_MODBUS_SEND "|" D_CMND_MODBUS_SETBAUDRATE "|" D_CMND_MODBUS_SETSERIALCONFIG;
void (*const ModbusBridgeCommand[])(void) PROGMEM = {
&CmndModbusTCPStart, &CmndModbusTCPConnect,
&CmndModbusTCPStart, &CmndModbusTCPConnect, &CmndModbusTCPMqtt,
&CmndModbusBridgeSend, &CmndModbusBridgeSetBaudrate, &CmndModbusBridgeSetConfig};
struct ModbusBridgeTCP
@ -97,6 +98,7 @@ struct ModbusBridgeTCP
uint8_t *tcp_buf = nullptr; // data transfer buffer
IPAddress ip_filter;
uint16_t tcp_transaction_id = 0;
bool output_mqtt = false;
};
ModbusBridgeTCP modbusBridgeTCP;
@ -328,7 +330,7 @@ void ModbusBridgeHandle(void)
{
#ifdef USE_MODBUS_BRIDGE_TCP
// If tcp client connected don't log error and exit this function (do not process)
if (nitems(modbusBridgeTCP.client_tcp))
if (nitems(modbusBridgeTCP.client_tcp) && !modbusBridgeTCP.output_mqtt)
{
return;
}
@ -657,25 +659,28 @@ void ModbusTCPHandle(void)
modbusBridgeTCP.tcp_transaction_id = (uint16_t)((((uint16_t)modbusBridgeTCP.tcp_buf[0]) << 8) | ((uint16_t)modbusBridgeTCP.tcp_buf[1]));
if (mbfunctioncode <= 2)
if (mbfunctioncode <= 2) // Multiple Coils, Inputs
{
count = (uint16_t)((((uint16_t)modbusBridgeTCP.tcp_buf[10]) << 8) | ((uint16_t)modbusBridgeTCP.tcp_buf[11]));
modbusBridge.byteCount = ((count - 1) >> 3) + 1;
modbusBridge.dataCount = ((count - 1) >> 4) + 1;
modbusBridge.dataCount = count;
modbusBridge.type = ModbusBridgeType::mb_bit;
}
else if (mbfunctioncode <= 4)
else if (mbfunctioncode <= 4) // Multiple Holding or input registers
{
count = (uint16_t)((((uint16_t)modbusBridgeTCP.tcp_buf[10]) << 8) | ((uint16_t)modbusBridgeTCP.tcp_buf[11]));
modbusBridge.byteCount = count * 2;
modbusBridge.dataCount = count;
modbusBridge.type = ModbusBridgeType::mb_uint16;
}
else
else // Write coil(s) or register(s)
{
// For functioncode 15 & 16 ignore bytecount, modbusBridgeModbus does calculate this
uint8_t dataStartByte = mbfunctioncode <= 6 ? 10 : 13;
uint16_t byteCount = (buf_len - dataStartByte);
modbusBridge.byteCount = 2;
modbusBridge.dataCount = 1;
modbusBridge.type = ModbusBridgeType::mb_uint16;
writeData = (uint16_t *)malloc((byteCount / 2)+1);
if (nullptr == writeData)
@ -705,6 +710,14 @@ void ModbusTCPHandle(void)
modbusBridgeModbus->Send(mbdeviceaddress, mbfunctioncode, mbstartaddress, count, writeData);
if (modbusBridgeTCP.output_mqtt)
{
modbusBridge.deviceAddress = mbdeviceaddress;
modbusBridge.functionCode = (ModbusBridgeFunctionCode)mbfunctioncode;
modbusBridge.startAddress = mbstartaddress;
modbusBridge.count = count;
}
free(writeData);
}
}
@ -1111,6 +1124,12 @@ void CmndModbusTCPConnect(void)
ResponseCmndDone();
}
void CmndModbusTCPMqtt(void)
{
modbusBridgeTCP.output_mqtt = XdrvMailbox.payload;
ResponseCmndDone();
}
#endif
/*********************************************************************************************\