diff --git a/include/settings.hpp b/include/settings.hpp index f1e5b13..2bcbf36 100644 --- a/include/settings.hpp +++ b/include/settings.hpp @@ -77,6 +77,48 @@ class Settings */ bool set_aog_heartbeat_enabled(bool enabled, bool save = true); + /** + * @brief Get the configured TC version + * @return The configured version (0-4, default 3) + */ + std::uint8_t get_tc_version() const; + + /** + * @brief Set the TC version + * @param version The version to set (0=DIS, 1=FDIS.1, 2=FirstEdition, 3=SecondEditionDraft, 4=SecondPublishedEdition) + * @param save Whether or not to save the settings to file + * @return True if the version was set successfully, false otherwise + */ + bool set_tc_version(std::uint8_t version, bool save = true); + + /** + * @brief Get the configured language code + * @return The language code (default "en") + */ + std::string get_language_code() const; + + /** + * @brief Set the language code + * @param code The language code + * @param save Whether or not to save the settings to file + * @return True if the setting was set successfully, false otherwise + */ + bool set_language_code(std::string code, bool save = true); + + /** + * @brief Get the configured country code + * @return The country code (default "US") + */ + std::string get_country_code() const; + + /** + * @brief Set the country code + * @param code The country code + * @param save Whether or not to save the settings to file + * @return True if the setting was set successfully, false otherwise + */ + bool set_country_code(std::string code, bool save = true); + /** * @brief Get the absolute path to the settings file * @param filename The filename to get the path for @@ -88,7 +130,13 @@ class Settings constexpr static std::array DEFAULT_SUBNET = { 192, 168, 5 }; constexpr static bool DEFAULT_TECU_ENABLED = true; constexpr static bool DEFAULT_AOG_HEARTBEAT_ENABLED = true; + constexpr static std::uint8_t DEFAULT_TC_VERSION = 3; ///< SecondEditionDraft (V3 default for maximum implement compatibility) + static const std::string DEFAULT_LANGUAGE_CODE; + static const std::string DEFAULT_COUNTRY_CODE; std::array configuredSubnet = DEFAULT_SUBNET; bool tecuEnabled = DEFAULT_TECU_ENABLED; bool aogHeartbeatEnabled = DEFAULT_AOG_HEARTBEAT_ENABLED; + std::uint8_t tcVersion = DEFAULT_TC_VERSION; + std::string languageCode = DEFAULT_LANGUAGE_CODE; + std::string countryCode = DEFAULT_COUNTRY_CODE; }; diff --git a/include/task_controller.hpp b/include/task_controller.hpp index 9546457..d1ca919 100644 --- a/include/task_controller.hpp +++ b/include/task_controller.hpp @@ -76,7 +76,8 @@ class ClientState class MyTCServer : public isobus::TaskControllerServer { public: - MyTCServer(std::shared_ptr internalControlFunction); + MyTCServer(std::shared_ptr internalControlFunction, + isobus::TaskControllerServer::TaskControllerVersion version = isobus::TaskControllerServer::TaskControllerVersion::SecondEditionDraft); bool activate_object_pool(std::shared_ptr partnerCF, ObjectPoolActivationError &, ObjectPoolErrorCodes &, std::uint16_t &, std::uint16_t &) override; bool change_designator(std::shared_ptr, std::uint16_t, const std::vector &) override; bool deactivate_object_pool(std::shared_ptr partnerCF) override; diff --git a/src/app.cpp b/src/app.cpp index 3425304..18fb8aa 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -13,6 +13,7 @@ #include "isobus/isobus/can_network_manager.hpp" #include "isobus/isobus/isobus_preferred_addresses.hpp" #include "isobus/isobus/isobus_standard_data_description_indices.hpp" +#include "isobus/isobus/isobus_task_controller_server.hpp" #include "isobus/utility/system_timing.hpp" #include "task_controller.hpp" @@ -174,10 +175,32 @@ bool Application::initialize() } } - tcServer = std::make_shared(tcCF); + // Map settings version to TaskControllerVersion enum + isobus::TaskControllerServer::TaskControllerVersion tcVersionEnum; + switch (settings->get_tc_version()) + { + case 0: + tcVersionEnum = isobus::TaskControllerServer::TaskControllerVersion::DraftInternationalStandard; + break; + case 1: + tcVersionEnum = isobus::TaskControllerServer::TaskControllerVersion::FinalDraftInternationalStandardFirstEdition; + break; + case 2: + tcVersionEnum = isobus::TaskControllerServer::TaskControllerVersion::FirstPublishedEdition; + break; + case 3: + tcVersionEnum = isobus::TaskControllerServer::TaskControllerVersion::SecondEditionDraft; + break; + case 4: + default: + tcVersionEnum = isobus::TaskControllerServer::TaskControllerVersion::SecondPublishedEdition; + break; + } + + tcServer = std::make_shared(tcCF, tcVersionEnum); auto &languageInterface = tcServer->get_language_command_interface(); - languageInterface.set_language_code("en"); // This is the default, but you can change it if you want - languageInterface.set_country_code("US"); // This is the default, but you can change it if you want + languageInterface.set_language_code(settings->get_language_code()); + languageInterface.set_country_code(settings->get_country_code()); tcServer->initialize(); tcServer->set_task_totals_active(true); // TODO: make this dynamic based on status in AOG diff --git a/src/settings.cpp b/src/settings.cpp index a601b9f..608175c 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -21,6 +21,9 @@ using json = nlohmann::json; +const std::string Settings::DEFAULT_LANGUAGE_CODE = "en"; +const std::string Settings::DEFAULT_COUNTRY_CODE = "US"; + bool Settings::load() { std::ifstream file(get_filename_path("settings.json")); @@ -84,6 +87,66 @@ bool Settings::load() aogHeartbeatEnabled = DEFAULT_AOG_HEARTBEAT_ENABLED; // Key not found, use default } + if (data.contains("tcVersion")) + { + try + { + int version = data["tcVersion"].get(); + if (version >= 0 && version <= 4) + { + tcVersion = static_cast(version); + } + else + { + std::cout << "[" << get_timestamp() << "] Invalid tcVersion " << version << ", using default " << static_cast(DEFAULT_TC_VERSION) << std::endl; + tcVersion = DEFAULT_TC_VERSION; + } + } + catch (const nlohmann::json::exception &e) + { + std::cout << "[" << get_timestamp() << "] Error parsing 'tcVersion': " << e.what() << std::endl; + tcVersion = DEFAULT_TC_VERSION; + } + } + else + { + tcVersion = DEFAULT_TC_VERSION; // Key not found, use default + } + + if (data.contains("languageCode")) + { + try + { + languageCode = data["languageCode"].get(); + } + catch (const nlohmann::json::exception &e) + { + std::cout << "[" << get_timestamp() << "] Error parsing 'languageCode': " << e.what() << std::endl; + languageCode = DEFAULT_LANGUAGE_CODE; + } + } + else + { + languageCode = DEFAULT_LANGUAGE_CODE; + } + + if (data.contains("countryCode")) + { + try + { + countryCode = data["countryCode"].get(); + } + catch (const nlohmann::json::exception &e) + { + std::cout << "[" << get_timestamp() << "] Error parsing 'countryCode': " << e.what() << std::endl; + countryCode = DEFAULT_COUNTRY_CODE; + } + } + else + { + countryCode = DEFAULT_COUNTRY_CODE; + } + return true; } @@ -93,6 +156,9 @@ bool Settings::save() const data["subnet"] = configuredSubnet; data["tecuEnabled"] = tecuEnabled; data["aogHeartbeatEnabled"] = aogHeartbeatEnabled; + data["tcVersion"] = tcVersion; + data["languageCode"] = languageCode; + data["countryCode"] = countryCode; std::ofstream file(get_filename_path("settings.json")); if (!file.is_open()) @@ -154,6 +220,59 @@ bool Settings::set_aog_heartbeat_enabled(bool enabled, bool save) return true; } +std::uint8_t Settings::get_tc_version() const +{ + return tcVersion; +} + +bool Settings::set_tc_version(std::uint8_t version, bool save) +{ + if (version > 4) + { + std::cout << "[" << get_timestamp() << "] Invalid TC version " << static_cast(version) << ", using default " << static_cast(DEFAULT_TC_VERSION) << std::endl; + tcVersion = DEFAULT_TC_VERSION; + } + else + { + tcVersion = version; + } + if (save) + { + return this->save(); + } + return true; +} + +std::string Settings::get_language_code() const +{ + return languageCode; +} + +bool Settings::set_language_code(std::string code, bool save) +{ + languageCode = code; + if (save) + { + return this->save(); + } + return true; +} + +std::string Settings::get_country_code() const +{ + return countryCode; +} + +bool Settings::set_country_code(std::string code, bool save) +{ + countryCode = code; + if (save) + { + return this->save(); + } + return true; +} + namespace { std::filesystem::path get_base_config_dir() diff --git a/src/task_controller.cpp b/src/task_controller.cpp index 6155074..ce6a2b0 100644 --- a/src/task_controller.cpp +++ b/src/task_controller.cpp @@ -244,14 +244,15 @@ bool ClientState::try_get_element_work_state(std::uint16_t elementNumber, bool & return false; } -MyTCServer::MyTCServer(std::shared_ptr internalControlFunction) : +MyTCServer::MyTCServer(std::shared_ptr internalControlFunction, + isobus::TaskControllerServer::TaskControllerVersion version) : TaskControllerServer(internalControlFunction, 1, // AOG limits to 1 boom 64, // AOG limits to 16 sections of unique width but can be 64 by using zones 64, // 64 channels for position based control isobus::TaskControllerOptions() .with_implement_section_control(), // We support section control - TaskControllerVersion::SecondEditionDraft) + version) { }