Skip to content

Commit

Permalink
Add a CAN message logger
Browse files Browse the repository at this point in the history
Added a class that logs all CAN messages related to the VT to a Vector ASCII CAN log file.
  • Loading branch information
ad3154 committed Dec 22, 2023
1 parent 64ee36d commit 8428193
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 10 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ target_sources(
"src/InputStringComponent.cpp"
"src/AlarmMaskAudio.cpp"
"src/AppImages.cpp"
"src/ASCIILogFile.cpp"
"src/InputListComponent.cpp")

target_include_directories(AgISOVirtualTerminal
Expand Down
31 changes: 31 additions & 0 deletions include/ASCIILogFile.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//================================================================================================
/// @file ASCIILogFile.hpp
///
/// @brief Defines a CAN logger that saves messages in a Vector .asc file.
/// @author Adrian Del Grosso
///
/// @copyright 2023 Adrian Del Grosso
//================================================================================================
#ifndef ASCII_LOG_FILE_HPP
#define ASCII_LOG_FILE_HPP

#include "isobus/hardware_integration/can_hardware_interface.hpp"

#include "JuceHeader.h"

/// @brief Logs to Vector .asc file
class ASCIILogFile
{
public:
ASCIILogFile();

~ASCIILogFile() = default;

private:
File logFile;
std::shared_ptr<void> canFrameReceivedListener;
std::shared_ptr<void> canFrameSentListener;
Time initialTimestamp;
};

#endif // ASCII_LOG_FILE_HPP
2 changes: 0 additions & 2 deletions include/ServerMainComponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,6 @@ class ServerMainComponent : public juce::Component
SoundPlayer mSoundPlayer;
AudioDeviceManager mAudioDeviceManager;
std::unique_ptr<AlertWindow> popupMenu;
std::unique_ptr<FileChooser> diagnosticFileChooser;
std::unique_ptr<ZipFile::Builder> diagnosticFileBuilder;
std::uint8_t numberOfPoolsToRender = 0;
std::uint8_t numberPhysicalSoftKeys = 6;
std::uint8_t numberVirtualSoftKeys = 64;
Expand Down
111 changes: 111 additions & 0 deletions src/ASCIILogFile.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*******************************************************************************
** @file ASCIILogFile.cpp
** @author Adrian Del Grosso
** @copyright The Open-Agriculture Developers
*******************************************************************************/
#include "ASCIILogFile.hpp"

#include "isobus/utility/system_timing.hpp"
#include "isobus/utility/to_string.hpp"

ASCIILogFile::ASCIILogFile()
{
auto currentTime = Time::getCurrentTime().toString(true, true, true, false);
initialTimestamp = Time::getCurrentTime();
auto fileNameTime = currentTime;
fileNameTime = currentTime.replaceCharacter(' ', '_');
fileNameTime = currentTime.replaceCharacter(':', '_');

logFile = File(File::getSpecialLocation(File::userApplicationDataDirectory).getFullPathName() +
File::getSeparatorString() +
"Open-Agriculture" +
File::getSeparatorString() +
"CANLog_" +
fileNameTime +
".asc");

// Prune old log files
auto logDirectory = logFile.getParentDirectory();
auto childFiles = logDirectory.findChildFiles(File::findFiles, false, "*.asc");

for (auto &file : childFiles)
{
if (file.getCreationTime() < Time::getCurrentTime() - RelativeTime::days(3))
{
file.deleteFile();
}
}

// Write vector ascii header
if (logFile.hasWriteAccess())
{
logFile.appendText("date " + currentTime + "\n");
logFile.appendText("base hex timestamps absolute\n");
logFile.appendText("no internal events logged\n");
canFrameReceivedListener = isobus::CANHardwareInterface::get_can_frame_received_event_dispatcher().add_listener([this](const isobus::CANMessageFrame &canFrame) {
logFile.appendText(" ");
auto currentTime = Time::getCurrentTime() - initialTimestamp;
auto milliseconds = isobus::to_string(currentTime.inMilliseconds() % 1000);

while (milliseconds.length() < 3)
{
milliseconds = "0" + milliseconds;
}

logFile.appendText(isobus::to_string(std::floor(currentTime.inSeconds())) +
"." +
milliseconds +
"000 1 " +
String::toHexString(canFrame.identifier).toUpperCase().toStdString() +
"x Rx d " +
isobus::to_string(static_cast<int>(canFrame.dataLength)) +
" ");

for (std::uint_fast8_t i = 0; i < canFrame.dataLength; i++)
{
logFile.appendText(String::toHexString(canFrame.data[i]).paddedLeft('0', 2).toUpperCase().toStdString() + " ");
}

for (std::uint_fast8_t i = canFrame.dataLength; i < 8; i++)
{
logFile.appendText("00 ");
}
logFile.appendText("\n");
});

canFrameSentListener = isobus::CANHardwareInterface::get_can_frame_transmitted_event_dispatcher().add_listener([this](const isobus::CANMessageFrame &canFrame) {
logFile.appendText(" ");
auto currentTime = Time::getCurrentTime() - initialTimestamp;
auto milliseconds = isobus::to_string(currentTime.inMilliseconds() % 1000);

while (milliseconds.length() < 3)
{
milliseconds = "0" + milliseconds;
}

logFile.appendText(isobus::to_string(std::floor(currentTime.inSeconds())) +
"." +
milliseconds +
"000 1 " +
String::toHexString(canFrame.identifier).toUpperCase().toStdString() +
"x Tx d " +
isobus::to_string(static_cast<int>(canFrame.dataLength)) +
" ");

for (std::uint_fast8_t i = 0; i < canFrame.dataLength; i++)
{
logFile.appendText(String::toHexString(canFrame.data[i]).paddedLeft('0', 2).toUpperCase().toStdString() + " ");
}

for (std::uint_fast8_t i = canFrame.dataLength; i < 8; i++)
{
logFile.appendText("00 ");
}
logFile.appendText("\n");
});
}
else
{
RuntimePermissions::request(RuntimePermissions::writeExternalStorage, nullptr);
}
}
2 changes: 2 additions & 0 deletions src/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "ServerMainComponent.hpp"
#include "isobus/hardware_integration/can_hardware_interface.hpp"
#include "isobus/isobus/can_internal_control_function.hpp"
#include "ASCIILogFile.hpp"

//==============================================================================
class AgISOVirtualTerminalApplication : public juce::JUCEApplication
Expand Down Expand Up @@ -134,6 +135,7 @@ class AgISOVirtualTerminalApplication : public juce::JUCEApplication

private:
std::unique_ptr<MainWindow> mainWindow;
ASCIILogFile logFile;
};

//==============================================================================
Expand Down
13 changes: 5 additions & 8 deletions src/ServerMainComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -675,17 +675,14 @@ bool ServerMainComponent::perform(const InvocationInfo &info)

case static_cast<int>(CommandIDs::GenerateLogPackage):
{
diagnosticFileBuilder = std::make_unique<ZipFile::Builder>();
auto diagnosticFileBuilder = std::make_unique<ZipFile::Builder>();
bool anyFilesAdded = false;

if (File(File::getSpecialLocation(File::userApplicationDataDirectory).getFullPathName() + File::getSeparatorString() + "Open-Agriculture" + File::getSeparatorString() + "AgISOVirtualTerminalLog.txt").existsAsFile())
auto userDataFolder = File(File::getSpecialLocation(File::userApplicationDataDirectory).getFullPathName() + File::getSeparatorString() + "Open-Agriculture" + File::getSeparatorString());
auto userDataFiles = userDataFolder.findChildFiles(File::TypesOfFileToFind::findFiles, false, "*");
for (auto &file : userDataFiles)
{
diagnosticFileBuilder->addFile(File::getSpecialLocation(File::userApplicationDataDirectory).getFullPathName() + File::getSeparatorString() + "Open-Agriculture" + File::getSeparatorString() + "AgISOVirtualTerminalLog.txt", 9);
anyFilesAdded = true;
}
if (File(File::getSpecialLocation(File::userApplicationDataDirectory).getFullPathName() + File::getSeparatorString() + "Open-Agriculture" + File::getSeparatorString() + "vt_settings.xml").existsAsFile())
{
diagnosticFileBuilder->addFile(File::getSpecialLocation(File::userApplicationDataDirectory).getFullPathName() + File::getSeparatorString() + "Open-Agriculture" + File::getSeparatorString() + "vt_settings.xml", 9);
diagnosticFileBuilder->addFile(file, 9);
anyFilesAdded = true;
}

Expand Down

0 comments on commit 8428193

Please sign in to comment.