#include #include #include #include "Service.h" #include "thrawn_api.h" #include "spdlog/spdlog.h" #include "Cache.h" #include "LuaEngine.h" #include #include "Version.h" #include #include #include "mqtt++.h" std::vector lua_scripts_in_folder(const std::string& path_str) { std::vector scripts; std::filesystem::path scripts_folder(path_str); if (std::filesystem::exists(scripts_folder)) { for (const auto& file: std::filesystem::directory_iterator(scripts_folder)) { if (file.is_regular_file() && file.path().extension() == ".lua") { scripts.push_back(file.path().string()); } } }else{ throw std::invalid_argument("Folder '" + path_str + "' does not exist."); } return scripts; } int main(int argc, char* argv[]) { std::string services_path_str = "/etc/thrawn"; std::string mqttServerURI = "tcp://chimaera:1883"; mqttpp::LastWill last_will {"dev/thrawn/status", "0"}; std::string version_topic = "dev/thrawn/version"; std::string version_topic_value = std::to_string(THRAWN_MAJOR_VERSION) + "." + std::to_string(THRAWN_MINOR_VERSION) + "." + std::to_string(THRAWN_PATCH_VERSION); std::string lastWillConnected = "1"; /* * Parsing arguments * Show version or load path */ if (argc > 1) { if (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0) { std::cout << "Version: " << THRAWN_MAJOR_VERSION << "." << THRAWN_MINOR_VERSION << "." << THRAWN_PATCH_VERSION << std::endl; return 0; } services_path_str = argv[1]; } /* * MQTT */ spdlog::info("Starting MQTT connection to '{}' .", mqttServerURI); mqttpp::Client mqtt(mqttServerURI, last_will); if (! mqtt.connect()) { spdlog::error("Failed to establishe mqtt connection to ‘{}'", mqttServerURI); return 1; } mqtt.publish(last_will.topic, lastWillConnected); mqtt.publish(version_topic, version_topic_value); mqtt.subscribe("#", [&] (const char* topic, const std::string& msg) { LuaEngine::get_instance().cache.set_topic_value(topic, msg); for (auto& service : LuaEngine::get_instance().services) { for (const std::string& sub_topic : service.subscriptions) { if (sub_topic == topic) { service.on_update(TopicState(topic, msg)); } } } }); LuaEngine::get_instance().publish = [&](const TopicState& state) { mqtt.publish(state.topic, state.value); }; spdlog::info("Connection to MQTT server '{}' successfull.", mqttServerURI); try { for (const auto& script : lua_scripts_in_folder(services_path_str)) { LuaEngine::get_instance().create_service(script); } }catch(const std::exception& e) { spdlog::error(e.what()); return 1; } /* * LUA Engine */ spdlog::info("Starting Thrawn services on Chimaera."); LuaEngine::get_instance().load_services(); spdlog::info("{} service(s) loaded.", LuaEngine::get_instance().services.size()); LuaEngine::get_instance().start_services(); spdlog::info("All services loaded."); while (true) { using namespace std::chrono_literals; std::this_thread::sleep_for(100ms); } return 0; }