Skip to content

Commit

Permalink
add optional location and phsae values
Browse files Browse the repository at this point in the history
Signed-off-by: Soumya Subramanya <[email protected]>

fix rebasign errors

Signed-off-by: Soumya Subramanya <[email protected]>

fix formatting

Signed-off-by: Soumya Subramanya <[email protected]>

intermidiate commit

Signed-off-by: Soumya Subramanya <[email protected]>

PR changes

Signed-off-by: Soumya Subramanya <[email protected]>

remove fake values

Signed-off-by: Soumya Subramanya <[email protected]>

put back optional location and phase values

Signed-off-by: Soumya Subramanya <[email protected]>

remove fake values

Signed-off-by: Soumya Subramanya <[email protected]>

fix formatting

Signed-off-by: Soumya Subramanya <[email protected]>

fix some more PR issues

Signed-off-by: Soumya Subramanya <[email protected]>

revert unexpected changes

Signed-off-by: Soumya Subramanya <[email protected]>

Pr changes
  • Loading branch information
SNSubramanya committed Nov 16, 2023
1 parent 8b026d4 commit f71b134
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 29 deletions.
2 changes: 1 addition & 1 deletion config/v201/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@
"AlignedDataMeasurands": {
"variable_name": "Measurands",
"attributes": {
"Actual": "Energy.Active.Import.Register,Voltage"
"Actual": "Energy.Active.Import.Register,Voltage,Frequency"
}
},
"AlignedDataTxEndedInterval": {
Expand Down
10 changes: 4 additions & 6 deletions include/ocpp/v201/average_meter_values.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,13 @@ class AverageMeterValues {
};
struct MeterValueMeasurands {
MeasurandEnum measurand;
PhaseEnum phase;
std::optional<PhaseEnum> phase; // measurand may or may not have a phase field
std::optional<LocationEnum> location; // measurand may or may not have location field

// Define a comparison operator for the struct
bool operator<(const MeterValueMeasurands& other) const {
// Compare based on name, then age
if (measurand != other.measurand) {
return measurand < other.measurand;
}
return phase < other.phase;

return measurand < other.measurand or location < other.location or phase < other.phase;
}
};

Expand Down
4 changes: 0 additions & 4 deletions include/ocpp/v201/charge_point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,10 +303,6 @@ class ChargePoint : ocpp::ChargingStationBase {
/// \return true if the charge point is offline. std::nullopt if it is online;
bool is_offline();

/// \brief Returns the last present meter value for evseId 0
/// \return MeterValue
MeterValue get_meter_value();

/// \brief Returns customer information based on the given arguments. This function also executes the
/// get_customer_information_callback in case it is present
/// \param customer_certificate Certificate of the customer this request refers to
Expand Down
41 changes: 25 additions & 16 deletions lib/ocpp/v201/average_meter_values.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace v201 {
AverageMeterValues::AverageMeterValues() {
}
void AverageMeterValues::clear_values() {
std::lock_guard<std::mutex> lk(this->avg_meter_value_mutex);
this->aligned_meter_values.clear();
this->averaged_meter_values.sampledValue.clear();
}
Expand All @@ -20,12 +21,12 @@ void AverageMeterValues::set_values(const MeterValue& meter_value) {
this->averaged_meter_values = meter_value;

// avg all the possible measurerands
for (auto element : meter_value.sampledValue) {
for (auto& element : meter_value.sampledValue) {
if (is_avg_meas(element)) {
MeterValueCalc temp = this->aligned_meter_values[{element.measurand.value(), element.phase.value_or(7)}];
MeterValueCalc& temp =
this->aligned_meter_values[{element.measurand.value(), element.phase, element.location}];
temp.sum += element.value;
temp.num_elements++;
this->aligned_meter_values[{element.measurand.value(), element.phase.value()}] = temp;
}
}
}
Expand All @@ -39,23 +40,31 @@ MeterValue AverageMeterValues::retrieve_processed_values() {
void AverageMeterValues::average_meter_value() {
for (auto& element : this->averaged_meter_values.sampledValue) {
if (is_avg_meas(element)) {
element.value = this->aligned_meter_values[{element.measurand.value(), element.phase.value()}].sum /
this->aligned_meter_values[{element.measurand.value(), element.phase.value()}].num_elements;
EVLOG_debug << "Meas: " << element.measurand.value() << " phase: " << element.phase.value() << " sum: "
<< this->aligned_meter_values[{element.measurand.value(), element.phase.value()}].sum
<< " num_ele"
<< this->aligned_meter_values[{element.measurand.value(), element.phase.value()}].num_elements;
EVLOG_debug << "AVG: " << element.value;

MeterValueCalc& temp =
this->aligned_meter_values[{element.measurand.value(), element.phase, element.location}];

element.value = temp.sum / temp.num_elements;

EVLOG_debug << "====== Meas: " << element.measurand.value();
if (element.phase.has_value()) {

EVLOG_debug << " phase: " << element.phase.value();
}
if (element.location.has_value()) {

EVLOG_debug << " loc: " << element.location.value();
}

EVLOG_debug << " sum:" << temp.sum << "#num" << temp.num_elements << "AVG: " << element.value;
}
}
}
bool AverageMeterValues::is_avg_meas(const SampledValue& sample) {

// TODO: check up on location values and how they impact the averaging
if (sample.measurand.has_value()) {
if ((sample.measurand == MeasurandEnum::Current_Import) || (sample.measurand == MeasurandEnum::Voltage) ||
(sample.measurand == MeasurandEnum::Power_Active_Import) || (sample.measurand == MeasurandEnum::Frequency))
return true;
if (sample.measurand.has_value() and (sample.measurand == MeasurandEnum::Current_Import) or
(sample.measurand == MeasurandEnum::Voltage) or (sample.measurand == MeasurandEnum::Power_Active_Import) or
(sample.measurand == MeasurandEnum::Frequency)) {
return true;
} else {
return false;
}
Expand Down
61 changes: 59 additions & 2 deletions lib/ocpp/v201/charge_point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,63 @@ void ChargePoint::on_meter_value(const int32_t evse_id, const MeterValue& meter_
}
}

std::string ChargePoint::get_customer_information(const std::optional<CertificateHashDataType> customer_certificate,
const std::optional<IdToken> id_token,
const std::optional<CiString<64>> customer_identifier) {
std::stringstream s;

// Retrieve possible customer information from application that uses this library
if (this->callbacks.get_customer_information_callback.has_value()) {
s << this->callbacks.get_customer_information_callback.value()(customer_certificate, id_token,
customer_identifier);
}

// Retrieve information from auth cache
if (id_token.has_value()) {
const auto hashed_id_token = utils::generate_token_hash(id_token.value());
const auto entry = this->database_handler->authorization_cache_get_entry(hashed_id_token);
if (entry.has_value()) {
s << "Hashed id_token stored in cache: " + hashed_id_token + "\n";
s << "IdTokenInfo: " << entry.value();
}
}

return s.str();
}

void ChargePoint::clear_customer_information(const std::optional<CertificateHashDataType> customer_certificate,
const std::optional<IdToken> id_token,
const std::optional<CiString<64>> customer_identifier) {
if (this->callbacks.clear_customer_information_callback.has_value()) {
this->callbacks.clear_customer_information_callback.value()(customer_certificate, id_token,
customer_identifier);
}

if (id_token.has_value()) {
const auto hashed_id_token = utils::generate_token_hash(id_token.value());
this->database_handler->authorization_cache_delete_entry(hashed_id_token);
this->update_authorization_cache_size();
}
}

void ChargePoint::configure_message_logging_format(const std::string& message_log_path) {
auto log_formats = this->device_model->get_value<std::string>(ControllerComponentVariables::LogMessagesFormat);
bool log_to_console = log_formats.find("console") != log_formats.npos;
bool detailed_log_to_console = log_formats.find("console_detailed") != log_formats.npos;
bool log_to_file = log_formats.find("log") != log_formats.npos;
bool log_to_html = log_formats.find("html") != log_formats.npos;
bool session_logging = log_formats.find("session_logging") != log_formats.npos;
bool message_callback = log_formats.find("callback") != log_formats.npos;
std::function<void(const std::string& message, MessageDirection direction)> logging_callback = nullptr;

if (message_callback) {
logging_callback = this->callbacks.ocpp_messages_callback.value_or(nullptr);
}

this->logging = std::make_shared<ocpp::MessageLogging>(
!log_formats.empty(), message_log_path, DateTime().to_rfc3339(), log_to_console, detailed_log_to_console,
log_to_file, log_to_html, session_logging, logging_callback);
}
void ChargePoint::on_unavailable(const int32_t evse_id, const int32_t connector_id) {
this->evses.at(evse_id)->submit_event(connector_id, ConnectorEvent::Unavailable);
}
Expand Down Expand Up @@ -1041,8 +1098,8 @@ void ChargePoint::update_aligned_data_interval() {

if (!meter_value.sampledValue.empty()) {
this->meter_values_req(0, std::vector<ocpp::v201::MeterValue>(1, meter_value));
this->aligned_data_evse0.clear_values();
}
this->aligned_data_evse0.clear_values();

for (auto const& [evse_id, evse] : this->evses) {
if (evse->has_active_transaction()) {
Expand All @@ -1059,8 +1116,8 @@ void ChargePoint::update_aligned_data_interval() {
// J01.FR.14 this is the only case where we send a MeterValue.req
this->meter_values_req(evse_id, std::vector<ocpp::v201::MeterValue>(1, meter_value));
// clear the values
evse->clear_idle_meter_values();
}
evse->clear_idle_meter_values();
}
},
interval, std::chrono::floor<date::days>(date::utc_clock::to_sys(date::utc_clock::now())));
Expand Down

0 comments on commit f71b134

Please sign in to comment.