diff --git a/MqttClient.cpp b/MqttClient.cpp index 30f3d35..6c023b3 100644 --- a/MqttClient.cpp +++ b/MqttClient.cpp @@ -31,17 +31,17 @@ Metro secondTick = Metro(1000); MqttClient::MqttClient(RequestSender *meterBusMaster) : - m_client(), m_meterBusMaster(meterBusMaster), m_mqttClient(MQTT_BROKER, MQTT_PORT, callback, m_client), - m_disconnectState(3), m_disconnectTime(millis()), m_uptime(0) + m_client(), m_meterBusMaster(meterBusMaster), m_mqttClient(MQTT_BROKER, MQTT_PORT, callback, m_client), + m_disconnectState(3), m_disconnectTime(millis()), m_uptime(0), m_deviceIdx(0) { for (uint8_t i = 0; i < NUM_OF_DEVICES; i++) { - m_mbusDevTuple[i] = { 0, 0, 0 }; + m_mbusDevTuple[i] = { 0, 0, 0, 0 }; } - m_mbusDevTuple[0] = { 0x53, 60, 0 }; // light meter + m_mbusDevTuple[0] = { 1, 0x53, 60, 0 }; // light meter } -void MqttClient::sendResponse(uint8_t *responseBuffer, uint16_t responseBufferLength) { +void MqttClient::sendResponse(uint8_t *responseBuffer, uint16_t responseBufferLength, uint8_t token) { char strbuf[256]; memset(strbuf, sizeof(strbuf), 0); PString buf = PString(strbuf, sizeof(strbuf)); @@ -49,21 +49,22 @@ void MqttClient::sendResponse(uint8_t *responseBuffer, uint16_t responseBufferLe buf << "{ \"metadata\": { \"device\": \"MeterbusHub\" }, " << "\"data\": {" << - "\"uptime\": " << m_uptime << ", " + "\"token\": " << token << ", " << + "\"uptime\": " << m_uptime << ", " << "\"telegram\": \""; - uint16_t i = 0; - while (true) { - if (responseBuffer[i] <= 0x0f) { - buf.print("0"); - } - buf.print(responseBuffer[i], HEX); - buf.print(" "); - i++; - if (i == responseBufferLength) { - break; - } - } + uint16_t i = 0; + while (true) { + if (responseBuffer[i] <= 0x0f) { + buf.print("0"); + } + buf.print(responseBuffer[i], HEX); + buf.print(" "); + i++; + if (i == responseBufferLength) { + break; + } + } buf << "\"}}"; @@ -77,7 +78,7 @@ void MqttClient::sendResponse(uint8_t *responseBuffer, uint16_t responseBufferLe // m_server.write(responseBuffer, responseBufferLength); } -void MqttClient::sendError(uint8_t code) { +void MqttClient::sendError(uint8_t code, uint8_t token) { } void MqttClient::begin() { @@ -130,21 +131,40 @@ void MqttClient::exec() { Serial << "no MQTT connection, message lost: " << msg << endl; } - for (uint8_t i = 0; i < NUM_OF_DEVICES; i++) { - if ((m_mbusDevTuple[i].address != 0) && (m_mbusDevTuple[i].timer == 0)) { - m_mbusDevTuple[i].timer = m_mbusDevTuple[i].queryPeriod; - Serial << "Issue request for device " << m_mbusDevTuple[i].address << endl; - - uint8_t *sendBuffer = m_meterBusMaster->getSendBuffer(); - sendBuffer[0] = 0x10; - sendBuffer[1] = 0x5b; - sendBuffer[2] = m_mbusDevTuple[i].address; - sendBuffer[3] = (uint8_t)(sendBuffer[1] + sendBuffer[2]); - sendBuffer[4] = 0x16; - m_meterBusMaster->sendBufferReady(5, this); + if ((m_mbusDevTuple[i].address != 0) && (m_mbusDevTuple[i].timer != 0)) { + m_mbusDevTuple[i].timer -= 1; + if (m_mbusDevTuple[i].timer == 0) { + Serial << "Device " << m_mbusDevTuple[i].token << " ready for request" << endl; + } else { + Serial << "Device " << m_mbusDevTuple[i].token << " not ready for request, timer: " << m_mbusDevTuple[i].timer << endl; + } } - m_mbusDevTuple[i].timer -= 1; + } + + while (m_deviceIdx < NUM_OF_DEVICES) { + if ((m_mbusDevTuple[m_deviceIdx].address != 0) && (m_mbusDevTuple[m_deviceIdx].timer == 0)) { + m_mbusDevTuple[m_deviceIdx].timer = m_mbusDevTuple[m_deviceIdx].queryPeriod; + Serial << "Issue request for device " << m_mbusDevTuple[m_deviceIdx].token << endl; + uint8_t *sendBuffer = m_meterBusMaster->getSendBuffer(); + if (sendBuffer != 0) { + Serial << "send buffer ready" << endl; + + sendBuffer[0] = 0x10; + sendBuffer[1] = 0x5b; + sendBuffer[2] = m_mbusDevTuple[m_deviceIdx].address; + sendBuffer[3] = (uint8_t)(sendBuffer[1] + sendBuffer[2]); + sendBuffer[4] = 0x16; + m_meterBusMaster->sendBufferReady(5, m_mbusDevTuple[m_deviceIdx].token, this); + break; + } else { + Serial << "no send buffer ready" << endl; + } + } + m_deviceIdx++; + } + if (m_deviceIdx >= NUM_OF_DEVICES) { + m_deviceIdx = 0; } } diff --git a/MqttClient.h b/MqttClient.h index a51e380..bf5053f 100644 --- a/MqttClient.h +++ b/MqttClient.h @@ -17,6 +17,7 @@ #define NUM_OF_DEVICES 10 typedef struct { + uint8_t token; uint8_t address; uint16_t queryPeriod; uint16_t timer; @@ -27,8 +28,8 @@ public: MqttClient(RequestSender *meterBusMaster); void begin(); void exec(); - virtual void sendResponse(uint8_t *responseBuffer, uint16_t responseBufferLength); - virtual void sendError(uint8_t code); + virtual void sendResponse(uint8_t *responseBuffer, uint16_t responseBufferLength, uint8_t token); + virtual void sendError(uint8_t code, uint8_t token); private: EthernetClient m_client; RequestSender *m_meterBusMaster; @@ -36,6 +37,7 @@ private: uint8_t m_disconnectState; uint32_t m_disconnectTime; uint32_t m_uptime; + uint8_t m_deviceIdx; mbusDevTuple_t m_mbusDevTuple[NUM_OF_DEVICES]; }; diff --git a/mBusDialog.h b/mBusDialog.h index 17e620d..bcdaa29 100644 --- a/mBusDialog.h +++ b/mBusDialog.h @@ -6,14 +6,14 @@ class ResponseCallback { public: - virtual void sendResponse(uint8_t *responseBuffer, uint16_t responseBufferLength) =0; - virtual void sendError(uint8_t code) = 0; + virtual void sendResponse(uint8_t *responseBuffer, uint16_t responseBufferLength, uint8_t token) =0; + virtual void sendError(uint8_t code, uint8_t token) = 0; }; class RequestSender { public: virtual uint8_t *getSendBuffer() =0; - virtual void sendBufferReady(uint16_t bufLen, ResponseCallback *responseCallback) =0; + virtual void sendBufferReady(uint16_t bufLen, uint8_t token, ResponseCallback *responseCallback) =0; }; diff --git a/meterBusMaster.cpp b/meterBusMaster.cpp index 449db14..b65469f 100644 --- a/meterBusMaster.cpp +++ b/meterBusMaster.cpp @@ -99,12 +99,12 @@ String SendOctets::exec(String params) { if (err) { return "error"; } else { - m_meterBusMaster->sendBufferReady(sendBufLen, this); + m_meterBusMaster->sendBufferReady(sendBufLen, 1, this); return "success"; } } -void SendOctets::sendResponse(uint8_t *responseBuffer, uint16_t responseBufferLength) { +void SendOctets::sendResponse(uint8_t *responseBuffer, uint16_t responseBufferLength, uint8_t token) { Print *out = m_server; out->print("SO RESP: "); uint16_t i = 0; @@ -122,7 +122,7 @@ void SendOctets::sendResponse(uint8_t *responseBuffer, uint16_t responseBufferLe out->println(""); } -void SendOctets::sendError(uint8_t code) { +void SendOctets::sendError(uint8_t code, uint8_t token) { switch (code) { case 1: m_server->println("SO RESP: no resp."); @@ -139,8 +139,8 @@ void SendOctets::sendError(uint8_t code) { MeterBusMaster::MeterBusMaster() : m_sendOctets(this), m_measureCurrent(this), m_calibrationSupport(this), m_cmdReadyToSend(false), m_cmdReadyFromRecv(false), m_expectResponse(false), - m_sendBufLen(0), m_recvBufLen(0), m_retransmitCount(0), m_responseCallback(0), - m_sampling(true), m_calibration(false) { + m_sendBufLen(0), m_recvBufLen(0), m_retransmitCount(0), m_token(0), + m_responseCallback(0), m_sampling(true), m_calibration(false) { pinMode(RX_EN_PIN, OUTPUT); digitalWrite(RX_EN_PIN, RX_DISABLE); Serial3.begin(2400); @@ -160,11 +160,12 @@ uint8_t *MeterBusMaster::getSendBuffer() { return m_expectResponse ? 0 : m_sendBuffer; } -void MeterBusMaster::sendBufferReady(uint16_t sendBufLen, ResponseCallback *responseCallback) { +void MeterBusMaster::sendBufferReady(uint16_t sendBufLen, uint8_t token, ResponseCallback *responseCallback) { m_cmdReadyToSend = true; m_retransmitCount = 0; m_sendBufLen = sendBufLen; m_responseCallback = responseCallback; + m_token = token; } void MeterBusMaster::prepareResponse(bool err, uint8_t in) { @@ -173,7 +174,7 @@ void MeterBusMaster::prepareResponse(bool err, uint8_t in) { if (err) { if (m_responseCallback != 0) { - m_responseCallback->sendError(1); + m_responseCallback->sendError(1, m_token); } expectedChars = 0; state = 0; @@ -212,9 +213,10 @@ void MeterBusMaster::prepareResponse(bool err, uint8_t in) { if (expectedChars == 0) { if (m_responseCallback != 0) { - m_responseCallback->sendResponse(m_recvBuffer, m_recvBufLen); + m_responseCallback->sendResponse(m_recvBuffer, m_recvBufLen, m_token); } m_expectResponse = false; + m_token = 0; state = 0; m_responseCallback = 0; } diff --git a/meterBusMaster.h b/meterBusMaster.h index ca0e788..d60bc1e 100644 --- a/meterBusMaster.h +++ b/meterBusMaster.h @@ -24,8 +24,8 @@ public: virtual String getCmdName() { return "SO"; } virtual String getHelp() { return "Send octets"; } virtual String exec(String params); - virtual void sendResponse(uint8_t *responseBuffer, uint16_t responseBufferLength); - virtual void sendError(uint8_t code); + virtual void sendResponse(uint8_t *responseBuffer, uint16_t responseBufferLength, uint8_t token); + virtual void sendError(uint8_t code, uint8_t token); private: RequestSender *m_meterBusMaster; }; @@ -62,7 +62,7 @@ public: void begin(CmdServer *cmdServer); void exec(); uint8_t *getSendBuffer(); - void sendBufferReady(uint16_t bufLen, ResponseCallback *responseCallback); + void sendBufferReady(uint16_t bufLen, uint8_t token, ResponseCallback *responseCallback); friend class CalibrationSupport; private: SendOctets m_sendOctets; @@ -74,6 +74,7 @@ private: uint16_t m_sendBufLen; uint16_t m_recvBufLen; uint8_t m_retransmitCount; + uint8_t m_token; ResponseCallback *m_responseCallback; uint8_t m_sendBuffer[SEND_BUFFER_SIZE]; uint8_t m_recvBuffer[RECEIVE_BUFFER_SIZE]; diff --git a/meterBusServer.cpp b/meterBusServer.cpp index 365a36b..26d4463 100644 --- a/meterBusServer.cpp +++ b/meterBusServer.cpp @@ -7,7 +7,7 @@ MeterBusServer::MeterBusServer(uint16_t port, RequestSender *meterBusMaster) : m_server(port), m_client(255), m_meterBusMaster(meterBusMaster) { } -void MeterBusServer::sendResponse(uint8_t *responseBuffer, uint16_t responseBufferLength) { +void MeterBusServer::sendResponse(uint8_t *responseBuffer, uint16_t responseBufferLength, uint8_t token) { m_server.write(responseBuffer, responseBufferLength); } @@ -31,7 +31,7 @@ void MeterBusServer::exec() { *(sendBuffer + sendBufLen) = ch; sendBufLen++; } - m_meterBusMaster->sendBufferReady(sendBufLen, this); + m_meterBusMaster->sendBufferReady(sendBufLen, 1, this); } } } diff --git a/meterBusServer.h b/meterBusServer.h index ebdf01b..297e22f 100644 --- a/meterBusServer.h +++ b/meterBusServer.h @@ -18,7 +18,7 @@ public: MeterBusServer(uint16_t port, RequestSender *meterBusMaster); void begin(); void exec(); - virtual void sendResponse(uint8_t *responseBuffer, uint16_t responseBufferLength); + virtual void sendResponse(uint8_t *responseBuffer, uint16_t responseBufferLength, uint8_t token); virtual void sendError(uint8_t code); private: EthernetServer m_server;