Skip to content

Commit

Permalink
Adapt CableCheck to IEC-23(2023)
Browse files Browse the repository at this point in the history
Refactor power supply dc interface
Add errors to imd interface
Adapt umwc driver to latest firmware
Fix umwc fw update
Add powermeter to umwc
Added Communication Errors to interfaces

Signed-off-by: Cornelius Claussen <[email protected]>
  • Loading branch information
corneliusclaussen committed Jun 13, 2024
1 parent bc621a7 commit 34489f9
Show file tree
Hide file tree
Showing 46 changed files with 695 additions and 398 deletions.
3 changes: 3 additions & 0 deletions config/config-sil-dc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ active_modules:
slac:
module: JsSlacSimulator
imd:
config_implementation:
main:
selftest_success: true
module: IMDSimulator
ev_manager:
module: JsEvManager
Expand Down
2 changes: 1 addition & 1 deletion dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
---
everest-framework:
git: https://github.com/EVerest/everest-framework.git
git_tag: v0.14.0
git_tag: 82117ad705f835e1cf8a3c6d61cd70aa4d44d372
options: ["BUILD_TESTING OFF"]
sigslot:
git: https://github.com/palacaze/sigslot
Expand Down
4 changes: 4 additions & 0 deletions errors/evse_board_support.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,7 @@ errors:
- name: VendorWarning
description: >-
Vendor specific error code. Charging may continue.
- name: CommunicationFault
description: >-
The communication to the hardware or underlying driver is lost or has errors.
20 changes: 20 additions & 0 deletions errors/isolation_monitor.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
description: >-
Errors for Isolation Monitor
Note that actual isolation faults should just be reported as resistance values,
EvseManager will interpret them according to the limits given in the norm and stop charging.
This is only to report device errors to indicate valid isolation resistance measurements etc
are no longer possible.
errors:
- name: DeviceFault
description: The IMD device is not fully functional anymore and cannot be used to monitor the isolation resistance.
- name: CommunicationFault
description: >-
The communication to the hardware or underlying driver is lost or has errors.
- name: VendorError
description: >-
Vendor specific error code. Will stop charging session.
- name: VendorWarning
description: >-
Vendor specific error code. Charging may continue.
6 changes: 6 additions & 0 deletions errors/powermeter.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
description: >-
Errors for Powermeter
errors:
- name: CommunicationFault
description: >-
The communication to the hardware or underlying driver is lost or has errors.
6 changes: 6 additions & 0 deletions errors/system.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
description: >-
Errors for System
errors:
- name: CommunicationFault
description: >-
The communication to the hardware or underlying driver is lost or has errors.
19 changes: 18 additions & 1 deletion interfaces/isolation_monitor.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,25 @@ cmds:
description: >-
Stop recurring measurements. The device should stop to monitor the
isolation resistance and stop publishing the data.
start_self_test:
description: >-
Start self test. This will be done during the CableCheck phase, so a DC voltage will be present
according to IEC 61851-23 (2023). The command should return immediately.
The "self_test_result" variable must be published once the self testing is done.
Note that on many hardware devices this can take a long time (e.g. 20 seconds).
arguments:
test_voltage_V:
description: >-
Specifies the test voltage [V] that is applied on the DC pins during self test.
This can be used to verify the internal voltage measurement of the IMD.
type: number
vars:
IsolationMeasurement:
isolation_measurement:
description: Isolation monitoring measurement results
type: object
$ref: /isolation_monitor#/IsolationMeasurement
self_test_result:
description: Indicates the self test is done and publishes the result. Set "true" for success, "false" for failure.
type: boolean
errors:
- reference: /errors/isolation_monitor
2 changes: 2 additions & 0 deletions interfaces/powermeter.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ vars:
description: Measured dataset
type: object
$ref: /powermeter#/Powermeter
errors:
- reference: /errors/powermeter
2 changes: 2 additions & 0 deletions interfaces/system.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,5 @@ vars:
type: object
$ref: /system#/LogStatus

errors:
- reference: /errors/system
7 changes: 5 additions & 2 deletions modules/EvseManager/Charger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -962,7 +962,8 @@ bool Charger::set_max_current(float c, std::chrono::time_point<date::utc_clock>
// is it still valid?
if (validUntil > date::utc_clock::now()) {
{
std::lock_guard lock(state_machine_mutex);
Everest::scoped_lock_timeout lock(state_machine_mutex,
Everest::MutexDescription::Charger_pause_charging);
shared_context.max_current = c;
shared_context.max_current_valid_until = validUntil;
}
Expand Down Expand Up @@ -1524,7 +1525,9 @@ void Charger::check_soft_over_current() {
// i.e. max_current is in valid range
bool Charger::power_available() {
if (shared_context.max_current_valid_until < date::utc_clock::now()) {
EVLOG_warning << "Power budget expired, falling back to 0.";
EVLOG_warning << "Power budget expired, falling back to 0. Last update: "
<< Everest::Date::to_rfc3339(shared_context.max_current_valid_until)
<< " Now:" << Everest::Date::to_rfc3339(date::utc_clock::now());
if (shared_context.max_current > 0.) {
shared_context.max_current = 0.;
signal_max_current(shared_context.max_current);
Expand Down
2 changes: 1 addition & 1 deletion modules/EvseManager/Charger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ class Charger {
EventQueue<ErrorHandlingEvents> error_handling_event_queue;

// constants
static constexpr float CHARGER_ABSOLUTE_MAX_CURRENT{80.};
static constexpr float CHARGER_ABSOLUTE_MAX_CURRENT{1000.};
constexpr static int LEGACY_WAKEUP_TIMEOUT{30000};
// valid Length of BCB toggles
static constexpr auto TP_EV_VALD_STATE_DURATION_MIN =
Expand Down
95 changes: 93 additions & 2 deletions modules/EvseManager/ErrorHandling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,14 @@ ErrorHandling::ErrorHandling(const std::unique_ptr<evse_board_supportIntf>& _r_b
const std::vector<std::unique_ptr<ISO15118_chargerIntf>>& _r_hlc,
const std::vector<std::unique_ptr<connector_lockIntf>>& _r_connector_lock,
const std::vector<std::unique_ptr<ac_rcdIntf>>& _r_ac_rcd,
const std::unique_ptr<evse_managerImplBase>& _p_evse) :
r_bsp(_r_bsp), r_hlc(_r_hlc), r_connector_lock(_r_connector_lock), r_ac_rcd(_r_ac_rcd), p_evse(_p_evse) {
const std::unique_ptr<evse_managerImplBase>& _p_evse,
const std::vector<std::unique_ptr<isolation_monitorIntf>>& _r_imd) :
r_bsp(_r_bsp),
r_hlc(_r_hlc),
r_connector_lock(_r_connector_lock),
r_ac_rcd(_r_ac_rcd),
p_evse(_p_evse),
r_imd(_r_imd) {

if (r_hlc.size() > 0) {
hlc = true;
Expand Down Expand Up @@ -163,6 +169,52 @@ ErrorHandling::ErrorHandling(const std::unique_ptr<evse_board_supportIntf>& _r_b
}
});
}

// Subscribe to ac_rcd to receive errors from IMD hardware
if (r_imd.size() > 0) {
r_imd[0]->subscribe_all_errors(
[this](const Everest::error::Error& error) {
types::evse_manager::ErrorEnum evse_error{types::evse_manager::ErrorEnum::VendorWarning};
types::evse_manager::Error output_error;
output_error.error_description = error.description;
output_error.error_severity = to_evse_manager_severity(error.severity);

if (modify_error_imd(error, true, evse_error)) {
// signal to charger a new error has been set that prevents charging
output_error.error_code = evse_error;
signal_error(output_error, true);
} else {
// signal an error that does not prevent charging
output_error.error_code = evse_error;
signal_error(output_error, false);
}
},
[this](const Everest::error::Error& error) {
types::evse_manager::ErrorEnum evse_error{types::evse_manager::ErrorEnum::VendorWarning};
types::evse_manager::Error output_error;
output_error.error_description = error.description;
output_error.error_severity = to_evse_manager_severity(error.severity);

if (modify_error_imd(error, false, evse_error)) {
// signal to charger an error has been cleared that prevents charging
output_error.error_code = evse_error;
signal_error_cleared(output_error, true);
} else {
// signal an error cleared that does not prevent charging
output_error.error_code = evse_error;
signal_error_cleared(output_error, false);
}

if (active_errors.all_cleared()) {
// signal to charger that all errors are cleared now
signal_all_errors_cleared();
// clear errors with HLC stack
if (hlc) {
r_hlc[0]->call_reset_error();
}
}
});
}
}

void ErrorHandling::raise_overcurrent_error(const std::string& description) {
Expand Down Expand Up @@ -577,4 +629,43 @@ bool ErrorHandling::modify_error_evse_manager(const std::string& error_type, boo
return true;
};

bool ErrorHandling::modify_error_imd(const Everest::error::Error& error, bool active,
types::evse_manager::ErrorEnum& evse_error) {
const std::string& error_type = error.type;

if (active) {
EVLOG_error << "Raised error " << error_type << ": " << error.description << " (" << error.message << ")";
} else {
EVLOG_info << "Cleared error " << error_type << ": " << error.description << " (" << error.message << ")";
}

if (error_type == "isolation_monitor/DeviceFault") {
active_errors.imd.set(IMDErrors::DeviceFault, active);
evse_error = types::evse_manager::ErrorEnum::IMDFault;
if (hlc && active) {
r_hlc[0]->call_send_error(types::iso15118_charger::EvseError::Error_Malfunction);
}
} else if (error_type == "isolation_monitor/CommunicationFault") {
active_errors.imd.set(IMDErrors::CommunicationFault, active);
evse_error = types::evse_manager::ErrorEnum::IMDFault;
if (hlc && active) {
r_hlc[0]->call_send_error(types::iso15118_charger::EvseError::Error_Malfunction);
}
} else if (error_type == "isolation_monitor/VendorError") {
active_errors.connector_lock.set(ConnectorLockErrors::VendorError, active);
evse_error = types::evse_manager::ErrorEnum::VendorError;
if (hlc && active) {
r_hlc[0]->call_send_error(types::iso15118_charger::EvseError::Error_Malfunction);
}
} else {
// Errors that do not stop charging
if (error_type == "isolation_monitor/VendorWarning") {
evse_error = types::evse_manager::ErrorEnum::VendorWarning;
}
return false;
}
// Error stops charging
return true;
};

} // namespace module
19 changes: 17 additions & 2 deletions modules/EvseManager/ErrorHandling.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <generated/interfaces/evse_board_support/Interface.hpp>
#include <generated/interfaces/evse_manager/Implementation.hpp>
#include <generated/interfaces/evse_manager/Interface.hpp>
#include <generated/interfaces/isolation_monitor/Interface.hpp>
#include <sigslot/signal.hpp>

#include "EnumFlags.hpp"
Expand Down Expand Up @@ -93,14 +94,24 @@ enum class ConnectorLockErrors : std::uint8_t {
last = VendorError
};

enum class IMDErrors : std::uint8_t {
DeviceFault,
CommunicationFault,
VendorWarning,
VendorError,
last = VendorError
};

struct ActiveErrors {
AtomicEnumFlags<BspErrors, std::uint32_t> bsp;
AtomicEnumFlags<EvseManagerErrors, std::uint8_t> evse_manager;
AtomicEnumFlags<AcRcdErrors, std::uint8_t> ac_rcd;
AtomicEnumFlags<ConnectorLockErrors, std::uint8_t> connector_lock;
AtomicEnumFlags<IMDErrors, std::uint8_t> imd;

inline bool all_cleared() {
return bsp.all_reset() && evse_manager.all_reset() && ac_rcd.all_reset() && connector_lock.all_reset();
return bsp.all_reset() && evse_manager.all_reset() && ac_rcd.all_reset() && connector_lock.all_reset() &&
imd.all_reset();
};
};

Expand All @@ -111,7 +122,8 @@ class ErrorHandling {
const std::vector<std::unique_ptr<ISO15118_chargerIntf>>& r_hlc,
const std::vector<std::unique_ptr<connector_lockIntf>>& r_connector_lock,
const std::vector<std::unique_ptr<ac_rcdIntf>>& r_ac_rcd,
const std::unique_ptr<evse_managerImplBase>& _p_evse);
const std::unique_ptr<evse_managerImplBase>& _p_evse,
const std::vector<std::unique_ptr<isolation_monitorIntf>>& _r_imd);

// Signal that one error has been raised. Bool argument is true if it preventing charging.
sigslot::signal<types::evse_manager::Error, bool> signal_error;
Expand All @@ -135,6 +147,7 @@ class ErrorHandling {
const std::vector<std::unique_ptr<connector_lockIntf>>& r_connector_lock;
const std::vector<std::unique_ptr<ac_rcdIntf>>& r_ac_rcd;
const std::unique_ptr<evse_managerImplBase>& p_evse;
const std::vector<std::unique_ptr<isolation_monitorIntf>>& r_imd;

Check notice on line 150 in modules/EvseManager/ErrorHandling.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/EvseManager/ErrorHandling.hpp#L150

class member 'ErrorHandling::r_imd' is never used.

bool modify_error_bsp(const Everest::error::Error& error, bool active, types::evse_manager::ErrorEnum& evse_error);
bool modify_error_connector_lock(const Everest::error::Error& error, bool active,
Expand All @@ -144,6 +157,8 @@ class ErrorHandling {

bool modify_error_evse_manager(const std::string& error_type, bool active,
types::evse_manager::ErrorEnum& evse_error);
bool modify_error_imd(const Everest::error::Error& error, bool active,
types::evse_manager::ErrorEnum& evse_error);
bool hlc{false};

ActiveErrors active_errors;
Expand Down
Loading

0 comments on commit 34489f9

Please sign in to comment.