Skip to content

Commit

Permalink
Adding horodate guess for historical TIC frames
Browse files Browse the repository at this point in the history
  • Loading branch information
lains committed Apr 10, 2024
1 parent 8dedd99 commit 9cad098
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 17 deletions.
12 changes: 12 additions & 0 deletions inc/domain/TicFrameParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,20 @@ class TicFrameParser {
protected:
void onNewMeasurementAvailable();

/**
* @brief Take a TIC frame date timestamp into account
*
* @param horodate The orodate data that has been read in the current TIC frame
**/
void onNewDate(const TIC::Horodate& horodate);

/**
* @brief Try to guess the arrival time for the current frame and store it as the current frame's horodate
*
* @note This is required for historical TIC frames that include no date timestamp
**/
void guessFrameArrivalTime();

void onRefPowerInfo(uint32_t power);

void onNewComputedPower(int minValue, int maxValue);
Expand Down
5 changes: 5 additions & 0 deletions inc/hal/Stm32DebugOutput.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ class Stm32DebugOutput {
bool send(const std::string& text);
#endif

/**
* @brief Send an unsigned int value to the debug console
*/
bool send(unsigned int value);

/**
* @brief Send the hex dump of a byte buffer to the debug console
*/
Expand Down
12 changes: 10 additions & 2 deletions src/domain/PowerHistory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,17 @@ void PowerHistory::setContext(TicProcessingContext* context) {

void PowerHistory::onNewPowerData(const TicEvaluatedPower& power, const TIC::Horodate& horodate, unsigned int frameSequenceNb) {
#ifdef EMBEDDED_DEBUG_CONSOLE
Stm32DebugOutput::get().send("onNewPowerData()\n");
Stm32DebugOutput::get().send("onNewPowerData() with ");
if (!(power.isValid)) {
Stm32DebugOutput::get().send("in");
}
Stm32DebugOutput::get().send("valid power and ");
if (!(horodate.isValid)) {
Stm32DebugOutput::get().send("in");
}
Stm32DebugOutput::get().send("valid horodate\n");
#endif
if (!power.isValid /*|| !horodate.isValid*/) {
if (!power.isValid || !horodate.isValid) {
#ifdef EMBEDDED_DEBUG_CONSOLE
Stm32DebugOutput::get().send("Skipping invalid frame\n");
#endif
Expand Down
84 changes: 69 additions & 15 deletions src/domain/TicFrameParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,38 @@ void TicFrameParser::onNewDate(const TIC::Horodate& horodate) {
this->lastFrameMeasurements.horodate = horodate;
}

void TicFrameParser::guessFrameArrivalTime() {
this->onNewMeasurementAvailable();
if (this->lastFrameMeasurements.fromFrameNb != this->nbFramesParsed) {
#ifdef EMBEDDED_DEBUG_CONSOLE
Stm32DebugOutput::get().send("It seems we are in a new frame ID ");
Stm32DebugOutput::get().send(static_cast<unsigned int>(this->nbFramesParsed));
Stm32DebugOutput::get().send("\n");
#endif
}
this->lastFrameMeasurements.horodate = TIC::Horodate();
this->lastFrameMeasurements.horodate.isValid = true; /* Fake the horodate */
this->lastFrameMeasurements.horodate.year = 2024;
this->lastFrameMeasurements.horodate.month = 1;
this->lastFrameMeasurements.horodate.second = (this->nbFramesParsed * 3) % 60; /* Assume 1 historical TIC frame every 3 seconds */
unsigned int emulatedHorodateRemainder = (this->nbFramesParsed / 20); /* Counts total remainder as minutes */
this->lastFrameMeasurements.horodate.minute = emulatedHorodateRemainder % 60;
emulatedHorodateRemainder = emulatedHorodateRemainder / 60; /* Now count total remainder as hours */
this->lastFrameMeasurements.horodate.hour = emulatedHorodateRemainder % 24;
this->lastFrameMeasurements.horodate.degradedTime = true;
this->lastFrameMeasurements.horodate.season = TIC::Horodate::Season::Unknown;
/* Note: we discard days and month for now */
#ifdef EMBEDDED_DEBUG_CONSOLE
Stm32DebugOutput::get().send("Injecting timestamp in historical frame: ");
Stm32DebugOutput::get().send(static_cast<unsigned int>(this->lastFrameMeasurements.horodate.hour));
Stm32DebugOutput::get().send(":");
Stm32DebugOutput::get().send(static_cast<unsigned int>(this->lastFrameMeasurements.horodate.minute));
Stm32DebugOutput::get().send(":");
Stm32DebugOutput::get().send(static_cast<unsigned int>(this->lastFrameMeasurements.horodate.second));
Stm32DebugOutput::get().send("\n");
#endif
}

void TicFrameParser::onRefPowerInfo(uint32_t power) {
//FIXME: Todo
}
Expand All @@ -232,15 +264,36 @@ void TicFrameParser::onNewComputedPower(int minValue, int maxValue) {

#ifdef EMBEDDED_DEBUG_CONSOLE
Stm32DebugOutput::get().send("onNewComputedPower(");
char p[6];
p[0]='0' + (minValue / 10000)%10;
p[1]='0' + (minValue / 1000)%10;
p[2]='0' + (minValue / 100)%10;
p[3]='0' + (minValue / 10)%10;
p[4]='0' + (minValue / 1)%10;
p[5]='\0';
Stm32DebugOutput::get().send(p);
Stm32DebugOutput::get().send("W)\n");
if (minValue != maxValue)
Stm32DebugOutput::get().send("[");
{
if (minValue < 0) {
Stm32DebugOutput::get().send("-");
Stm32DebugOutput::get().send(static_cast<unsigned int>(-minValue));
}
else {
Stm32DebugOutput::get().send(static_cast<unsigned int>(minValue));
}
}
if (minValue != maxValue) {
Stm32DebugOutput::get().send(";");
if (maxValue < 0) {
Stm32DebugOutput::get().send("-");
Stm32DebugOutput::get().send(static_cast<unsigned int>(-maxValue));
}
else {
Stm32DebugOutput::get().send(static_cast<unsigned int>(maxValue));
}
Stm32DebugOutput::get().send("]");
}
Stm32DebugOutput::get().send("W) with ");
if (this->lastFrameMeasurements.horodate.isValid) {
Stm32DebugOutput::get().send("a valid");
}
else {
Stm32DebugOutput::get().send("no");
}
Stm32DebugOutput::get().send("horodate\n");
#endif
this->lastFrameMeasurements.instPower.setMinMax(minValue, maxValue);
if (this->onNewPowerData != nullptr) {
Expand All @@ -259,12 +312,7 @@ void TicFrameParser::onDatasetExtracted(const uint8_t* buf, unsigned int cnt) {

#ifdef EMBEDDED_DEBUG_CONSOLE
Stm32DebugOutput::get().send("onDatasetExtracted() called with ");
char sz[4];
sz[0]='0' + (cnt / 100)%10;
sz[1]='0' + (cnt / 10)%10;
sz[2]='0' + (cnt / 1)%10;
sz[3]='\0';
Stm32DebugOutput::get().send(sz);
Stm32DebugOutput::get().send(static_cast<unsigned int>(cnt));
Stm32DebugOutput::get().send(" bytes\n");
#endif
TIC::DatasetView dv(buf, cnt); /* Decode the TIC dataset using a dataset view object */
Expand All @@ -275,6 +323,12 @@ void TicFrameParser::onDatasetExtracted(const uint8_t* buf, unsigned int cnt) {
Stm32DebugOutput::get().send(dv.labelBuffer, dv.labelSz);
Stm32DebugOutput::get().send("\n");
#endif
if (dv.decodedType == TIC::DatasetView::ValidHistorical) { /* In this case, we will have no horodate, evaluate time instead */
#ifdef EMBEDDED_DEBUG_CONSOLE
Stm32DebugOutput::get().send("Dataset above is following historical format\n");
#endif
this->guessFrameArrivalTime();
}
//std::vector<uint8_t> datasetLabel(dv.labelBuffer, dv.labelBuffer+dv.labelSz);
//std::cout << "Dataset has label \"" << std::string(datasetLabel.begin(), datasetLabel.end()) << "\"\n";
if (dv.labelSz == 4 &&
Expand Down
21 changes: 21 additions & 0 deletions src/hal/Stm32DebugOutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,27 @@ bool send(const std::string& text) {
}
#endif

bool Stm32DebugOutput::send(unsigned int value) {
char valueAsInt[10 + 1];
char *firstNon0Digit = nullptr;
char *currentDigit = valueAsInt + 10;
*currentDigit = '\0'; /* Terminate the string */
do {
currentDigit--;
*currentDigit = '0' + (value % 10);
if (*currentDigit != '0') {
firstNon0Digit = currentDigit;
}
value /= 10;
} while (currentDigit != valueAsInt /* Check for underflow */);
if (!firstNon0Digit) {
valueAsInt[0] = '0';
firstNon0Digit = valueAsInt;
valueAsInt[1] = '\0';
}
return this->send(firstNon0Digit);
}

bool Stm32DebugOutput::hexdumpBuffer(const uint8_t* buffer, unsigned int len) {
char byteHexDump[]="@@";
unsigned char nibble;
Expand Down

0 comments on commit 9cad098

Please sign in to comment.