diff --git a/cmake/ev-project-bootstrap.cmake b/cmake/ev-project-bootstrap.cmake index 2a18d9456..5f4e8a94e 100644 --- a/cmake/ev-project-bootstrap.cmake +++ b/cmake/ev-project-bootstrap.cmake @@ -5,7 +5,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/config-run-script.cmake) include(${CMAKE_CURRENT_LIST_DIR}/config-run-nodered-script.cmake) # dependencies -require_ev_cli_version("0.0.17") +require_ev_cli_version("0.0.18") # source generate scripts / setup include(${CMAKE_CURRENT_LIST_DIR}/everest-generate.cmake) diff --git a/config/config-sil-dc.yaml b/config/config-sil-dc.yaml index 8912f5b50..0ec8114cf 100644 --- a/config/config-sil-dc.yaml +++ b/config/config-sil-dc.yaml @@ -20,7 +20,7 @@ active_modules: evse_id_din: 49A80737A45678 session_logging: true session_logging_xml: false - session_logging_path: /tmp + session_logging_path: /tmp/everest-logs charge_mode: DC connections: bsp: diff --git a/config/config-sil-four-evse.yaml b/config/config-sil-four-evse.yaml index 2ab92a421..52c2457cf 100644 --- a/config/config-sil-four-evse.yaml +++ b/config/config-sil-four-evse.yaml @@ -21,7 +21,7 @@ active_modules: evse_id: DE*PNX*E12345*1 session_logging: true session_logging_xml: false - session_logging_path: /tmp + session_logging_path: /tmp/everest-logs ac_hlc_enabled: false ac_hlc_use_5percent: false ac_enforce_hlc: false diff --git a/config/config-sil-ocpp.yaml b/config/config-sil-ocpp.yaml index eb1d7c962..fdb8ea3dd 100644 --- a/config/config-sil-ocpp.yaml +++ b/config/config-sil-ocpp.yaml @@ -23,7 +23,7 @@ active_modules: evse_id: "1" session_logging: true session_logging_xml: false - session_logging_path: /tmp + session_logging_path: /tmp/everest-logs ac_hlc_enabled: false ac_hlc_use_5percent: false ac_enforce_hlc: false diff --git a/config/config-sil-two-evse-dc.yaml b/config/config-sil-two-evse-dc.yaml index 23990c42a..326ce305d 100644 --- a/config/config-sil-two-evse-dc.yaml +++ b/config/config-sil-two-evse-dc.yaml @@ -23,7 +23,7 @@ active_modules: evse_id_din: 49A80737A45678 session_logging: true session_logging_xml: false - session_logging_path: /tmp + session_logging_path: /tmp/everest-logs charge_mode: DC connections: bsp: diff --git a/config/config-sil-two-evse.yaml b/config/config-sil-two-evse.yaml index ede4f9209..c4f4bd07a 100644 --- a/config/config-sil-two-evse.yaml +++ b/config/config-sil-two-evse.yaml @@ -21,7 +21,7 @@ active_modules: evse_id: DE*PNX*E12345*1 session_logging: true session_logging_xml: false - session_logging_path: /tmp + session_logging_path: /tmp/everest-logs ac_hlc_enabled: true ac_hlc_use_5percent: false ac_enforce_hlc: false diff --git a/config/config-sil.yaml b/config/config-sil.yaml index 71b804ac0..58f9e337d 100644 --- a/config/config-sil.yaml +++ b/config/config-sil.yaml @@ -1,9 +1,11 @@ +settings: + telemetry_enabled: true active_modules: api: connections: evse_manager: - implementation_id: evse - module_id: evse_manager + module_id: connector_1 module: API auth: config_module: @@ -13,7 +15,7 @@ active_modules: connections: evse_manager: - implementation_id: evse - module_id: evse_manager + module_id: connector_1 token_provider: - implementation_id: main module_id: token_provider @@ -33,7 +35,7 @@ active_modules: module_id: iso15118_car simulation_control: - implementation_id: yeti_simulation_control - module_id: yeti_driver + module_id: connector_1_powerpath slac: - implementation_id: ev module_id: slac @@ -44,7 +46,7 @@ active_modules: - implementation_id: energy_grid module_id: grid_connection_point module: EnergyManager - evse_manager: + connector_1: config_module: ac_enforce_hlc: false ac_hlc_enabled: true @@ -61,23 +63,25 @@ active_modules: payment_enable_eim: true rcd_enabled: true session_logging: true - session_logging_path: /tmp + session_logging_path: /tmp/everest-logs session_logging_xml: false three_phases: true connections: bsp: - implementation_id: board_support - module_id: yeti_driver + module_id: connector_1_powerpath hlc: - implementation_id: charger module_id: iso15118_charger powermeter_grid_side: - implementation_id: powermeter - module_id: yeti_driver + module_id: connector_1_powerpath slac: - implementation_id: evse module_id: slac module: EvseManager + telemetry: + id: 1 grid_connection_point: config_module: fuse_limit_A: 40 @@ -85,7 +89,7 @@ active_modules: connections: energy_consumer: - implementation_id: energy_grid - module_id: evse_manager + module_id: connector_1 module: EnergyNode iso15118_car: config_implementation: @@ -135,7 +139,7 @@ active_modules: connections: evse: - implementation_id: evse - module_id: evse_manager + module_id: connector_1 module: JsDummyTokenProvider token_validator: config_implementation: @@ -145,9 +149,11 @@ active_modules: validation_result: Accepted connections: {} module: JsDummyTokenValidator - yeti_driver: + connector_1_powerpath: connections: {} module: JsYetiSimulator + telemetry: + id: 1 x-module-layout: api: position: @@ -160,7 +166,7 @@ x-module-layout: - id: main interface: empty type: provide - - id: evse_manager + - id: connector_1 interface: evse_manager type: requirement top: [] @@ -170,7 +176,7 @@ x-module-layout: y: -6 terminals: bottom: - - id: evse_manager + - id: connector_1 interface: evse_manager type: requirement left: [] @@ -224,7 +230,7 @@ x-module-layout: interface: energy type: requirement top: [] - evse_manager: + connector_1: position: x: 17 y: 13 @@ -377,7 +383,7 @@ x-module-layout: type: provide right: [] top: [] - yeti_driver: + connector_1_powerpath: position: x: 15 y: 26 diff --git a/dependencies.yaml b/dependencies.yaml index abbd6e0a8..af81ee2d7 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -1,7 +1,7 @@ --- everest-framework: git: https://github.com/EVerest/everest-framework.git - git_tag: v0.3.0 + git_tag: v0.4.0 sigslot: git: https://github.com/palacaze/sigslot git_tag: v1.2.0 @@ -38,7 +38,7 @@ RISE-V2G: # OCPP libocpp: git: https://github.com/EVerest/libocpp.git - git_tag: v0.5.0 + git_tag: 904343c96f945710586b45975beb5b6dfed811d6 # Josev Josev: git: https://github.com/EVerest/ext-switchev-iso15118.git diff --git a/modules/EvseManager/EvseManager.cpp b/modules/EvseManager/EvseManager.cpp index 3e824a469..d1826c303 100644 --- a/modules/EvseManager/EvseManager.cpp +++ b/modules/EvseManager/EvseManager.cpp @@ -375,7 +375,7 @@ void EvseManager::ready() { hlc_waiting_for_auth_pnc = false; } r_hlc[0]->call_set_Auth_Okay_PnC(types::authorization::AuthorizationStatus::Accepted, - types::authorization::CertificateStatus::Accepted); + types::authorization::CertificateStatus::Accepted); } else { std::scoped_lock lock(hlc_mutex); hlc_waiting_for_auth_eim = false; @@ -614,6 +614,110 @@ void EvseManager::ready() { charger->setMaxCurrent(0.0F, date::utc_clock::now()); charger->run(); charger->enable(); + + telemetryThreadHandle = std::thread([this]() { + while (!telemetryThreadHandle.shouldExit()) { + sleep(10); + auto p = get_latest_powermeter_data_billing(); + Everest::TelemetryMap telemetry_data{{"timestamp", p.timestamp}, + {"type", "power_meter"}, + {"meter_id", p.meter_id.get_value_or("N/A")}, + {"energy_import_total_Wh", p.energy_Wh_import.total}}; + + if (p.energy_Wh_import.L1.is_initialized()) { + telemetry_data["energy_import_L1_Wh"] = p.energy_Wh_import.L1.get(); + } + if (p.energy_Wh_import.L2.is_initialized()) { + telemetry_data["energy_import_L2_Wh"] = p.energy_Wh_import.L2.get(); + } + if (p.energy_Wh_import.L3.is_initialized()) { + telemetry_data["energy_import_L3_Wh"] = p.energy_Wh_import.L3.get(); + } + + if (p.energy_Wh_export.is_initialized()) { + telemetry_data["energy_export_total_Wh"] = p.energy_Wh_export.get().total; + } + if (p.energy_Wh_export.is_initialized() && p.energy_Wh_export.get().L1.is_initialized()) { + telemetry_data["energy_export_L1_Wh"] = p.energy_Wh_export.get().L1.get(); + } + if (p.energy_Wh_export.is_initialized() && p.energy_Wh_export.get().L2.is_initialized()) { + telemetry_data["energy_export_L2_Wh"] = p.energy_Wh_export.get().L2.get(); + } + if (p.energy_Wh_export.is_initialized() && p.energy_Wh_export.get().L3.is_initialized()) { + telemetry_data["energy_export_L3_Wh"] = p.energy_Wh_export.get().L3.get(); + } + + if (p.power_W.is_initialized()) { + telemetry_data["power_total_W"] = p.power_W.get().total; + } + if (p.power_W.is_initialized() && p.power_W.get().L1.is_initialized()) { + telemetry_data["power_L1_W"] = p.power_W.get().L1.get(); + } + if (p.power_W.is_initialized() && p.power_W.get().L2.is_initialized()) { + telemetry_data["power_L3_W"] = p.power_W.get().L2.get(); + } + if (p.power_W.is_initialized() && p.power_W.get().L3.is_initialized()) { + telemetry_data["power_L3_W"] = p.power_W.get().L3.get(); + } + + if (p.VAR.is_initialized()) { + telemetry_data["var_total"] = p.VAR.get().total; + } + if (p.VAR.is_initialized() && p.VAR.get().L1.is_initialized()) { + telemetry_data["var_L1"] = p.VAR.get().L1.get(); + } + if (p.VAR.is_initialized() && p.VAR.get().L2.is_initialized()) { + telemetry_data["var_L1"] = p.VAR.get().L2.get(); + } + if (p.VAR.is_initialized() && p.VAR.get().L3.is_initialized()) { + telemetry_data["var_L1"] = p.VAR.get().L3.get(); + } + + if (p.voltage_V.is_initialized() && p.voltage_V.get().L1.is_initialized()) { + telemetry_data["voltage_L1_V"] = p.voltage_V.get().L1.get(); + } + if (p.voltage_V.is_initialized() && p.voltage_V.get().L2.is_initialized()) { + telemetry_data["voltage_L2_V"] = p.voltage_V.get().L2.get(); + } + if (p.voltage_V.is_initialized() && p.voltage_V.get().L3.is_initialized()) { + telemetry_data["voltage_L3_V"] = p.voltage_V.get().L3.get(); + } + if (p.voltage_V.is_initialized() && p.voltage_V.get().DC.is_initialized()) { + telemetry_data["voltage_DC_V"] = p.voltage_V.get().DC.get(); + } + + if (p.current_A.is_initialized() && p.current_A.get().L1.is_initialized()) { + telemetry_data["current_L1_A"] = p.current_A.get().L1.get(); + } + if (p.current_A.is_initialized() && p.current_A.get().L2.is_initialized()) { + telemetry_data["current_L2_A"] = p.current_A.get().L2.get(); + } + if (p.current_A.is_initialized() && p.current_A.get().L3.is_initialized()) { + telemetry_data["current_L3_A"] = p.current_A.get().L3.get(); + } + if (p.current_A.is_initialized() && p.current_A.get().DC.is_initialized()) { + telemetry_data["current_DC_A"] = p.current_A.get().DC.get(); + } + + if (p.frequency_Hz.is_initialized()) { + telemetry_data["frequency_L1_Hz"] = p.frequency_Hz.get().L1; + } + if (p.frequency_Hz.is_initialized() && p.frequency_Hz.get().L2.is_initialized()) { + telemetry_data["frequency_L2_Hz"] = p.frequency_Hz.get().L2.get(); + } + if (p.frequency_Hz.is_initialized() && p.frequency_Hz.get().L3.is_initialized()) { + telemetry_data["frequency_L3_Hz"] = p.frequency_Hz.get().L3.get(); + } + + if (p.phase_seq_error.is_initialized()) { + telemetry_data["phase_seq_error"] = p.phase_seq_error.get(); + } + + // Publish as external telemetry data + telemetry.publish("livedata", "power_meter", telemetry_data); + } + }); + EVLOG_info << fmt::format(fmt::emphasis::bold | fg(fmt::terminal_color::green), "🌀🌀🌀 Ready to start charging 🌀🌀🌀"); } @@ -791,7 +895,7 @@ void EvseManager::charger_was_authorized() { std::scoped_lock lock(hlc_mutex); if (hlc_waiting_for_auth_pnc && charger->Authorized_PnC()) { r_hlc[0]->call_set_Auth_Okay_PnC(types::authorization::AuthorizationStatus::Accepted, - types::authorization::CertificateStatus::Accepted); + types::authorization::CertificateStatus::Accepted); hlc_waiting_for_auth_eim = false; hlc_waiting_for_auth_pnc = false; } diff --git a/modules/EvseManager/EvseManager.hpp b/modules/EvseManager/EvseManager.hpp index 08e0621d7..71428275a 100644 --- a/modules/EvseManager/EvseManager.hpp +++ b/modules/EvseManager/EvseManager.hpp @@ -5,7 +5,7 @@ // // AUTO GENERATED - MARKED REGIONS WILL BE KEPT -// template version 1 +// template version 2 // #include "ld-ev.hpp" @@ -75,7 +75,7 @@ struct Conf { class EvseManager : public Everest::ModuleBase { public: EvseManager() = delete; - EvseManager(const ModuleInfo& info, Everest::MqttProvider& mqtt_provider, + EvseManager(const ModuleInfo& info, Everest::MqttProvider& mqtt_provider, Everest::TelemetryProvider& telemetry, std::unique_ptr p_evse, std::unique_ptr p_energy_grid, std::unique_ptr p_token_provider, std::unique_ptr r_bsp, @@ -86,6 +86,7 @@ class EvseManager : public Everest::ModuleBase { std::vector> r_powersupply_DC, Conf& config) : ModuleBase(info), mqtt(mqtt_provider), + telemetry(telemetry), p_evse(std::move(p_evse)), p_energy_grid(std::move(p_energy_grid)), p_token_provider(std::move(p_token_provider)), @@ -100,6 +101,7 @@ class EvseManager : public Everest::ModuleBase { const Conf& config; Everest::MqttProvider& mqtt; + Everest::TelemetryProvider& telemetry; const std::unique_ptr p_evse; const std::unique_ptr p_energy_grid; const std::unique_ptr p_token_provider; @@ -201,6 +203,7 @@ class EvseManager : public Everest::ModuleBase { void imd_stop(); void imd_start(); + Everest::Thread telemetryThreadHandle; // ev@211cfdbe-f69a-4cd6-a4ec-f8aaa3d1b6c8:v1 }; diff --git a/modules/EvseManager/SessionLog.cpp b/modules/EvseManager/SessionLog.cpp index a693df544..7a73f7426 100644 --- a/modules/EvseManager/SessionLog.cpp +++ b/modules/EvseManager/SessionLog.cpp @@ -29,29 +29,36 @@ SessionLog::~SessionLog() { } void SessionLog::setPath(const std::string& path) { - logpath = path; + logpath_root = path; } void SessionLog::enable() { enabled = true; } -void SessionLog::startSession(const std::string& session_id) { +boost::optional SessionLog::startSession(const std::string& session_id) { if (enabled) { if (session_active) { stopSession(); } - // create log directory if it does not exist + // create general log directory if it does not exist + if (!std::filesystem::exists(logpath_root)) + std::filesystem::create_directory(logpath_root); + + std::string ts = Everest::Date::to_rfc3339(date::utc_clock::now()); + logpath = fmt::format("{}/{}-{}", logpath_root, ts, session_id); + + // create sessionlog directory if it does not exist if (!std::filesystem::exists(logpath)) std::filesystem::create_directory(logpath); // open new file - std::string ts = Everest::Date::to_rfc3339(date::utc_clock::now()); - const std::string fn = fmt::format("{}/everest-session-{}.log", logpath, session_id); - const std::string fnhtml = fmt::format("{}/everest-session-{}.html", logpath, session_id); - // const std::string fn = fmt::format("{}/everest-session.log", logpath); - // const std::string fnhtml = fmt::format("{}/everest-session.html", logpath); + fn = fmt::format("{}/incomplete-eventlog.csv", logpath); + fnhtml = fmt::format("{}/incomplete-eventlog.html", logpath); + fn_complete = fmt::format("{}/eventlog.csv", logpath); + fnhtml_complete = fmt::format("{}/eventlog.html", logpath); + try { logfile_csv.open(fn); logfile_html.open(fnhtml); @@ -86,7 +93,10 @@ void SessionLog::startSession(const std::string& session_id) { ""; logfile_html << "\n"; sys("Session logging started."); + return boost::optional(logpath); } + + return boost::optional(); } void SessionLog::stopSession() { @@ -102,6 +112,10 @@ void SessionLog::stopSession() { logfile_html.close(); } + // rename files to indicate they are finished now + std::filesystem::rename(fn, fn_complete); + std::filesystem::rename(fnhtml, fnhtml_complete); + session_active = false; } } diff --git a/modules/EvseManager/SessionLog.hpp b/modules/EvseManager/SessionLog.hpp index 55a7eadac..d14f31c6b 100644 --- a/modules/EvseManager/SessionLog.hpp +++ b/modules/EvseManager/SessionLog.hpp @@ -5,6 +5,7 @@ #include #include +#include namespace module { /* @@ -18,26 +19,32 @@ class SessionLog { void setPath(const std::string& path); void enable(); - void startSession(const std::string& session_id); + boost::optional startSession(const std::string& session_id); void stopSession(); void car(bool iso15118, const std::string& msg); - void car(bool iso15118, const std::string& msg, const std::string& xml, const std::string& xml_hex, const std::string& xml_base64, const std::string& json_str); + void car(bool iso15118, const std::string& msg, const std::string& xml, const std::string& xml_hex, + const std::string& xml_base64, const std::string& json_str); void evse(bool iso15118, const std::string& msg); - void evse(bool iso15118, const std::string& msg, const std::string& xml, const std::string& xml_hex, const std::string& xml_base64, const std::string& json_str); + void evse(bool iso15118, const std::string& msg, const std::string& xml, const std::string& xml_hex, + const std::string& xml_base64, const std::string& json_str); void xmlOutput(bool e); void sys(const std::string& msg); private: - void output(unsigned int evse, bool iso15118, const std::string& msg, const std::string& xml, const std::string& xml_hex, const std::string& xml_base64, const std::string& json_str); + void output(unsigned int evse, bool iso15118, const std::string& msg, const std::string& xml, + const std::string& xml_hex, const std::string& xml_base64, const std::string& json_str); std::string html_encode(const std::string& msg); bool xmloutput; bool session_active; bool enabled; + std::string logpath_root; std::string logpath; + std::string fn, fnhtml, fn_complete, fnhtml_complete; + std::ofstream logfile_csv; std::ofstream logfile_html; }; diff --git a/modules/EvseManager/evse/evse_managerImpl.cpp b/modules/EvseManager/evse/evse_managerImpl.cpp index 610c4dc3e..39aeb376a 100644 --- a/modules/EvseManager/evse/evse_managerImpl.cpp +++ b/modules/EvseManager/evse/evse_managerImpl.cpp @@ -119,15 +119,27 @@ void evse_managerImpl::ready() { set_session_uuid(); - session_log.startSession(session_uuid); + session_started.logging_path = session_log.startSession(session_uuid); session_log.evse( false, fmt::format("Session Started: {}", types::evse_manager::start_session_reason_to_string(reason))); + mod->telemetry.publish("session", "events", + { + {"timestamp", Everest::Date::to_rfc3339(date::utc_clock::now())}, + {"type", "session_started"}, + {"session_id", session_uuid}, + {"reason", types::evse_manager::start_session_reason_to_string(reason)}, + }); + se.session_started = session_started; } else if (e == types::evse_manager::SessionEventEnum::SessionFinished) { session_log.evse(false, fmt::format("Session Finished")); session_log.stopSession(); + mod->telemetry.publish("session", "events", + {{"timestamp", Everest::Date::to_rfc3339(date::utc_clock::now())}, + {"type", "session_finished"}, + {"session_id", session_uuid}}); } else if (e == types::evse_manager::SessionEventEnum::TransactionStarted) { types::evse_manager::TransactionStarted transaction_started; transaction_started.timestamp = @@ -149,6 +161,17 @@ void evse_managerImpl::ready() { session_log.evse(false, fmt::format("Transaction Started ({} kWh)", energy_import / 1000.)); + Everest::TelemetryMap telemetry_data = {{"timestamp", Everest::Date::to_rfc3339(date::utc_clock::now())}, + {"type", "transaction_started"}, + {"session_id", session_uuid}, + {"energy_counter_import_wh", p.energy_Wh_import.total}, + {"id_tag", transaction_started.id_tag}}; + + if (p.energy_Wh_export.is_initialized()) { + telemetry_data["energy_counter_export_wh"] = p.energy_Wh_export.get().total; + } + mod->telemetry.publish("session", "events", telemetry_data); + se.transaction_started.emplace(transaction_started); } else if (e == types::evse_manager::SessionEventEnum::TransactionFinished) { types::evse_manager::TransactionFinished transaction_finished; @@ -176,7 +199,18 @@ void evse_managerImpl::ready() { types::evse_manager::stop_transaction_reason_to_string(reason), energy_import / 1000.)); - session_uuid = ""; + Everest::TelemetryMap telemetry_data = { + {"timestamp", Everest::Date::to_rfc3339(date::utc_clock::now())}, + {"type", "transaction_finished"}, + {"session_id", session_uuid}, + {"energy_counter_import_wh", p.energy_Wh_import.total}, + {"reason", types::evse_manager::stop_transaction_reason_to_string(reason)}}; + + if (p.energy_Wh_export.is_initialized()) { + telemetry_data["energy_counter_export_wh"] = p.energy_Wh_export.get().total; + } + + mod->telemetry.publish("session", "events", telemetry_data); se.transaction_finished.emplace(transaction_finished); } else if (e == types::evse_manager::SessionEventEnum::Error) { @@ -186,6 +220,9 @@ void evse_managerImpl::ready() { se.uuid = session_uuid; publish_session_event(se); + if (e == types::evse_manager::SessionEventEnum::SessionFinished) { + session_uuid = ""; + } }); // Note: Deprecated. Only kept for Node red compatibility, will be removed in the future @@ -257,7 +294,6 @@ bool evse_managerImpl::handle_resume_charging() { }; bool evse_managerImpl::handle_stop_transaction(types::evse_manager::StopTransactionRequest& request) { - if (mod->get_hlc_enabled()) { mod->r_hlc[0]->call_stop_charging(true); } diff --git a/modules/EvseManager/manifest.yaml b/modules/EvseManager/manifest.yaml index ac5acffae..a3ec81b7d 100644 --- a/modules/EvseManager/manifest.yaml +++ b/modules/EvseManager/manifest.yaml @@ -177,6 +177,7 @@ requires: min_connections: 0 max_connections: 1 enable_external_mqtt: true +enable_telemetry: true metadata: license: https://spdx.org/licenses/Apache-2.0.html authors: diff --git a/modules/JsYetiSimulator/index.js b/modules/JsYetiSimulator/index.js index d3b59fcf6..8f74f9f5b 100644 --- a/modules/JsYetiSimulator/index.js +++ b/modules/JsYetiSimulator/index.js @@ -29,9 +29,13 @@ const Event_EFtoBCD = 11; const Event_BCDtoEF = 12; const Event_PermanentFault = 13; +var module_id; +let global_info; + boot_module(async ({ setup, info, config, mqtt, }) => { + global_info = info; // register commands setup.provides.yeti_simulation_control.register.enable(enable_simulation); setup.provides.yeti_simulation_control.register.setSimulationData((mod, args) => { @@ -88,8 +92,48 @@ boot_module(async ({ mod.pubCnt = 0; clearData(mod); setInterval(simulation_loop, 250, mod); + if (global_info.telemetry_enabled) { + setInterval(telemetry_slow, 15000, mod); + setInterval(telemetry_fast, 1000, mod); + } }); +function telemetry_slow(mod) { + const date = new Date(); + mod.telemetry_data.power_path_controller_version.timestamp = date.toISOString(); + mod.telemetry.publish('livedata', 'power_path_controller_version', mod.telemetry_data.power_path_controller_version); +} + +function telemetry_fast(mod) { + const date = new Date(); + mod.telemetry_data.power_path_controller.timestamp = date.toISOString(); + mod.telemetry_data.power_path_controller.cp_voltage_high = mod.cpHi; + mod.telemetry_data.power_path_controller.cp_voltage_low = mod.cpLo; + mod.telemetry_data.power_path_controller.cp_pwm_duty_cycle = mod.pwm_duty_cycle * 100.; + mod.telemetry_data.power_path_controller.cp_state = stateToString(mod); + + mod.telemetry_data.power_path_controller.temperature_controller = mod.powermeter.tempL1; + mod.telemetry_data.power_path_controller.temperature_car_connector = mod.powermeter.tempL1 * 2.; + mod.telemetry_data.power_path_controller.watchdog_reset_count = 0; + mod.telemetry_data.power_path_controller.error = false; + + mod.telemetry_data.power_switch.timestamp = date.toISOString(); + mod.telemetry_data.power_switch.is_on = mod.relais_on; + mod.telemetry_data.power_switch.time_to_switch_on_ms = 110; + mod.telemetry_data.power_switch.time_to_switch_off_ms = 100; + mod.telemetry_data.power_switch.temperature_C = 20; + mod.telemetry_data.power_switch.error = false; + mod.telemetry_data.power_switch.error_over_current = false; + + mod.telemetry_data.rcd.timestamp = date.toISOString(); + mod.telemetry_data.rcd.current_mA = mod.rcd_current; + + mod.telemetry.publish('livedata', 'power_path_controller', mod.telemetry_data.power_path_controller); + mod.telemetry.publish('livedata', 'power_switch', mod.telemetry_data.power_switch); + mod.telemetry.publish('livedata', 'rcd', mod.telemetry_data.rcd); + +} + function publish_event(mod, event) { // console.log("------------ EVENT PUB "+event); mod.provides.board_support.publish.event(event_to_enum(event)); @@ -353,12 +397,14 @@ function powerOn(mod) { if (!mod.relais_on) { publish_event(mod, Event_PowerOn); mod.relais_on = true; + mod.telemetry_data.power_switch.switching_count++; } } function powerOff(mod) { if (mod.relais_on) { publish_event(mod, Event_PowerOff); + mod.telemetry_data.power_switch.switching_count++; mod.relais_on = false; } } @@ -509,6 +555,61 @@ function clearData(mod) { L3: 0.0, }; mod.powermeter_sim_last_time_stamp = 0; + + mod.telemetry_data = { + + power_path_controller_version: { + timestamp: "", + type: "power_path_controller_version", + hardware_version: 3, + software_version: "1.01", + date_manufactured: "20220304", + operating_time_h: 2330, + operating_time_h_warning: 5000, + operating_time_h_error: 6000, + error: false + }, + + power_path_controller: { + timestamp: "", + type: "power_path_controller", + cp_voltage_high: 0.0, + cp_voltage_low: 0.0, + cp_pwm_duty_cycle: 0.0, + cp_state: "A1", + pp_ohm: 220.1, + supply_voltage_12V: 12.1, + supply_voltage_minus_12V: -11.9, + temperature_controller: 33, + temperature_car_connector: 65, + watchdog_reset_count: 1, + error: false + }, + + power_switch: { + timestamp: "", + type: "power_switch", + switching_count: 0, + switching_count_warning: 30000, + switching_count_error: 50000, + is_on: false, + time_to_switch_on_ms: 110, + time_to_switch_off_ms: 100, + temperature_C: 20, + error: false, + error_over_current: false + }, + + rcd: { + timestamp: "", + type: "rcd", + enabled: true, + current_mA: 2.5, + triggered: false, + error: false + } + } + } function reset_powermeter(mod) { @@ -519,35 +620,37 @@ function reset_powermeter(mod) { }; mod.powermeter_sim_last_time_stamp = 0; } -/* -function stateToString(state) { - switch (state) { + +function stateToString(mod) { + let pwm = (mod.pwm_running ? "2" : "1"); + switch (mod.state) { case STATE_DISABLED: return 'Disabled'; - break; + break; case STATE_A: - return 'A'; - break; + return 'A' + pwm; + break; case STATE_B: - return 'B'; - break; + return 'B' + pwm; + break; case STATE_C: - return 'C'; - break; + return 'C' + pwm; + break; case STATE_D: - return 'D'; - break; + return 'D' + pwm; + break; case STATE_E: return 'E'; - break; + break; case STATE_F: return 'F'; - break; + break; case STATE_DF: return 'DF'; - break; + break; } -} */ +} + function power_meter_external(p) { const date = new Date(); return ({ @@ -721,13 +824,13 @@ function read_pp_ampacity(mod) { } // PP resistor value in spec, use a conservative interpretation of the resistance ranges - if(pp_resistor > 936.0 && pp_resistor <= 2460.0) { + if (pp_resistor > 936.0 && pp_resistor <= 2460.0) { return 13.0; - } else if(pp_resistor > 308.0 && pp_resistor <= 936.0) { + } else if (pp_resistor > 308.0 && pp_resistor <= 936.0) { return 20.0; - } else if(pp_resistor > 140.0 && pp_resistor <= 308.0) { + } else if (pp_resistor > 140.0 && pp_resistor <= 308.0) { return 32.0; - } else if(pp_resistor > 80.0 && pp_resistor <= 140.0) { + } else if (pp_resistor > 80.0 && pp_resistor <= 140.0) { return 63.0; } diff --git a/modules/JsYetiSimulator/manifest.yaml b/modules/JsYetiSimulator/manifest.yaml index 5ae9f495f..e009ecd94 100644 --- a/modules/JsYetiSimulator/manifest.yaml +++ b/modules/JsYetiSimulator/manifest.yaml @@ -25,6 +25,7 @@ provides: interface: yeti_simulation_control description: Interface for the Yeti HIL simulator enable_external_mqtt: true +enable_telemetry: true metadata: license: https://opensource.org/licenses/Apache-2.0 authors: diff --git a/modules/OCPP/OCPP.cpp b/modules/OCPP/OCPP.cpp index 2b68ad9b3..841a99528 100644 --- a/modules/OCPP/OCPP.cpp +++ b/modules/OCPP/OCPP.cpp @@ -411,12 +411,13 @@ void OCPP::init() { auto session_started = session_event.session_started.value(); this->charge_point->on_session_started( connector, session_event.uuid, - types::evse_manager::start_session_reason_to_string(session_started.reason)); + types::evse_manager::start_session_reason_to_string(session_started.reason), + session_started.logging_path); } else if (event == "SessionFinished") { EVLOG_debug << "Connector#" << connector << ": " << "Received SessionFinished"; // ev side disconnect - this->charge_point->on_session_stopped(connector); + this->charge_point->on_session_stopped(connector, session_event.uuid); } else if (event == "Error") { EVLOG_debug << "Connector#" << connector << ": " << "Received Error"; diff --git a/modules/OCPP/OCPP.hpp b/modules/OCPP/OCPP.hpp index 334d893bf..411ec6c71 100644 --- a/modules/OCPP/OCPP.hpp +++ b/modules/OCPP/OCPP.hpp @@ -23,23 +23,21 @@ // ev@4bf81b14-a215-475c-a1d3-0a484ae48918:v1 // insert your custom include headers here -#include #include #include #include #include +#include #include -#include #include #include +#include #include - // ev@4bf81b14-a215-475c-a1d3-0a484ae48918:v1 namespace module { struct Conf { - std::string OcppMainPath; std::string ChargePointConfigPath; std::string UserConfigPath; std::string DatabasePath; diff --git a/modules/PacketSniffer/PacketSniffer.cpp b/modules/PacketSniffer/PacketSniffer.cpp index a741bc8b6..a120ae9d1 100644 --- a/modules/PacketSniffer/PacketSniffer.cpp +++ b/modules/PacketSniffer/PacketSniffer.cpp @@ -20,8 +20,7 @@ void PacketSniffer::init() { p_handle = pcap_open_live(config.device.c_str(), BUFFERSIZE, PROMISC_MODE, PACKET_BUFFER_TIMEOUT_MS, errbuf); if (p_handle == nullptr) { - EVLOG_AND_THROW(Everest::EverestConfigError( - fmt::format("Could not open device {}", config.device))); + EVLOG_AND_THROW(Everest::EverestConfigError(fmt::format("Could not open device {}", config.device))); return; } @@ -32,13 +31,17 @@ void PacketSniffer::init() { } r_evse_manager->subscribe_session_event([this](types::evse_manager::SessionEvent session_event) { - std::lock_guard lock(this->capture_mutex); if (session_event.event == types::evse_manager::SessionEventEnum::SessionStarted) { if (!already_started) { already_started = true; capturing_stopped = false; - std::thread(&PacketSniffer::capture, this, config.session_logging_path, session_event.uuid).detach(); + if (session_event.session_started.is_initialized() && + session_event.session_started.get().logging_path.is_initialized()) { + std::thread(&PacketSniffer::capture, this, session_event.session_started.get().logging_path.get(), + session_event.uuid) + .detach(); + } } else { EVLOG_warning << fmt::format("Capturing already started. Ignoring this SessionStarted event"); } @@ -55,24 +58,22 @@ void PacketSniffer::ready() { void PacketSniffer::capture(const std::string& logpath, const std::string& session_id) { - const std::string fn = fmt::format("{}/everest-session-{}.dump", - logpath, session_id); + const std::string fn = fmt::format("{}/ethernet-traffic.dump", logpath); if ((pdumpfile = pcap_dump_open(p_handle, fn.c_str())) == nullptr) { - EVLOG_error << fmt::format("Error opening savefile {} for writing: {}", - fn, pcap_geterr(p_handle)); + EVLOG_error << fmt::format("Error opening savefile {} for writing: {}", fn, pcap_geterr(p_handle)); return; } while (!capturing_stopped) { - if (pcap_dispatch(p_handle, ALL_PACKETS_PROCESSED, &pcap_dump, (u_char *)pdumpfile) <= PCAP_ERROR) { - EVLOG_error << fmt::format("Error reading packets from interface: {}, error: {}", - config.device, pcap_geterr(p_handle)); + if (pcap_dispatch(p_handle, ALL_PACKETS_PROCESSED, &pcap_dump, (u_char*)pdumpfile) <= PCAP_ERROR) { + EVLOG_error << fmt::format("Error reading packets from interface: {}, error: {}", config.device, + pcap_geterr(p_handle)); break; } std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_MS)); } - + pcap_dump_close(pdumpfile); } diff --git a/modules/YetiDriver/CMakeLists.txt b/modules/YetiDriver/CMakeLists.txt index 65506bb74..16df973d9 100644 --- a/modules/YetiDriver/CMakeLists.txt +++ b/modules/YetiDriver/CMakeLists.txt @@ -31,10 +31,6 @@ target_sources(${MODULE_NAME} "powermeter/powermeterImpl.cpp" "board_support/board_support_ACImpl.cpp" "yeti_extras/yeti_extrasImpl.cpp" - "debug_yeti/debug_jsonImpl.cpp" - "debug_powermeter/debug_jsonImpl.cpp" - "debug_state/debug_jsonImpl.cpp" - "debug_keepalive/debug_jsonImpl.cpp" "yeti_simulation_control/yeti_simulation_controlImpl.cpp" ) diff --git a/modules/YetiDriver/YetiDriver.cpp b/modules/YetiDriver/YetiDriver.cpp index 6f7d674d6..045689341 100644 --- a/modules/YetiDriver/YetiDriver.cpp +++ b/modules/YetiDriver/YetiDriver.cpp @@ -1,9 +1,35 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2020 - 2021 Pionix GmbH and Contributors to EVerest #include "YetiDriver.hpp" +#include +#include namespace module { +std::string lowlevelstate_to_string(const DebugUpdate_LoLevelState s, bool pwm_on) { + const std::string pwm = (pwm_on ? "2" : "1"); + switch (s) { + case DebugUpdate_LoLevelState_DISABLED: + return "Disabled"; + case DebugUpdate_LoLevelState_A: + return "A" + pwm; + case DebugUpdate_LoLevelState_B: + return "B" + pwm; + case DebugUpdate_LoLevelState_C: + return "C" + pwm; + case DebugUpdate_LoLevelState_D: + return "D" + pwm; + case DebugUpdate_LoLevelState_E: + return "E"; + case DebugUpdate_LoLevelState_F: + return "F"; + case DebugUpdate_LoLevelState_DF: + return "DF"; + default: + return "Unknown"; + } +} + void YetiDriver::init() { // initialize serial driver @@ -13,12 +39,52 @@ void YetiDriver::init() { return; } + telemetry_power_path_controller_version = {{"timestamp", ""}, + {"type", "power_path_controller_version"}, + {"hardware_version", 1}, + {"software_version", "1.00"}, + {"date_manufactured", "N/A"}, + {"operating_time_h", 5}, + {"operating_time_h_warning", 5000}, + {"operating_time_h_error", 6000}, + {"software_version", "1.00"}, + {"error", false}}; + + telemetry_power_path_controller = {{"timestamp", ""}, + {"type", "power_path_controller"}, + {"cp_voltage_high", 0.0}, + {"cp_voltage_low", 0.0}, + {"cp_pwm_duty_cycle", 0.0}, + {"cp_state", "A1"}, + {"pp_ohm", 0.0}, + {"supply_voltage_12V", 0.0}, + {"supply_voltage_minus_12V", 0.0}, + {"temperature_controller", 0.0}, + {"temperature_car_connector", 0.0}, + {"watchdog_reset_count", 0.0}, + {"error", false}}; + + telemetry_power_switch = {{"timestamp", ""}, + {"type", "power_switch"}, + {"switching_count", 0}, + {"switching_count_warning", 30000}, + {"switching_count_error", 50000}, + {"is_on", false}, + {"time_to_switch_on_ms", 100}, + {"time_to_switch_off_ms", 100}, + {"temperature_C", 0.0}, + {"error", false}, + {"error_over_current", false}}; + + telemetry_rcd = {{"timestamp", ""}, // + {"type", "rcd"}, // + {"enabled", true}, // + {"current_mA", 0.0}, // + {"triggered", false}, // + {"error", false}}; // + invoke_init(*p_powermeter); invoke_init(*p_yeti_extras); - invoke_init(*p_debug_yeti); - invoke_init(*p_debug_powermeter); - invoke_init(*p_debug_state); - invoke_init(*p_debug_keepalive); invoke_init(*p_yeti_simulation_control); invoke_init(*p_board_support); } @@ -39,12 +105,59 @@ void YetiDriver::ready() { invoke_ready(*p_powermeter); invoke_ready(*p_yeti_extras); - invoke_ready(*p_debug_yeti); - invoke_ready(*p_debug_powermeter); - invoke_ready(*p_debug_state); - invoke_ready(*p_debug_keepalive); invoke_ready(*p_yeti_simulation_control); invoke_ready(*p_board_support); + + serial.signalKeepAliveLo.connect([this](const KeepAliveLo& k) { + auto k_json = keep_alive_lo_to_json(k); + mqtt.publish("/external/keepalive_json", k_json.dump()); + }); + + telemetryThreadHandle = std::thread([this]() { + while (!telemetryThreadHandle.shouldExit()) { + sleep(10); + { + std::scoped_lock lock(telemetry_mutex); + publish_external_telemetry_livedata("power_path_controller", telemetry_power_path_controller); + publish_external_telemetry_livedata("rcd", telemetry_rcd); + publish_external_telemetry_livedata("power_path_controller_version", + telemetry_power_path_controller_version); + } + } + }); + + serial.signalDebugUpdate.connect([this](const DebugUpdate& d) { + static bool relay_was_on = true; + auto d_json = debug_update_to_json(d); + mqtt.publish("/external/debug_json", d_json.dump()); + { + std::scoped_lock lock(telemetry_mutex); + // update external telemetry data + telemetry_power_path_controller.at("timestamp") = Everest::Date::to_rfc3339(date::utc_clock::now()); + telemetry_power_path_controller.at("cp_voltage_high") = d.evse_pwm_voltage_hi; + telemetry_power_path_controller.at("cp_voltage_low") = d.evse_pwm_voltage_lo; + telemetry_power_path_controller.at("cp_pwm_duty_cycle") = 0.; // FIXME this should be included + telemetry_power_path_controller.at("cp_state") = + lowlevelstate_to_string(d.lowlevel_state, d.evse_pwm_running); + telemetry_power_path_controller.at("pp_ohm") = 0.; // FIXME this should be included + telemetry_power_path_controller.at("supply_voltage_12V") = d.supply_voltage_12V; + telemetry_power_path_controller.at("supply_voltage_minus_12V") = d.supply_voltage_N12V; + telemetry_power_path_controller.at("temperature_controller") = d.cpu_temperature; + telemetry_power_path_controller.at("temperature_car_connector") = 0.; + telemetry_power_path_controller.at("watchdog_reset_count") = d.watchdog_reset_count; + + telemetry_rcd.at("timestamp") = Everest::Date::to_rfc3339(date::utc_clock::now()); + telemetry_rcd.at("current_mA") = d.rcd_current; + telemetry_rcd.at("enabled") = d.rcd_enabled; + + telemetry_power_switch.at("timestamp") = Everest::Date::to_rfc3339(date::utc_clock::now()); + telemetry_power_switch.at("is_on") = d.relais_on; + if (relay_was_on != d.relais_on) { + publish_external_telemetry_livedata("power_switch", telemetry_power_switch); + } + relay_was_on = d.relais_on; + } + }); } Everest::json power_meter_data_to_json(const PowerMeter& p) { @@ -182,4 +295,10 @@ InterfaceControlMode str_to_control_mode(std::string data) { return InterfaceControlMode_NONE; } +void YetiDriver::publish_external_telemetry_livedata(const std::string& topic, const Everest::TelemetryMap& data) { + if (info.telemetry_enabled) { + telemetry.publish("livedata", topic, data); + } +} + } // namespace module diff --git a/modules/YetiDriver/YetiDriver.hpp b/modules/YetiDriver/YetiDriver.hpp index 558bcea7f..7628670c2 100644 --- a/modules/YetiDriver/YetiDriver.hpp +++ b/modules/YetiDriver/YetiDriver.hpp @@ -5,14 +5,13 @@ // // AUTO GENERATED - MARKED REGIONS WILL BE KEPT -// template version 1 +// template version 2 // #include "ld-ev.hpp" // headers for provided interface implementations #include -#include #include #include #include @@ -33,37 +32,30 @@ struct Conf { class YetiDriver : public Everest::ModuleBase { public: YetiDriver() = delete; - YetiDriver(const ModuleInfo& info, Everest::MqttProvider& mqtt_provider, + YetiDriver(const ModuleInfo& info, Everest::MqttProvider& mqtt_provider, Everest::TelemetryProvider& telemetry, std::unique_ptr p_powermeter, std::unique_ptr p_board_support, - std::unique_ptr p_yeti_extras, std::unique_ptr p_debug_yeti, - std::unique_ptr p_debug_powermeter, - std::unique_ptr p_debug_state, std::unique_ptr p_debug_keepalive, + std::unique_ptr p_yeti_extras, std::unique_ptr p_yeti_simulation_control, Conf& config) : ModuleBase(info), mqtt(mqtt_provider), + telemetry(telemetry), p_powermeter(std::move(p_powermeter)), p_board_support(std::move(p_board_support)), p_yeti_extras(std::move(p_yeti_extras)), - p_debug_yeti(std::move(p_debug_yeti)), - p_debug_powermeter(std::move(p_debug_powermeter)), - p_debug_state(std::move(p_debug_state)), - p_debug_keepalive(std::move(p_debug_keepalive)), p_yeti_simulation_control(std::move(p_yeti_simulation_control)), config(config){}; const Conf& config; Everest::MqttProvider& mqtt; + Everest::TelemetryProvider& telemetry; const std::unique_ptr p_powermeter; const std::unique_ptr p_board_support; const std::unique_ptr p_yeti_extras; - const std::unique_ptr p_debug_yeti; - const std::unique_ptr p_debug_powermeter; - const std::unique_ptr p_debug_state; - const std::unique_ptr p_debug_keepalive; const std::unique_ptr p_yeti_simulation_control; // ev@1fce4c5e-0ab8-41bb-90f7-14277703d2ac:v1 + void publish_external_telemetry_livedata(const std::string& topic, const Everest::TelemetryMap& data); evSerial serial; // ev@1fce4c5e-0ab8-41bb-90f7-14277703d2ac:v1 @@ -79,6 +71,12 @@ class YetiDriver : public Everest::ModuleBase { // ev@211cfdbe-f69a-4cd6-a4ec-f8aaa3d1b6c8:v1 // insert your private definitions here + Everest::TelemetryMap telemetry_power_path_controller_version; + Everest::TelemetryMap telemetry_power_path_controller; + Everest::TelemetryMap telemetry_power_switch; + Everest::TelemetryMap telemetry_rcd; + std::mutex telemetry_mutex; + Everest::Thread telemetryThreadHandle; // ev@211cfdbe-f69a-4cd6-a4ec-f8aaa3d1b6c8:v1 }; diff --git a/modules/YetiDriver/debug_keepalive/debug_jsonImpl.cpp b/modules/YetiDriver/debug_keepalive/debug_jsonImpl.cpp deleted file mode 100644 index 931bfece9..000000000 --- a/modules/YetiDriver/debug_keepalive/debug_jsonImpl.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2020 - 2021 Pionix GmbH and Contributors to EVerest -#include "debug_jsonImpl.hpp" - -namespace module { -namespace debug_keepalive { - -void debug_jsonImpl::init() { - mod->serial.signalKeepAliveLo.connect([this](const KeepAliveLo& k) { - auto k_json = keep_alive_lo_to_json(k); - mod->mqtt.publish("/external/keepalive_json", k_json.dump()); - publish_debug_json(k_json); - }); -} - -void debug_jsonImpl::ready() { -} - -} // namespace debug_keepalive -} // namespace module diff --git a/modules/YetiDriver/debug_keepalive/debug_jsonImpl.hpp b/modules/YetiDriver/debug_keepalive/debug_jsonImpl.hpp deleted file mode 100644 index 9989f0f2c..000000000 --- a/modules/YetiDriver/debug_keepalive/debug_jsonImpl.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Pionix GmbH and Contributors to EVerest -#ifndef DEBUG_KEEPALIVE_DEBUG_JSON_IMPL_HPP -#define DEBUG_KEEPALIVE_DEBUG_JSON_IMPL_HPP - -// -// AUTO GENERATED - MARKED REGIONS WILL BE KEPT -// template version 3 -// - -#include - -#include "../YetiDriver.hpp" - -// ev@75ac1216-19eb-4182-a85c-820f1fc2c091:v1 -// insert your custom include headers here -// ev@75ac1216-19eb-4182-a85c-820f1fc2c091:v1 - -namespace module { -namespace debug_keepalive { - -struct Conf {}; - -class debug_jsonImpl : public debug_jsonImplBase { -public: - debug_jsonImpl() = delete; - debug_jsonImpl(Everest::ModuleAdapter* ev, const Everest::PtrContainer& mod, Conf& config) : - debug_jsonImplBase(ev, "debug_keepalive"), mod(mod), config(config){}; - - // ev@8ea32d28-373f-4c90-ae5e-b4fcc74e2a61:v1 - // insert your public definitions here - // ev@8ea32d28-373f-4c90-ae5e-b4fcc74e2a61:v1 - -protected: - // no commands defined for this interface - - // ev@d2d1847a-7b88-41dd-ad07-92785f06f5c4:v1 - // insert your protected definitions here - // ev@d2d1847a-7b88-41dd-ad07-92785f06f5c4:v1 - -private: - const Everest::PtrContainer& mod; - const Conf& config; - - virtual void init() override; - virtual void ready() override; - - // ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1 - // insert your private definitions here - // ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1 -}; - -// ev@3d7da0ad-02c2-493d-9920-0bbbd56b9876:v1 -// insert other definitions here -// ev@3d7da0ad-02c2-493d-9920-0bbbd56b9876:v1 - -} // namespace debug_keepalive -} // namespace module - -#endif // DEBUG_KEEPALIVE_DEBUG_JSON_IMPL_HPP diff --git a/modules/YetiDriver/debug_powermeter/debug_jsonImpl.cpp b/modules/YetiDriver/debug_powermeter/debug_jsonImpl.cpp deleted file mode 100644 index a1c722253..000000000 --- a/modules/YetiDriver/debug_powermeter/debug_jsonImpl.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2020 - 2021 Pionix GmbH and Contributors to EVerest -#include "debug_jsonImpl.hpp" - -namespace module { -namespace debug_powermeter { - -void debug_jsonImpl::init() { - mod->serial.signalPowerMeter.connect( - [this](const PowerMeter& p) { publish_debug_json(power_meter_data_to_json(p)); }); -} - -void debug_jsonImpl::ready() { -} - -} // namespace debug_powermeter -} // namespace module diff --git a/modules/YetiDriver/debug_powermeter/debug_jsonImpl.hpp b/modules/YetiDriver/debug_powermeter/debug_jsonImpl.hpp deleted file mode 100644 index 04e5a95d6..000000000 --- a/modules/YetiDriver/debug_powermeter/debug_jsonImpl.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Pionix GmbH and Contributors to EVerest -#ifndef DEBUG_POWERMETER_DEBUG_JSON_IMPL_HPP -#define DEBUG_POWERMETER_DEBUG_JSON_IMPL_HPP - -// -// AUTO GENERATED - MARKED REGIONS WILL BE KEPT -// template version 3 -// - -#include - -#include "../YetiDriver.hpp" - -// ev@75ac1216-19eb-4182-a85c-820f1fc2c091:v1 -// insert your custom include headers here -// ev@75ac1216-19eb-4182-a85c-820f1fc2c091:v1 - -namespace module { -namespace debug_powermeter { - -struct Conf {}; - -class debug_jsonImpl : public debug_jsonImplBase { -public: - debug_jsonImpl() = delete; - debug_jsonImpl(Everest::ModuleAdapter* ev, const Everest::PtrContainer& mod, Conf& config) : - debug_jsonImplBase(ev, "debug_powermeter"), mod(mod), config(config){}; - - // ev@8ea32d28-373f-4c90-ae5e-b4fcc74e2a61:v1 - // insert your public definitions here - // ev@8ea32d28-373f-4c90-ae5e-b4fcc74e2a61:v1 - -protected: - // no commands defined for this interface - - // ev@d2d1847a-7b88-41dd-ad07-92785f06f5c4:v1 - // insert your protected definitions here - // ev@d2d1847a-7b88-41dd-ad07-92785f06f5c4:v1 - -private: - const Everest::PtrContainer& mod; - const Conf& config; - - virtual void init() override; - virtual void ready() override; - - // ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1 - // insert your private definitions here - // ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1 -}; - -// ev@3d7da0ad-02c2-493d-9920-0bbbd56b9876:v1 -// insert other definitions here -// ev@3d7da0ad-02c2-493d-9920-0bbbd56b9876:v1 - -} // namespace debug_powermeter -} // namespace module - -#endif // DEBUG_POWERMETER_DEBUG_JSON_IMPL_HPP diff --git a/modules/YetiDriver/debug_state/debug_jsonImpl.cpp b/modules/YetiDriver/debug_state/debug_jsonImpl.cpp deleted file mode 100644 index 80b7014c8..000000000 --- a/modules/YetiDriver/debug_state/debug_jsonImpl.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2020 - 2021 Pionix GmbH and Contributors to EVerest -#include "debug_jsonImpl.hpp" - -namespace module { -namespace debug_state { - -void debug_jsonImpl::init() { - mod->serial.signalStateUpdate.connect( - [this](const StateUpdate& s) { publish_debug_json(state_update_to_json(s)); }); -} - -void debug_jsonImpl::ready() { -} - -} // namespace debug_state -} // namespace module diff --git a/modules/YetiDriver/debug_state/debug_jsonImpl.hpp b/modules/YetiDriver/debug_state/debug_jsonImpl.hpp deleted file mode 100644 index ce455d7c9..000000000 --- a/modules/YetiDriver/debug_state/debug_jsonImpl.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Pionix GmbH and Contributors to EVerest -#ifndef DEBUG_STATE_DEBUG_JSON_IMPL_HPP -#define DEBUG_STATE_DEBUG_JSON_IMPL_HPP - -// -// AUTO GENERATED - MARKED REGIONS WILL BE KEPT -// template version 3 -// - -#include - -#include "../YetiDriver.hpp" - -// ev@75ac1216-19eb-4182-a85c-820f1fc2c091:v1 -// insert your custom include headers here -// ev@75ac1216-19eb-4182-a85c-820f1fc2c091:v1 - -namespace module { -namespace debug_state { - -struct Conf {}; - -class debug_jsonImpl : public debug_jsonImplBase { -public: - debug_jsonImpl() = delete; - debug_jsonImpl(Everest::ModuleAdapter* ev, const Everest::PtrContainer& mod, Conf& config) : - debug_jsonImplBase(ev, "debug_state"), mod(mod), config(config){}; - - // ev@8ea32d28-373f-4c90-ae5e-b4fcc74e2a61:v1 - // insert your public definitions here - // ev@8ea32d28-373f-4c90-ae5e-b4fcc74e2a61:v1 - -protected: - // no commands defined for this interface - - // ev@d2d1847a-7b88-41dd-ad07-92785f06f5c4:v1 - // insert your protected definitions here - // ev@d2d1847a-7b88-41dd-ad07-92785f06f5c4:v1 - -private: - const Everest::PtrContainer& mod; - const Conf& config; - - virtual void init() override; - virtual void ready() override; - - // ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1 - // insert your private definitions here - // ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1 -}; - -// ev@3d7da0ad-02c2-493d-9920-0bbbd56b9876:v1 -// insert other definitions here -// ev@3d7da0ad-02c2-493d-9920-0bbbd56b9876:v1 - -} // namespace debug_state -} // namespace module - -#endif // DEBUG_STATE_DEBUG_JSON_IMPL_HPP diff --git a/modules/YetiDriver/debug_yeti/debug_jsonImpl.cpp b/modules/YetiDriver/debug_yeti/debug_jsonImpl.cpp deleted file mode 100644 index d35961162..000000000 --- a/modules/YetiDriver/debug_yeti/debug_jsonImpl.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2020 - 2021 Pionix GmbH and Contributors to EVerest -#include "debug_jsonImpl.hpp" - -namespace module { -namespace debug_yeti { - -void debug_jsonImpl::init() { - mod->serial.signalDebugUpdate.connect([this](const DebugUpdate& d) { - auto d_json = debug_update_to_json(d); - mod->mqtt.publish("/external/debug_json", d_json.dump()); - publish_debug_json(d_json); - }); -} - -void debug_jsonImpl::ready() { -} - -} // namespace debug_yeti -} // namespace module diff --git a/modules/YetiDriver/debug_yeti/debug_jsonImpl.hpp b/modules/YetiDriver/debug_yeti/debug_jsonImpl.hpp deleted file mode 100644 index 510a9b543..000000000 --- a/modules/YetiDriver/debug_yeti/debug_jsonImpl.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Pionix GmbH and Contributors to EVerest -#ifndef DEBUG_YETI_DEBUG_JSON_IMPL_HPP -#define DEBUG_YETI_DEBUG_JSON_IMPL_HPP - -// -// AUTO GENERATED - MARKED REGIONS WILL BE KEPT -// template version 3 -// - -#include - -#include "../YetiDriver.hpp" - -// ev@75ac1216-19eb-4182-a85c-820f1fc2c091:v1 -// insert your custom include headers here -// ev@75ac1216-19eb-4182-a85c-820f1fc2c091:v1 - -namespace module { -namespace debug_yeti { - -struct Conf {}; - -class debug_jsonImpl : public debug_jsonImplBase { -public: - debug_jsonImpl() = delete; - debug_jsonImpl(Everest::ModuleAdapter* ev, const Everest::PtrContainer& mod, Conf& config) : - debug_jsonImplBase(ev, "debug_yeti"), mod(mod), config(config){}; - - // ev@8ea32d28-373f-4c90-ae5e-b4fcc74e2a61:v1 - // insert your public definitions here - // ev@8ea32d28-373f-4c90-ae5e-b4fcc74e2a61:v1 - -protected: - // no commands defined for this interface - - // ev@d2d1847a-7b88-41dd-ad07-92785f06f5c4:v1 - // insert your protected definitions here - // ev@d2d1847a-7b88-41dd-ad07-92785f06f5c4:v1 - -private: - const Everest::PtrContainer& mod; - const Conf& config; - - virtual void init() override; - virtual void ready() override; - - // ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1 - // insert your private definitions here - // ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1 -}; - -// ev@3d7da0ad-02c2-493d-9920-0bbbd56b9876:v1 -// insert other definitions here -// ev@3d7da0ad-02c2-493d-9920-0bbbd56b9876:v1 - -} // namespace debug_yeti -} // namespace module - -#endif // DEBUG_YETI_DEBUG_JSON_IMPL_HPP diff --git a/modules/YetiDriver/manifest.yaml b/modules/YetiDriver/manifest.yaml index f37e67259..aaa4de784 100644 --- a/modules/YetiDriver/manifest.yaml +++ b/modules/YetiDriver/manifest.yaml @@ -34,22 +34,11 @@ provides: yeti_extras: interface: yeti_extras description: extra functionality special for Yeti - debug_yeti: - interface: debug_json - description: provides the debug information of the charging driver - debug_powermeter: - interface: debug_json - description: Provides the powermeter as a json object - debug_state: - interface: debug_json - description: Provides the state as a json object - debug_keepalive: - interface: debug_json - description: Provides the keepalive as a json object yeti_simulation_control: interface: yeti_simulation_control description: Interface for the Yeti HIL simulator enable_external_mqtt: true +enable_telemetry: true metadata: license: https://opensource.org/licenses/Apache-2.0 authors: diff --git a/types/evse_manager.yaml b/types/evse_manager.yaml index f04ba1ddd..b9bb88e80 100644 --- a/types/evse_manager.yaml +++ b/types/evse_manager.yaml @@ -138,6 +138,13 @@ types: description: Reason for session start type: string $ref: /evse_manager#/StartSessionReason + logging_path: + description: >- + File system path where additional log files are stored, such as + event logs, raw ethernet dumps, ocpp session logs etc. + Filenames should start with "incomplete-" when they are not finished yet, + this allows other process to wait for the completion after the SessionFinished event. + type: string TransactionStarted: description: Data for the TransactionStarted event type: object