This commit is contained in:
helgeerbe 2022-08-19 15:53:18 +02:00
parent b8ffa37e97
commit 7140574c37
3 changed files with 40 additions and 33 deletions

View File

@ -41,6 +41,8 @@ char MODULE[] = "VE.Frame"; // Victron seems to use this to find out where loggi
// The name of the record that contains the checksum. // The name of the record that contains the checksum.
static constexpr char checksumTagName[] = "CHECKSUM"; static constexpr char checksumTagName[] = "CHECKSUM";
HardwareSerial VedirectSerial(1);
VeDirectFrameHandler VeDirect; VeDirectFrameHandler VeDirect;
VeDirectFrameHandler::VeDirectFrameHandler() : VeDirectFrameHandler::VeDirectFrameHandler() :
@ -51,32 +53,35 @@ VeDirectFrameHandler::VeDirectFrameHandler() :
veEnd(0), veEnd(0),
mState(IDLE), mState(IDLE),
mChecksum(0), mChecksum(0),
mTextPointer(0), idx(0),
tempName(), tempName(),
tempValue() tempValue(),
_pollInterval(5),
_lastPoll(0)
{ {
} }
void VeDirectFrameHandler::init() void VeDirectFrameHandler::init()
{ {
Serial2.begin(19200, SERIAL_8N1, VICTRON_PIN_RX, VICTRON_PIN_TX); VedirectSerial.begin(19200, SERIAL_8N1, VICTRON_PIN_RX, VICTRON_PIN_TX);
Serial2.flush(); VedirectSerial.flush();
} }
void VeDirectFrameHandler::setPollInterval(uint32_t interval) void VeDirectFrameHandler::setPollInterval(unsigned long interval)
{ {
_pollInterval = interval; _pollInterval = interval;
} }
void VeDirectFrameHandler::loop() void VeDirectFrameHandler::loop()
{ {
unsigned long now = millis(); polltime = _pollInterval;
_frameEnd = false;
if ((millis() - getLastUpdate()) > (_pollInterval * 1000)) { if ((millis() - getLastUpdate()) < _pollInterval * 1000) {
while ( Serial2.available() && (!_frameEnd) && (millis() - now < 500)) { return;
rxData(Serial2.read()); }
}
while ( VedirectSerial.available()) {
rxData(VedirectSerial.read());
} }
} }
@ -109,8 +114,8 @@ void VeDirectFrameHandler::rxData(uint8_t inbyte)
} }
break; break;
case RECORD_BEGIN: case RECORD_BEGIN:
mTextPointer = mName; idx = 0;
*mTextPointer++ = inbyte; mName[idx++] = inbyte;
mState = RECORD_NAME; mState = RECORD_NAME;
break; break;
case RECORD_NAME: case RECORD_NAME:
@ -118,20 +123,20 @@ void VeDirectFrameHandler::rxData(uint8_t inbyte)
switch(inbyte) { switch(inbyte) {
case '\t': case '\t':
// the Checksum record indicates a EOR // the Checksum record indicates a EOR
if ( mTextPointer < (mName + sizeof(mName)) ) { if ( idx < sizeof(mName) ) {
*mTextPointer = 0; /* Zero terminate */ mName[idx] = 0; /* Zero terminate */
if (strcmp(mName, checksumTagName) == 0) { if (strcmp(mName, checksumTagName) == 0) {
mState = CHECKSUM; mState = CHECKSUM;
break; break;
} }
} }
mTextPointer = mValue; /* Reset value pointer */ idx = 0; /* Reset value pointer */
mState = RECORD_VALUE; mState = RECORD_VALUE;
break; break;
default: default:
// add byte to name, but do no overflow // add byte to name, but do no overflow
if ( mTextPointer < (mName + sizeof(mName)) ) if ( idx < sizeof(mName) )
*mTextPointer++ = inbyte; mName[idx++] = inbyte;
break; break;
} }
break; break;
@ -140,8 +145,8 @@ void VeDirectFrameHandler::rxData(uint8_t inbyte)
switch(inbyte) { switch(inbyte) {
case '\n': case '\n':
// forward record, only if it could be stored completely // forward record, only if it could be stored completely
if ( mTextPointer < (mValue + sizeof(mValue)) ) { if ( idx < sizeof(mValue) ) {
*mTextPointer = 0; // make zero ended mValue[idx] = 0; // make zero ended
textRxEvent(mName, mValue); textRxEvent(mName, mValue);
} }
mState = RECORD_BEGIN; mState = RECORD_BEGIN;
@ -150,8 +155,8 @@ void VeDirectFrameHandler::rxData(uint8_t inbyte)
break; break;
default: default:
// add byte to value, but do no overflow // add byte to value, but do no overflow
if ( mTextPointer < (mValue + sizeof(mValue)) ) if ( idx < sizeof(mValue) )
*mTextPointer++ = inbyte; mValue[idx++] = inbyte;
break; break;
} }
break; break;
@ -213,7 +218,6 @@ void VeDirectFrameHandler::frameEndEvent(bool valid) {
setLastUpdate(); setLastUpdate();
} }
frameIndex = 0; // reset frame frameIndex = 0; // reset frame
_frameEnd = true;
} }
/* /*
@ -236,7 +240,7 @@ bool VeDirectFrameHandler::hexRxEvent(uint8_t inbyte) {
return true; // stubbed out for future return true; // stubbed out for future
} }
uint32_t VeDirectFrameHandler::getLastUpdate() unsigned long VeDirectFrameHandler::getLastUpdate()
{ {
return _lastPoll; return _lastPoll;
} }

View File

@ -24,15 +24,17 @@ const byte buffLen = 40; // Maximum number of lines possi
#define VICTRON_PIN_RX 22 #define VICTRON_PIN_RX 22
#endif #endif
class VeDirectFrameHandler { class VeDirectFrameHandler {
public: public:
VeDirectFrameHandler(); VeDirectFrameHandler();
void init(); void init();
void setPollInterval(uint32_t interval); void setPollInterval(unsigned long interval);
void loop(); void loop();
uint32_t getLastUpdate(); unsigned long getLastUpdate();
void setLastUpdate(); void setLastUpdate();
String getPidAsString(const char* pid); String getPidAsString(const char* pid);
String getCsAsString(const char* pid); String getCsAsString(const char* pid);
@ -45,6 +47,7 @@ public:
int frameIndex; // which line of the frame are we on int frameIndex; // which line of the frame are we on
int veEnd; // current size (end) of the public buffer int veEnd; // current size (end) of the public buffer
unsigned long polltime=0;
private: private:
//bool mStop; // not sure what Victron uses this for, not using //bool mStop; // not sure what Victron uses this for, not using
@ -62,7 +65,7 @@ private:
uint8_t mChecksum; // checksum value uint8_t mChecksum; // checksum value
char * mTextPointer; // pointer to the private buffer we're writing to, name or value int idx; // index to the private buffer we're writing to, name or value
char mName[9]; // buffer for the field name char mName[9]; // buffer for the field name
char mValue[33]; // buffer for the field value char mValue[33]; // buffer for the field value
@ -74,9 +77,8 @@ private:
void frameEndEvent(bool); void frameEndEvent(bool);
void logE(const char *, const char *); void logE(const char *, const char *);
bool hexRxEvent(uint8_t); bool hexRxEvent(uint8_t);
uint32_t _pollInterval; unsigned long _pollInterval;
uint32_t _lastPoll = 0; unsigned long _lastPoll;
bool _frameEnd = false;
}; };
extern VeDirectFrameHandler VeDirect; extern VeDirectFrameHandler VeDirect;

View File

@ -48,7 +48,7 @@ void WebApiWsVedirectLiveClass::loop()
// Update on ve.direct change or at least after 10 seconds // Update on ve.direct change or at least after 10 seconds
if (millis() - _lastWsPublish > (10 * 1000) || (maxTimeStamp != _newestVedirectTimestamp)) { if (millis() - _lastWsPublish > (10 * 1000) || (maxTimeStamp != _newestVedirectTimestamp)) {
DynamicJsonDocument root(40960); DynamicJsonDocument root(1024);
JsonVariant var = root; JsonVariant var = root;
generateJsonResponse(var); generateJsonResponse(var);
@ -111,7 +111,8 @@ void WebApiWsVedirectLiveClass::generateJsonResponse(JsonVariant& root)
root[F(VeDirect.veName[i])] = VeDirect.veValue[i]; root[F(VeDirect.veName[i])] = VeDirect.veValue[i];
} }
} }
root[F("polltime")] = VeDirect.polltime;
root[F("VE.end")] = VeDirect.veEnd;
if (VeDirect.getLastUpdate() > _newestVedirectTimestamp) { if (VeDirect.getLastUpdate() > _newestVedirectTimestamp) {
_newestVedirectTimestamp = VeDirect.getLastUpdate(); _newestVedirectTimestamp = VeDirect.getLastUpdate();
} }
@ -132,7 +133,7 @@ void WebApiWsVedirectLiveClass::onWebsocketEvent(AsyncWebSocket* server, AsyncWe
void WebApiWsVedirectLiveClass::onLivedataStatus(AsyncWebServerRequest* request) void WebApiWsVedirectLiveClass::onLivedataStatus(AsyncWebServerRequest* request)
{ {
AsyncJsonResponse* response = new AsyncJsonResponse(false, 40960U); AsyncJsonResponse* response = new AsyncJsonResponse(false, 1024U);
JsonVariant root = response->getRoot().as<JsonVariant>(); JsonVariant root = response->getRoot().as<JsonVariant>();
generateJsonResponse(root); generateJsonResponse(root);