diff --git a/apps/fc/logger_service/BUILD b/apps/fc/logger_service/BUILD new file mode 100644 index 00000000..fed40625 --- /dev/null +++ b/apps/fc/logger_service/BUILD @@ -0,0 +1,9 @@ +cc_library( + name = "logger_data_type_lib", + srcs = ["data_type.cpp"], + hdrs = ["data_type.hpp"], + visibility = [ + "//apps/fc/logger_service:__subpackages__", + "//apps/fc/logger_service/tests:__subpackages__", + ], +) diff --git a/apps/fc/logger_service/data_type.cpp b/apps/fc/logger_service/data_type.cpp new file mode 100644 index 00000000..af3e1138 --- /dev/null +++ b/apps/fc/logger_service/data_type.cpp @@ -0,0 +1,93 @@ +/** + * @file data_type.cpp + * @author Krzysztof Kondracki (kondracki.christopher@gmail.com) + * @brief + * @version 0.1 + * @date 2026-04-13 + * + * @copyright Copyright (c) 2026 + * + */ +#include "apps/fc/logger_service/data_type.hpp" + +#include +#include + +namespace srp { +namespace logger { + +namespace { +constexpr auto kCsvHeader = + "TIMESTAMP;BOARD_TEMP1;BOARD_TEMP2;BOARD_TEMP3;BME_TEMP;BME_HUMIDITY;" + "BME_ALTITUDE;CPU_USAGE;MEM_USAGE;DISK_UTILIZATION"; +} + +std::string Data_t::get_header() { + return kCsvHeader; +} + +std::string Data_t::to_string(const std::string& timestamp) { + std::stringstream res; + res << std::fixed << std::setprecision(2); + res << timestamp << ";"; + + std::shared_lock lock(mutex_); + res << board_temp1_ << ";"; + res << board_temp2_ << ";"; + res << board_temp3_ << ";"; + res << bme_temp_ << ";"; + res << bme_humidity_ << ";"; + res << bme_altitude_ << ";"; + res << cpu_usage_ << ";"; + res << mem_usage_ << ";"; + res << disk_utilization_; + return res.str(); +} + +void Data_t::SetBoardTemp1(const tempType& temp) { + std::unique_lock lock(mutex_); + board_temp1_ = temp; +} + +void Data_t::SetBoardTemp2(const tempType& temp) { + std::unique_lock lock(mutex_); + board_temp2_ = temp; +} + +void Data_t::SetBoardTemp3(const tempType& temp) { + std::unique_lock lock(mutex_); + board_temp3_ = temp; +} + +void Data_t::SetBmeTemp(const bmeType& value) { + std::unique_lock lock(mutex_); + bme_temp_ = value; +} + +void Data_t::SetBmeHumidity(const bmeType& value) { + std::unique_lock lock(mutex_); + bme_humidity_ = value; +} + +void Data_t::SetBmeAltitude(const bmeType& value) { + std::unique_lock lock(mutex_); + bme_altitude_ = value; +} + +void Data_t::SetCpuUsage(const systemStatType& value) { + std::unique_lock lock(mutex_); + cpu_usage_ = value; +} + +void Data_t::SetMemUsage(const systemStatType& value) { + std::unique_lock lock(mutex_); + mem_usage_ = value; +} + +void Data_t::SetDiskUtilization(const systemStatType& value) { + std::unique_lock lock(mutex_); + disk_utilization_ = value; +} + +} // namespace logger +} // namespace srp diff --git a/apps/fc/logger_service/data_type.hpp b/apps/fc/logger_service/data_type.hpp new file mode 100644 index 00000000..6d2a89a9 --- /dev/null +++ b/apps/fc/logger_service/data_type.hpp @@ -0,0 +1,56 @@ +/** + * @file data_type.hpp + * @author Krzysztof Kondracki (kondracki.christopher@gmail.com) + * @brief + * @version 0.1 + * @date 2026-04-13 + * + * @copyright Copyright (c) 2026 + * + */ +#ifndef APPS_FC_LOGGER_SERVICE_DATA_TYPE_HPP_ +#define APPS_FC_LOGGER_SERVICE_DATA_TYPE_HPP_ + +#include +#include // NOLINT +#include +#include + +namespace srp { +namespace logger { + +class Data_t { + private: + using tempType = int16_t; + using bmeType = float; + using systemStatType = float; + + std::shared_mutex mutex_; + tempType board_temp1_{0}; + tempType board_temp2_{0}; + tempType board_temp3_{0}; + bmeType bme_temp_{0.0F}; + bmeType bme_humidity_{0.0F}; + bmeType bme_altitude_{0.0F}; + systemStatType cpu_usage_{0.0F}; + systemStatType mem_usage_{0.0F}; + systemStatType disk_utilization_{0.0F}; + + public: + std::string get_header(); + std::string to_string(const std::string& timestamp); + void SetBoardTemp1(const tempType& temp); + void SetBoardTemp2(const tempType& temp); + void SetBoardTemp3(const tempType& temp); + void SetBmeTemp(const bmeType& value); + void SetBmeHumidity(const bmeType& value); + void SetBmeAltitude(const bmeType& value); + void SetCpuUsage(const systemStatType& value); + void SetMemUsage(const systemStatType& value); + void SetDiskUtilization(const systemStatType& value); +}; + +} // namespace logger +} // namespace srp + +#endif // APPS_FC_LOGGER_SERVICE_DATA_TYPE_HPP_ diff --git a/apps/fc/logger_service/service/BUILD b/apps/fc/logger_service/service/BUILD new file mode 100644 index 00000000..fd51c16c --- /dev/null +++ b/apps/fc/logger_service/service/BUILD @@ -0,0 +1,23 @@ +cc_binary( + name = "logger_service_fc", + srcs = [ + "logger_builder.hpp", + "logger_did.hpp", + "logger_service.cpp", + "logger_service.hpp", + "main.cpp", + "service.hpp", + ], + visibility = ["//deployment:__subpackages__"], + deps = [ + "@srp_platform//ara/exec:adaptive_application_lib", + "//apps/fc/logger_service:logger_data_type_lib", + "//core/common:condition_lib", + "//core/csvdriver", + "//core/time:sys_time_change_lib", + "//core/timestamp:timestamp_controller", + "//deployment/apps/fc/logger_service:ara", + "//deployment/apps/fc/logger_service:someip_lib", + "@srp_platform//ara/diag:uds_lib", + ], +) diff --git a/apps/fc/logger_service/service/logger_builder.hpp b/apps/fc/logger_service/service/logger_builder.hpp new file mode 100644 index 00000000..97fcc275 --- /dev/null +++ b/apps/fc/logger_service/service/logger_builder.hpp @@ -0,0 +1,70 @@ +/** + * @file logger_builder.hpp + * @author Krzysztof Kondracki (kondracki.christopher@gmail.com) + * @brief + * @version 0.1 + * @date 2026-04-19 + * + * @copyright Copyright (c) 2026 + * + */ +#ifndef APPS_FC_LOGGER_SERVICE_SERVICE_LOGGER_BUILDER_HPP_ +#define APPS_FC_LOGGER_SERVICE_SERVICE_LOGGER_BUILDER_HPP_ + +#include +#include +#include +#include +#include + +#include "apps/fc/logger_service/service/logger_did.hpp" +#include "apps/fc/logger_service/service/service.hpp" + +namespace srp { +namespace logger { + +class Builder { + private: + std::unique_ptr logger_did_; + std::unique_ptr service_ipc_; + std::unique_ptr service_udp_; + std::function callback_; + + public: + explicit Builder(std::function callback_handler) + : callback_(std::move(callback_handler)) {} + + Builder& SetLoggerDID(const ara::core::InstanceSpecifier& specifier) { + logger_did_ = std::make_unique(specifier, callback_); + return *this; + } + + Builder& SetLoggerIPC(const std::string& instance) { + service_ipc_ = std::make_unique( + ara::core::InstanceSpecifier{instance}, + callback_); + return *this; + } + + Builder& SetLoggerUDP(const std::string& instance) { + service_udp_ = std::make_unique( + ara::core::InstanceSpecifier{instance}, + callback_); + return *this; + } + + struct Result { + std::unique_ptr logger_did; + std::unique_ptr service_ipc; + std::unique_ptr service_udp; + }; + + Result Build() { + return {std::move(logger_did_), std::move(service_ipc_), std::move(service_udp_)}; + } +}; + +} // namespace logger +} // namespace srp + +#endif // APPS_FC_LOGGER_SERVICE_SERVICE_LOGGER_BUILDER_HPP_ diff --git a/apps/fc/logger_service/service/logger_did.hpp b/apps/fc/logger_service/service/logger_did.hpp new file mode 100644 index 00000000..8c09471d --- /dev/null +++ b/apps/fc/logger_service/service/logger_did.hpp @@ -0,0 +1,54 @@ +/** + * @file logger_did.hpp + * @author Krzysztof Kondracki (kondracki.christopher@gmail.com) + * @brief + * @version 0.1 + * @date 2026-04-19 + * + * @copyright Copyright (c) 2026 + * + */ +#ifndef APPS_FC_LOGGER_SERVICE_SERVICE_LOGGER_DID_HPP_ +#define APPS_FC_LOGGER_SERVICE_SERVICE_LOGGER_DID_HPP_ + +#include +#include +#include +#include + +#include "ara/diag/generic_data_identifier.h" +#include "ara/diag/uds_error_domain.h" + +namespace srp { +namespace logger { + +using DidSaveThreadHandler = std::function; + +class FileLoggerDID : public ara::diag::GenericDiD { + private: + DidSaveThreadHandler handler_; + + ara::core::Result Read() noexcept override { + return ara::diag::MakeErrorCode( + ara::diag::UdsDiagErrc::kSubFunctionNotSupported); + } + + ara::core::Result Write(const std::vector& payload) noexcept override { + if (payload.size() != 1U) { + return ara::diag::MakeErrorCode( + ara::diag::UdsDiagErrc::kInvalidMessageLengthFormat); + } + + handler_(payload[0]); + return {}; + } + + public: + FileLoggerDID(const ara::core::InstanceSpecifier& instance, DidSaveThreadHandler handler) + : ara::diag::GenericDiD{instance}, handler_(std::move(handler)) {} +}; + +} // namespace logger +} // namespace srp + +#endif // APPS_FC_LOGGER_SERVICE_SERVICE_LOGGER_DID_HPP_ diff --git a/apps/fc/logger_service/service/logger_service.cpp b/apps/fc/logger_service/service/logger_service.cpp new file mode 100644 index 00000000..1658f613 --- /dev/null +++ b/apps/fc/logger_service/service/logger_service.cpp @@ -0,0 +1,192 @@ +/** + * @file logger_service.cpp + * @author Krzysztof Kondracki (kondracki.christopher@gmail.com) + * @brief + * @version 0.1 + * @date 2026-04-13 + * + * @copyright Copyright (c) 2026 + * + */ +#include "apps/fc/logger_service/service/logger_service.hpp" + +#include +#include + +#include "ara/log/log.h" +#include "apps/fc/logger_service/service/logger_builder.hpp" +#include "core/common/condition.h" +#include "core/csvdriver/csvdriver.h" +#include "core/time/sys_time.hpp" + +namespace srp { +namespace logger { + +namespace { + static constexpr auto kLoggerFilename = "_fc_log.csv"; + static constexpr auto kLoggerFilenamePrefix = "/home/root/"; + static constexpr std::uint16_t kSaveIntervalMs = 5000; + static constexpr auto kEnvServicePathName = "srp/apps/FcFileLoggerApp/envServiceFc_ipc"; + static constexpr auto kUdpServicePathName = "srp/apps/FcFileLoggerApp/logService_udp"; + static constexpr auto kIpcServicePathName = "srp/apps/FcFileLoggerApp/logService_ipc"; + static constexpr auto kSysStatServicePathName = "srp/apps/FcFileLoggerApp/FcSysStatService_ipc"; + static constexpr auto kFileDidPathName = "/srp/apps/FcFileLoggerApp/logger_did"; + static constexpr std::uint8_t kLogsOn = 1; + static constexpr std::uint8_t kLogsOff = 0; +} // namespace + +LoggerService::LoggerService() + : env_service_proxy_{ara::core::InstanceSpecifier{kEnvServicePathName}}, + stat_service_proxy_{ara::core::InstanceSpecifier{kSysStatServicePathName}}, + env_service_handler_{nullptr}, + stat_service_handler_{nullptr}, + did_instance_{kFileDidPathName}, + timestamp_{std::make_shared()}, + save_thread_{nullptr} { + Builder builder([this](std::uint8_t status) { StartFuncHandler(status); }); + auto result = builder.SetLoggerDID(did_instance_) + .SetLoggerIPC(kIpcServicePathName) + .SetLoggerUDP(kUdpServicePathName) + .Build(); + logger_did_ = std::move(result.logger_did); + service_ipc_ = std::move(result.service_ipc); + service_udp_ = std::move(result.service_udp); + + if (!timestamp_->Init()) { + ara::log::LogError() << "LoggerService: failed to initialize timestamp controller"; + } +} + +LoggerService::~LoggerService() { + StartFuncHandler(0); +} + +int LoggerService::Initialize( + const std::map /*parms*/) { + logger_did_->Offer(); + service_ipc_->StartOffer(); + service_udp_->StartOffer(); + SomeIpInit(); + return 0; +} + +int LoggerService::Run(const std::stop_token& token) { + while (!token.stop_requested()) { + service_ipc_->LoggingState.Update(save_state_.load()); + service_udp_->LoggingState.Update(save_state_.load()); + core::condition::wait_for(std::chrono::milliseconds(1000), token); + } + + StartFuncHandler(0); + service_ipc_->StopOffer(); + service_udp_->StopOffer(); + logger_did_->StopOffer(); + return 0; +} + +void LoggerService::StartFuncHandler(std::uint8_t status) { + if (status == kLogsOn && !save_thread_) { + save_thread_ = std::make_shared( + [this](std::stop_token token) { SaveLoop(token); }); + return; + } + + if (status == kLogsOff && save_thread_) { + save_thread_->request_stop(); + save_thread_->join(); + save_thread_.reset(); + } +} + +void LoggerService::SaveLoop(const std::stop_token& token) { + csv::CSVDriver writer; + writer.Init(std::make_unique()); + + const auto prefix = core::time::TimeChanger::ReadSystemTimeAsString(); + const std::string filename = kLoggerFilenamePrefix + prefix.value_or("") + kLoggerFilename; + if (writer.Open(filename, data_.get_header()) != 0) { + ara::log::LogError() << "LoggerService::SaveLoop: failed to open file " << filename; + return; + } + + save_state_.store(kLogsOn); + while (!token.stop_requested()) { + const auto start = std::chrono::high_resolution_clock::now(); + auto ts = timestamp_->GetNewTimeStamp(); + if (ts.has_value() && writer.WriteLine(data_.to_string(std::to_string(ts.value()))) != 0) { + ara::log::LogWarn() << "LoggerService::SaveLoop: failed to write line"; + } + + const auto now = std::chrono::high_resolution_clock::now(); + const auto elapsed = std::chrono::duration_cast(now - start); + if (elapsed < std::chrono::milliseconds(kSaveIntervalMs)) { + core::condition::wait_for(std::chrono::milliseconds(kSaveIntervalMs) - elapsed, token); + } + } + + writer.Close(); + save_state_.store(kLogsOff); +} + +void LoggerService::SomeIpInit() { + stat_service_proxy_.StartFindService([this](auto handler) { + stat_service_handler_ = handler; + stat_service_handler_->NewSystemUsage.Subscribe(1, [this](std::uint8_t /*status*/) { + stat_service_handler_->NewSystemUsage.SetReceiveHandler([this]() { + auto res = stat_service_handler_->NewSystemUsage.GetNewSamples(); + if (!res.HasValue()) { + return; + } + data_.SetCpuUsage(res.Value().cpu_usage); + data_.SetMemUsage(res.Value().mem_usage); + data_.SetDiskUtilization(res.Value().disk_utilization); + }); + }); + }); + + env_service_proxy_.StartFindService([this](auto handler) { + env_service_handler_ = handler; + + env_service_handler_->newBoardTempEvent_1.Subscribe(1, [this](std::uint8_t /*status*/) { + env_service_handler_->newBoardTempEvent_1.SetReceiveHandler([this]() { + auto res = env_service_handler_->newBoardTempEvent_1.GetNewSamples(); + if (res.HasValue()) { + data_.SetBoardTemp1(res.Value()); + } + }); + }); + + env_service_handler_->newBoardTempEvent_2.Subscribe(1, [this](std::uint8_t /*status*/) { + env_service_handler_->newBoardTempEvent_2.SetReceiveHandler([this]() { + auto res = env_service_handler_->newBoardTempEvent_2.GetNewSamples(); + if (res.HasValue()) { + data_.SetBoardTemp2(res.Value()); + } + }); + }); + + env_service_handler_->newBoardTempEvent_3.Subscribe(1, [this](std::uint8_t /*status*/) { + env_service_handler_->newBoardTempEvent_3.SetReceiveHandler([this]() { + auto res = env_service_handler_->newBoardTempEvent_3.GetNewSamples(); + if (res.HasValue()) { + data_.SetBoardTemp3(res.Value()); + } + }); + }); + + env_service_handler_->newBME280Event.Subscribe(1, [this](std::uint8_t /*status*/) { + env_service_handler_->newBME280Event.SetReceiveHandler([this]() { + auto res = env_service_handler_->newBME280Event.GetNewSamples(); + if (!res.HasValue()) { + return; + } + data_.SetBmeTemp(res.Value().temperature); + data_.SetBmeHumidity(res.Value().humidity); + data_.SetBmeAltitude(res.Value().altitude); + }); + }); + }); +} + +} // namespace logger +} // namespace srp diff --git a/apps/fc/logger_service/service/logger_service.hpp b/apps/fc/logger_service/service/logger_service.hpp new file mode 100644 index 00000000..baef3a54 --- /dev/null +++ b/apps/fc/logger_service/service/logger_service.hpp @@ -0,0 +1,64 @@ +/** + * @file logger_service.hpp + * @author Krzysztof Kondracki (kondracki.christopher@gmail.com) + * @brief + * @version 0.1 + * @date 2026-04-13 + * + * @copyright Copyright (c) 2026 + * + */ +#ifndef APPS_FC_LOGGER_SERVICE_SERVICE_LOGGER_SERVICE_HPP_ +#define APPS_FC_LOGGER_SERVICE_SERVICE_LOGGER_SERVICE_HPP_ + +#include +#include +#include +#include + +#include "apps/fc/logger_service/data_type.hpp" +#include "apps/fc/logger_service/service/logger_did.hpp" +#include "apps/fc/logger_service/service/service.hpp" +#include "ara/exec/adaptive_application.h" +#include "core/timestamp/timestamp_driver.hpp" +#include "srp/apps/FcSysStatService/FcSysStatServiceHandler.h" +#include "srp/env/EnvAppFc/EnvAppFcHandler.h" + +namespace srp { +namespace logger { + +class LoggerService final : public ara::exec::AdaptiveApplication { + private: + env::EnvAppFcProxy env_service_proxy_; + apps::FcSysStatServiceProxy stat_service_proxy_; + std::shared_ptr env_service_handler_; + std::shared_ptr stat_service_handler_; + Data_t data_; + std::unique_ptr logger_did_; + const ara::core::InstanceSpecifier did_instance_; + std::shared_ptr timestamp_; + + std::atomic save_state_{0}; + std::shared_ptr save_thread_; + + std::unique_ptr service_ipc_; + std::unique_ptr service_udp_; + + void SaveLoop(const std::stop_token& token); + void StartFuncHandler(std::uint8_t status); + void SomeIpInit(); + + protected: + int Run(const std::stop_token& token) override; + int Initialize( + const std::map parms) override; + + public: + ~LoggerService() override; + LoggerService(); +}; + +} // namespace logger +} // namespace srp + +#endif // APPS_FC_LOGGER_SERVICE_SERVICE_LOGGER_SERVICE_HPP_ diff --git a/apps/fc/logger_service/service/main.cpp b/apps/fc/logger_service/service/main.cpp new file mode 100644 index 00000000..ed166aac --- /dev/null +++ b/apps/fc/logger_service/service/main.cpp @@ -0,0 +1,16 @@ +/** + * @file main.cpp + * @author Krzysztof Kondracki (kondracki.christopher@gmail.com) + * @brief + * @version 0.1 + * @date 2026-04-13 + * + * @copyright Copyright (c) 2026 + * + */ +#include "apps/fc/logger_service/service/logger_service.hpp" +#include "ara/exec/adaptive_lifecycle.h" + +int main(int argc, char const* argv[]) { + return ara::exec::RunAdaptiveLifecycle(argc, argv); +} diff --git a/apps/fc/logger_service/service/service.hpp b/apps/fc/logger_service/service/service.hpp new file mode 100644 index 00000000..df961abf --- /dev/null +++ b/apps/fc/logger_service/service/service.hpp @@ -0,0 +1,50 @@ +/** + * @file service.hpp + * @author Krzysztof Kondracki (kondracki.christopher@gmail.com) + * @brief + * @version 0.1 + * @date 2026-04-13 + * + * @copyright Copyright (c) 2026 + * + */ +#ifndef APPS_FC_LOGGER_SERVICE_SERVICE_SERVICE_HPP_ +#define APPS_FC_LOGGER_SERVICE_SERVICE_SERVICE_HPP_ + +#include + +#include "srp/apps/FcFileLoggerAppSkeleton.h" + +using SaveThreadHandler = std::function; + +namespace srp { +namespace apps { + +class MyFcFileLoggerAppSkeleton : public FcFileLoggerAppSkeleton { + private: + SaveThreadHandler handler_; + + public: + MyFcFileLoggerAppSkeleton( + const ara::core::InstanceSpecifier& instance, + SaveThreadHandler handler) + : FcFileLoggerAppSkeleton{instance}, handler_(handler) {} + + ~MyFcFileLoggerAppSkeleton() override = default; + + protected: + ara::core::Result Start() override { + handler_(1); + return ara::core::Result(true); + } + + ara::core::Result Stop() override { + handler_(0); + return ara::core::Result(true); + } +}; + +} // namespace apps +} // namespace srp + +#endif // APPS_FC_LOGGER_SERVICE_SERVICE_SERVICE_HPP_ diff --git a/apps/fc/logger_service/tests/BUILD b/apps/fc/logger_service/tests/BUILD new file mode 100644 index 00000000..9bdb9d70 --- /dev/null +++ b/apps/fc/logger_service/tests/BUILD @@ -0,0 +1,9 @@ +cc_test( + name = "data_type_test", + srcs = ["data_type_test.cc"], + deps = [ + "//apps/fc/logger_service:logger_data_type_lib", + "@com_google_googletest//:gtest_main", + ], + size = "small", +) diff --git a/apps/fc/logger_service/tests/data_type_test.cc b/apps/fc/logger_service/tests/data_type_test.cc new file mode 100644 index 00000000..3f4337dd --- /dev/null +++ b/apps/fc/logger_service/tests/data_type_test.cc @@ -0,0 +1,76 @@ +/** + * @file data_type_test.cc + * @author Krzysztof Kondracki (kondracki.christopher@gmail.com) + * @brief + * @version 0.1 + * @date 2026-04-13 + * + * @copyright Copyright (c) 2026 + * + */ +#include + +#include +#include +#include + +#include "apps/fc/logger_service/data_type.hpp" + +namespace { +std::size_t CountSemicolons(const std::string& value) { + return static_cast(std::count(value.begin(), value.end(), ';')); +} +} // namespace + +TEST(DataToStringTest, ReturnsExpectedHeader) { + srp::logger::Data_t data; + EXPECT_EQ( + data.get_header(), + "TIMESTAMP;BOARD_TEMP1;BOARD_TEMP2;BOARD_TEMP3;BME_TEMP;BME_HUMIDITY;" + "BME_ALTITUDE;CPU_USAGE;MEM_USAGE;DISK_UTILIZATION"); +} + +TEST(DataToStringTest, UsesZeroDefaultsWhenNoSamplesArrived) { + srp::logger::Data_t data; + EXPECT_EQ(data.to_string("1000"), "1000;0;0;0;0.00;0.00;0.00;0.00;0.00;0.00"); +} + +TEST(DataToStringTest, FormatsExpectedCsvLineWhenAllFieldsAreSet) { + srp::logger::Data_t data; + data.SetBoardTemp1(10); + data.SetBoardTemp2(11); + data.SetBoardTemp3(12); + data.SetBmeTemp(20.5F); + data.SetBmeHumidity(30.0F); + data.SetBmeAltitude(100.25F); + data.SetCpuUsage(40.0F); + data.SetMemUsage(50.0F); + data.SetDiskUtilization(60.0F); + + EXPECT_EQ( + data.to_string("123"), + "123;10;11;12;20.50;30.00;100.25;40.00;50.00;60.00"); +} + +TEST(DataToStringTest, UsesLatestValueAfterOverwrite) { + srp::logger::Data_t data; + data.SetBmeHumidity(1.0F); + data.SetBmeHumidity(55.5F); + + EXPECT_EQ(data.to_string("x"), "x;0;0;0;0.00;55.50;0.00;0.00;0.00;0.00"); +} + +TEST(DataToStringTest, SupportsInt16BoundsForBoardTemperature) { + srp::logger::Data_t data; + data.SetBoardTemp1(std::numeric_limits::min()); + data.SetBoardTemp2(std::numeric_limits::max()); + + EXPECT_EQ(data.to_string("b"), "b;-32768;32767;0;0.00;0.00;0.00;0.00;0.00;0.00"); +} + +TEST(DataToStringTest, PreservesCsvColumnCountForSimpleTimestamp) { + srp::logger::Data_t data; + const std::string line = data.to_string("ts"); + + EXPECT_EQ(CountSemicolons(line), 9U); +} diff --git a/deployment/apps/fc/env_service/BUILD b/deployment/apps/fc/env_service/BUILD index c410fdf9..6155d5cf 100644 --- a/deployment/apps/fc/env_service/BUILD +++ b/deployment/apps/fc/env_service/BUILD @@ -22,7 +22,9 @@ filegroup( "//apps/fc:__subpackages__", "//apps/fc/env_service:__pkg__", "//deployment/apps/logger_service:__subpackages__", - "//deployment/apps/fc/radio_app:__subpackages__",], + "//deployment/apps/fc/radio_app:__subpackages__", + "//deployment/apps/fc/logger_service:__subpackages__", + ], ) adaptive_application( diff --git a/deployment/apps/fc/logger_service/BUILD b/deployment/apps/fc/logger_service/BUILD new file mode 100644 index 00000000..3286aeb7 --- /dev/null +++ b/deployment/apps/fc/logger_service/BUILD @@ -0,0 +1,32 @@ +load("@srp_platform//tools/model_generator/ara:adaptive_application.bzl", "adaptive_application", "ara_runtime_lib", "ara_someip_lib") + +ara_runtime_lib( + name = "ara", + model_src = ["//deployment/apps/fc/logger_service:instance"], + visibility = ["//apps/fc/logger_service:__subpackages__"], +) + +ara_someip_lib( + name = "someip_lib", + model_src = ["//deployment/apps/fc/logger_service:instance"], + visibility = ["//apps/fc/logger_service:__subpackages__"], +) + +filegroup( + name = "instance", + srcs = [ + "app_config.json", + "//deployment/system_definition/someip/fc/logger_service:service_someipy", + "//deployment/apps/fc/env_service:instance", + "//deployment/apps/fc/system_stat_service:instance", + "//deployment/system_definition/diag/jobs/file_logger:file_logger_job", + ], + visibility = ["//visibility:public"], +) + +adaptive_application( + name = "FcFileLoggerApp", + bin = "//apps/fc/logger_service/service:logger_service_fc", + model_src = ["//deployment/apps/fc/logger_service:instance"], + visibility = ["//deployment/cpu/fc:__subpackages__"], +) diff --git a/deployment/apps/fc/logger_service/app_config.json b/deployment/apps/fc/logger_service/app_config.json new file mode 100644 index 00000000..e100a41f --- /dev/null +++ b/deployment/apps/fc/logger_service/app_config.json @@ -0,0 +1,72 @@ +{ + "include": [ + "deployment/system_definition/someip/fc/logger_service/service.json", + "deployment/system_definition/someip/fc/env_service/service.json", + "deployment/system_definition/someip/fc/sys_stat_service/service.json" + ], + "package": "srp.apps", + "adaptive_application": { + "FcFileLoggerApp": { + "app": { + "functional_groups": [ + "Running", + "SafetyMode" + ], + "parms": "", + "logger": { + "app_id": "FCLG", + "app_des": "FC logger service", + "log_level": "kInfo", + "log_mode": "kRemote", + "ctx": [ + { + "ctx_id": "ara", + "log_level": "kWarn", + "ctx_des": "Default ctx for ara" + }, + { + "ctx_id": "acom", + "log_level": "kWarn", + "ctx_des": "Default ctx for ara::com" + }, + { + "ctx_id": "adiag", + "log_level": "kWarn", + "ctx_des": "Default ctx for ara::diag" + }, + { + "ctx_id": "exec", + "log_level": "kWarn", + "ctx_des": "Default ctx for ara::exec" + } + ] + } + }, + "provide": [ + { + "name": "FcFileLoggerApp as logService_udp", + "on": "udp", + "port": "10001", + "instance": 1 + }, + { + "name": "FcFileLoggerApp as logService_ipc", + "on": "ipc", + "instance": 2 + } + ], + "require": [ + { + "name": "srp.env.EnvAppFc as envServiceFc_ipc", + "on": "ipc", + "instance": 2 + }, + { + "name": "FcSysStatService as FcSysStatService_ipc", + "on": "ipc", + "instance": 2 + } + ] + } + } +} diff --git a/deployment/cpu/fc/BUILD b/deployment/cpu/fc/BUILD index 9fa8d8c6..ba830d4d 100644 --- a/deployment/cpu/fc/BUILD +++ b/deployment/cpu/fc/BUILD @@ -22,11 +22,12 @@ cpu_def( # "//deployment/example_adaptive/ExampleApp", # "//deployment/apps/fc/env_service:EnvAppFc", - # "//deployment/apps/fc/gps_app:GPSApp", - # "//deployment/apps/fc/recovery_service:RecoveryService", + "//deployment/apps/fc/gps_app:GPSApp", + "//deployment/apps/fc/recovery_service:RecoveryService", "//deployment/apps/fc/radio_app:RadioApp", "//deployment/apps/fc/main_app:MainApp", "//deployment/apps/fc/system_stat_service:FcSysStatService", + "//deployment/apps/fc/logger_service:FcFileLoggerApp", ], ) diff --git a/deployment/system_definition b/deployment/system_definition index d2a1099d..4b8bd5e4 160000 --- a/deployment/system_definition +++ b/deployment/system_definition @@ -1 +1 @@ -Subproject commit d2a1099dafe8bd185ff9fae7b1d454abfeee1b25 +Subproject commit 4b8bd5e42e0d4e848742c7ea44d0806fc360dcd0