Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add simple EvAPI and extend EvManager with simplistic SoC calculation #891

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b7a727d
Add simple EvAPI and extend EvManager with simplistic SoC calculation
hikinggrass Oct 1, 2024
5fcc16b
Merge branch 'main' into feature/ev-api
hikinggrass Nov 6, 2024
feeb598
cleanup
hikinggrass Nov 6, 2024
921a7f7
Public EvAPI connectors in "ev_connectors" do not use regular API "co…
hikinggrass Nov 6, 2024
ed02b39
Remove session event from ev manager interface since it is not used
hikinggrass Nov 6, 2024
3a919b2
Add EVInfo variable to ev board support interface
hikinggrass Nov 6, 2024
fad56c4
Remove car manufacturer from ev manager interface since it is not used
hikinggrass Nov 6, 2024
038a90e
Re-publish bsp event in exeisting subscriber
hikinggrass Nov 6, 2024
59bc9b9
Re-publish ev info coming from ev board support
hikinggrass Nov 6, 2024
5e9a275
Add description to ev manager provide
hikinggrass Nov 6, 2024
eb4f634
Remove wring years from license header
hikinggrass Nov 6, 2024
81a79d8
Fix naming of charge current/voltage, add AC nominal voltage to config
hikinggrass Nov 6, 2024
d7a67ae
Remove EvAPI from config-sil again
hikinggrass Nov 6, 2024
fcf43bf
Use EvSessionInfo in EvAPI with reduced information compared to API
hikinggrass Nov 6, 2024
5060f53
clang-format
hikinggrass Nov 6, 2024
ba781f8
Refactor EvSessioninfo
hikinggrass Nov 7, 2024
2ec49b9
cleanup + const
hikinggrass Nov 7, 2024
8bc6ab4
Remove unnecessary charge_voltage_v member variables
hikinggrass Nov 7, 2024
536e8fb
make ms factor constexpr
hikinggrass Nov 7, 2024
17c9998
Replace charge_ac and charge_three_phase bool members with charge_mod…
hikinggrass Nov 7, 2024
c679a32
Adding iso_dc_power_on cmd to all node-red config-sil files. With thi…
SebaLukas Nov 14, 2024
a86c62d
Merge remote-tracking branch 'origin/main' into feature/ev-api
hikinggrass Nov 21, 2024
633fc08
fix codacy issue
hikinggrass Nov 21, 2024
a902c7f
clang-format
hikinggrass Nov 21, 2024
5879dd3
Merge branch 'main' into feature/ev-api
Pietfried Dec 3, 2024
a89c6c3
Merge branch 'main' into feature/ev-api
hikinggrass Dec 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/config-sil-dc-d20.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ active_modules:
connector_id: 1
auto_enable: true
auto_exec: false
auto_exec_commands: sleep 3;iso_wait_slac_matched;iso_start_v2g_session DC;iso_wait_pwr_ready;iso_wait_for_stop 15;iso_wait_v2g_session_stopped;unplug;
auto_exec_commands: sleep 3;iso_wait_slac_matched;iso_start_v2g_session DC;iso_wait_pwr_ready;iso_dc_power_on;iso_wait_for_stop 15;iso_wait_v2g_session_stopped;unplug;
dc_target_current: 20
dc_target_voltage: 400
connections:
Expand Down
4 changes: 2 additions & 2 deletions config/nodered/config-sil-dc-bpt-flow.json
Original file line number Diff line number Diff line change
Expand Up @@ -1789,7 +1789,7 @@
"options": [
{
"label": "DC ISO15118-2",
"value": "sleep 1;iso_wait_slac_matched;iso_start_v2g_session DC;iso_wait_pwr_ready;sleep 36000#iso_stop_charging;iso_wait_v2g_session_stopped;unplug#iso_pause_charging;iso_wait_for_resume#iso_start_bcb_toggle 3;iso_wait_pwm_is_running;iso_start_v2g_session DC;iso_wait_pwr_ready;sleep 36000;",
"value": "sleep 1;iso_wait_slac_matched;iso_start_v2g_session DC;iso_wait_pwr_ready;iso_dc_power_on;sleep 36000#iso_stop_charging;iso_wait_v2g_session_stopped;unplug#iso_pause_charging;iso_wait_for_resume#iso_start_bcb_toggle 3;iso_wait_pwm_is_running;iso_start_v2g_session DC;iso_wait_pwr_ready;iso_dc_power_on;sleep 36000;",
"type": "str"
}
],
Expand Down Expand Up @@ -1859,7 +1859,7 @@
"once": true,
"onceDelay": "1",
"topic": "sim_commands",
"payload": "sleep 1;iso_wait_slac_matched;iso_start_v2g_session DC;iso_wait_pwr_ready;sleep 36000#iso_stop_charging;iso_wait_v2g_session_stopped;unplug#iso_pause_charging;iso_wait_for_resume#iso_start_bcb_toggle 3;iso_wait_pwm_is_running;iso_start_v2g_session DC;iso_wait_pwr_ready;sleep 36000;",
"payload": "sleep 1;iso_wait_slac_matched;iso_start_v2g_session DC;iso_wait_pwr_ready;iso_dc_power_on;sleep 36000#iso_stop_charging;iso_wait_v2g_session_stopped;unplug#iso_pause_charging;iso_wait_for_resume#iso_start_bcb_toggle 3;iso_wait_pwm_is_running;iso_start_v2g_session DC;iso_wait_pwr_ready;iso_dc_power_on;sleep 36000;",
"payloadType": "str",
"x": 150,
"y": 1180,
Expand Down
4 changes: 2 additions & 2 deletions config/nodered/config-sil-dc-flow.json
Original file line number Diff line number Diff line change
Expand Up @@ -1789,7 +1789,7 @@
"options": [
{
"label": "DC ISO15118-2",
"value": "sleep 1;iso_wait_slac_matched;iso_start_v2g_session DC;iso_wait_pwr_ready;sleep 36000#iso_stop_charging;iso_wait_v2g_session_stopped;unplug#iso_pause_charging;iso_wait_for_resume#iso_start_bcb_toggle 3;iso_wait_pwm_is_running;iso_start_v2g_session DC;iso_wait_pwr_ready;sleep 36000;",
"value": "sleep 1;iso_wait_slac_matched;iso_start_v2g_session DC;iso_wait_pwr_ready;iso_dc_power_on;sleep 36000#iso_stop_charging;iso_wait_v2g_session_stopped;unplug#iso_pause_charging;iso_wait_for_resume#iso_start_bcb_toggle 3;iso_wait_pwm_is_running;iso_start_v2g_session DC;iso_wait_pwr_ready;iso_dc_power_on;sleep 36000;",
"type": "str"
}
],
Expand Down Expand Up @@ -1859,7 +1859,7 @@
"once": true,
"onceDelay": "1",
"topic": "sim_commands",
"payload": "sleep 1;iso_wait_slac_matched;iso_start_v2g_session DC;iso_wait_pwr_ready;sleep 36000#iso_stop_charging;iso_wait_v2g_session_stopped;unplug#iso_pause_charging;iso_wait_for_resume#iso_start_bcb_toggle 3;iso_wait_pwm_is_running;iso_start_v2g_session DC;iso_wait_pwr_ready;sleep 36000;",
"payload": "sleep 1;iso_wait_slac_matched;iso_start_v2g_session DC;iso_wait_pwr_ready;iso_dc_power_on;sleep 36000#iso_stop_charging;iso_wait_v2g_session_stopped;unplug#iso_pause_charging;iso_wait_for_resume#iso_start_bcb_toggle 3;iso_wait_pwm_is_running;iso_start_v2g_session DC;iso_wait_pwr_ready;iso_dc_power_on;sleep 36000;",
"payloadType": "str",
"x": 150,
"y": 1180,
Expand Down
2 changes: 1 addition & 1 deletion config/nodered/config-sil-two-evse-flow.json
Original file line number Diff line number Diff line change
Expand Up @@ -2141,7 +2141,7 @@
},
{
"label": "DC ISO15118-2",
"value": "sleep 1;iso_wait_slac_matched;iso_start_v2g_session DC;iso_wait_pwr_ready;sleep 36000#iso_stop_charging;iso_wait_v2g_session_stopped;unplug#iso_pause_charging;iso_wait_for_resume#iso_start_bcb_toggle 3;iso_wait_pwm_is_running;iso_start_v2g_session DC;iso_wait_pwr_ready;sleep 36000;",
"value": "sleep 1;iso_wait_slac_matched;iso_start_v2g_session DC;iso_wait_pwr_ready;iso_dc_power_on;sleep 36000#iso_stop_charging;iso_wait_v2g_session_stopped;unplug#iso_pause_charging;iso_wait_for_resume#iso_start_bcb_toggle 3;iso_wait_pwm_is_running;iso_start_v2g_session DC;iso_wait_pwr_ready;iso_dc_power_on;sleep 36000;",
"type": "str"
}
],
Expand Down
6 changes: 5 additions & 1 deletion interfaces/ev_board_support.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,9 @@ vars:
BSP Measurements
type: object
$ref: /board_support_common#/BspMeasurement
ev_info:
description: More details about the EV if available
type: object
$ref: /evse_manager#/EVInfo
errors:
- reference: /errors/generic
- reference: /errors/generic
16 changes: 16 additions & 0 deletions interfaces/ev_manager.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
description: >-
This interface defines the ev manager. An ev manager represents the
charging logic of the ev side
cmds: {}
vars:
bsp_event:
description: >-
Events from CP/Relais
type: object
$ref: /board_support_common#/BspEvent
ev_info:
description: More details about the EV if available
type: object
$ref: /evse_manager#/EVInfo
errors:
- reference: /errors/evse_manager
1 change: 1 addition & 0 deletions modules/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ ev_add_module(API)
ev_add_module(Auth)
ev_add_module(EnergyManager)
ev_add_module(EnergyNode)
ev_add_module(EvAPI)
ev_add_module(EvManager)
ev_add_module(ErrorHistory)
ev_add_module(Evse15118D20)
Expand Down
21 changes: 21 additions & 0 deletions modules/EvAPI/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#
# AUTO GENERATED - MARKED REGIONS WILL BE KEPT
# template version 3
#

# module setup:
# - ${MODULE_NAME}: module name
ev_setup_cpp_module()

# ev@bcc62523-e22b-41d7-ba2f-825b493a3c97:v1
# insert your custom targets and additional config variables here
# ev@bcc62523-e22b-41d7-ba2f-825b493a3c97:v1

target_sources(${MODULE_NAME}
PRIVATE
"main/emptyImpl.cpp"
)

# ev@c55432ab-152c-45a9-9d2e-7281d50c69c3:v1
# insert other things like install cmds etc here
# ev@c55432ab-152c-45a9-9d2e-7281d50c69c3:v1
116 changes: 116 additions & 0 deletions modules/EvAPI/EvAPI.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest
#include "EvAPI.hpp"
#include <utils/date.hpp>

namespace module {

static const auto NOTIFICATION_PERIOD = std::chrono::seconds(1);

void EvSessionInfo::reset() {
std::lock_guard<std::mutex> lock(this->session_info_mutex);
this->event = std::nullopt;
}

void EvSessionInfo::update_event(const types::board_support_common::Event& event) {
std::lock_guard<std::mutex> lock(this->session_info_mutex);
this->event = event;
}

EvSessionInfo::operator std::string() {
std::lock_guard<std::mutex> lock(this->session_info_mutex);

const auto now = date::utc_clock::now();

std::string state = "Unknown";
if (this->event.has_value()) {
state = types::board_support_common::event_to_string(this->event.value());
}

json session_info = json::object({
{"state", state},
{"datetime", Everest::Date::to_rfc3339(now)},
});

return session_info.dump();
}

void EvAPI::init() {
invoke_init(*p_main);

std::vector<std::string> ev_connectors;
std::string var_ev_connectors = this->api_base + "ev_connectors";

for (auto& ev : this->r_ev_manager) {
auto& session_info = this->info.emplace_back(std::make_unique<EvSessionInfo>());
const std::string ev_base = this->api_base + ev->module_id;
ev_connectors.push_back(ev->module_id);

// API variables
const std::string var_base = ev_base + "/var/";

const std::string var_ev_info = var_base + "ev_info";
ev->subscribe_ev_info([this, &ev, var_ev_info](types::evse_manager::EVInfo ev_info) {
json ev_info_json = ev_info;
this->mqtt.publish(var_ev_info, ev_info_json.dump());
});

const std::string var_session_info = var_base + "session_info";
ev->subscribe_bsp_event([this, var_session_info, &session_info](const auto& bsp_event) {
session_info->update_event(bsp_event.event);
this->mqtt.publish(var_session_info, *session_info);
});

const std::string var_datetime = var_base + "datetime";
this->api_threads.push_back(std::thread([this, var_datetime, var_session_info, &session_info]() {
auto next_tick = std::chrono::steady_clock::now();
while (this->running) {
std::string datetime_str = Everest::Date::to_rfc3339(date::utc_clock::now());
this->mqtt.publish(var_datetime, datetime_str);
this->mqtt.publish(var_session_info, *session_info);

next_tick += NOTIFICATION_PERIOD;
std::this_thread::sleep_until(next_tick);
}
}));

// API commands
const std::string cmd_base = ev_base + "/cmd/";
}

this->api_threads.push_back(std::thread([this, var_ev_connectors, ev_connectors]() {
auto next_tick = std::chrono::steady_clock::now();
while (this->running) {
const json ev_connectors_array = ev_connectors;
this->mqtt.publish(var_ev_connectors, ev_connectors_array.dump());

next_tick += NOTIFICATION_PERIOD;
std::this_thread::sleep_until(next_tick);
}
}));
}

void EvAPI::ready() {
invoke_ready(*p_main);

const std::string var_active_errors = this->api_base + "errors/var/active_errors";
this->api_threads.push_back(std::thread([this, var_active_errors]() {
auto next_tick = std::chrono::steady_clock::now();
while (this->running) {
if (not r_error_history.empty()) {
// request active errors
types::error_history::FilterArguments filter;
filter.state_filter = types::error_history::State::Active;
const auto active_errors = r_error_history.at(0)->call_get_errors(filter);
json errors_json = json(active_errors);

// publish
this->mqtt.publish(var_active_errors, errors_json.dump());
}
next_tick += NOTIFICATION_PERIOD;
std::this_thread::sleep_until(next_tick);
}
}));
}

} // namespace module
108 changes: 108 additions & 0 deletions modules/EvAPI/EvAPI.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest
#ifndef EVAPI_HPP
#define EVAPI_HPP

//
// AUTO GENERATED - MARKED REGIONS WILL BE KEPT
// template version 2
//

#include "ld-ev.hpp"

// headers for provided interface implementations
#include <generated/interfaces/empty/Implementation.hpp>

// headers for required interface implementations
#include <generated/interfaces/error_history/Interface.hpp>
#include <generated/interfaces/ev_manager/Interface.hpp>

// ev@4bf81b14-a215-475c-a1d3-0a484ae48918:v1
// insert your custom include headers here
#include <condition_variable>
#include <list>
#include <memory>
#include <mutex>
#include <sstream>

#include <date/date.h>
#include <date/tz.h>

#include <generated/types/board_support_common.hpp>

namespace module {

class LimitDecimalPlaces;

class EvSessionInfo {
public:
EvSessionInfo(){};

void reset();
void update_event(const types::board_support_common::Event& event);

/// \brief Converts this struct into a serialized json object
operator std::string();

private:
std::mutex session_info_mutex;
std::optional<types::board_support_common::Event> event;
};
} // namespace module
// ev@4bf81b14-a215-475c-a1d3-0a484ae48918:v1

namespace module {

struct Conf {};

class EvAPI : public Everest::ModuleBase {
public:
EvAPI() = delete;
EvAPI(const ModuleInfo& info, Everest::MqttProvider& mqtt_provider, std::unique_ptr<emptyImplBase> p_main,
std::vector<std::unique_ptr<ev_managerIntf>> r_ev_manager,
std::vector<std::unique_ptr<error_historyIntf>> r_error_history, Conf& config) :
ModuleBase(info),
mqtt(mqtt_provider),
p_main(std::move(p_main)),
r_ev_manager(std::move(r_ev_manager)),
r_error_history(std::move(r_error_history)),
config(config){};

Everest::MqttProvider& mqtt;
const std::unique_ptr<emptyImplBase> p_main;
const std::vector<std::unique_ptr<ev_managerIntf>> r_ev_manager;
const std::vector<std::unique_ptr<error_historyIntf>> r_error_history;
const Conf& config;

// ev@1fce4c5e-0ab8-41bb-90f7-14277703d2ac:v1
// insert your public definitions here
// ev@1fce4c5e-0ab8-41bb-90f7-14277703d2ac:v1

protected:
// ev@4714b2ab-a24f-4b95-ab81-36439e1478de:v1
// insert your protected definitions here
// ev@4714b2ab-a24f-4b95-ab81-36439e1478de:v1

private:
friend class LdEverest;
void init();
void ready();

// ev@211cfdbe-f69a-4cd6-a4ec-f8aaa3d1b6c8:v1
// insert your private definitions here
std::vector<std::thread> api_threads;

Check notice on line 93 in modules/EvAPI/EvAPI.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/EvAPI/EvAPI.hpp#L93

class member 'EvAPI::api_threads' is never used.
bool running = true;

std::list<std::unique_ptr<EvSessionInfo>> info;

Check notice on line 96 in modules/EvAPI/EvAPI.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/EvAPI/EvAPI.hpp#L96

class member 'EvAPI::info' is never used.

const std::string api_base = "everest_api/";

Check notice on line 98 in modules/EvAPI/EvAPI.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/EvAPI/EvAPI.hpp#L98

class member 'EvAPI::api_base' is never used.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps make this a static inline constexpr std::string_view

// ev@211cfdbe-f69a-4cd6-a4ec-f8aaa3d1b6c8:v1
};

// ev@087e516b-124c-48df-94fb-109508c7cda9:v1
// insert other definitions here
// ev@087e516b-124c-48df-94fb-109508c7cda9:v1

} // namespace module

#endif // EVAPI_HPP
2 changes: 2 additions & 0 deletions modules/EvAPI/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# EvAPI module documentation

Check notice on line 1 in modules/EvAPI/README.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/EvAPI/README.md#L1

Expected: 1; Actual: 0; Below

Check notice on line 1 in modules/EvAPI/README.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/EvAPI/README.md#L1

Expected: [None]; Actual: # EvAPI module documentation
This module is responsible for providing a simple MQTT based API to EVerest internals exposing EvManager related functionality

Check notice on line 2 in modules/EvAPI/README.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/EvAPI/README.md#L2

Expected: 80; Actual: 126

Check notice on line 2 in modules/EvAPI/README.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/EvAPI/README.md#L2

Files should end with a single newline character
16 changes: 16 additions & 0 deletions modules/EvAPI/main/emptyImpl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest

#include "emptyImpl.hpp"

namespace module {
namespace main {

void emptyImpl::init() {
}

void emptyImpl::ready() {
}

} // namespace main
} // namespace module
Loading