EVerest / everest-demo

EVerest demo: Dockerized demo with software in the loop simulation
Apache License 2.0
14 stars 14 forks source link

šŸ”Œ šŸ• Experiment with an end to end demo of departure time #64

Closed shankari closed 3 weeks ago

shankari commented 1 month ago

Let's try to build on #44 to include departure time.

EDIT: Simplified scenarios with a single SASchedule. More complex schedules are tracked in #68

High level scenario using AC L2:

[1] This is a real-life example from our recent trip to Arcata. We got to the hotel at around 8pm with a Tesla that was almost empty. We wanted to walk to a concert the next morning (9am - 11am) and then leave at noon rather than deal with parking at the concert venue. The hotel had validated parking in the public lot, but the charger was not smart, and there was no communication between the network and the hotel - the validated permit was a piece of paper to put on the windshield. So we got a notification at around 6am indicating that we would start getting charged for parking since the charging was complete. In this case, the fast charging was actually bad - my husband had to run down to the lot and move the car right after he woke up.

shankari commented 1 month ago

Note that these are still very simple scenarios that are primarily focused on the communication between the station and the car. Concretely, the following scenarios are out of scope:

There are lots of cool things we can do in terms of renegotiation and I fully agree that is where the power in smart charging is. But we are going to take one step at a time and bring in more and more complex functionality into the demo over time, involving the community, and making sure that it is consistent with what stakeholders expect. Note the final scenario here, where the EVSE is not able to meet the requested schedule - is that what we want the EVSE to return?

The goal of these initial demos is to build interest and engagement and help spearhead those conversations.

shankari commented 1 month ago

From a technical perspective, this demo boils down to the following technical tasks:

We will update this issue with progress as we work on these tasks

shankari commented 1 month ago

Looking through the patches that I slapped together quickly, the callback in the core module that handles the set limits or charge profile calls from the CSMS is in modules/OCPP201/OCPP201.cpp which essentially calls

        this->set_external_limits(charging_schedules);                                                       
        this->publish_charging_schedules(charging_schedules);                                                

Couple of other notes:

Going to focus on the EVSE manager's call_set_external_limits for now since:

  1. That seems most promising
  2. At least I can find it!
shankari commented 1 month ago

That looks like it calls through to the local_energy_limitsvariable in the EvseManager - e.g. https://github.com/EVerest/everest-core/blob/4b13b10c4b6ba7ae3edf0a9f7ddfdce274a9332a/modules/EvseManager/EvseManager.cpp#L1084

so here's where the ISO messages are sent out https://github.com/EVerest/everest-core/blob/4b13b10c4b6ba7ae3edf0a9f7ddfdce274a9332a/modules/EvseV2G/iso_server.cpp#L1105

it's a little bit complex, and it looks like we only populate one PMaxSchedule!!

            conn->ctx->evse_v2g_data.evse_sa_schedule_list.SAScheduleTuple.array[0]
                .PMaxSchedule.PMaxScheduleEntry.array[0]
                .RelativeTimeInterval.start = 0;
            conn->ctx->evse_v2g_data.evse_sa_schedule_list.SAScheduleTuple.array[0]
                .PMaxSchedule.PMaxScheduleEntry.array[0]
                .RelativeTimeInterval.duration_isUsed = 1;
            conn->ctx->evse_v2g_data.evse_sa_schedule_list.SAScheduleTuple.array[0]
                .PMaxSchedule.PMaxScheduleEntry.array[0]
                .RelativeTimeInterval.duration = SA_SCHEDULE_DURATION;
            conn->ctx->evse_v2g_data.evse_sa_schedule_list.SAScheduleTuple.array[0]
                .PMaxSchedule.PMaxScheduleEntry.arrayLen = 1;
            conn->ctx->evse_v2g_data.evse_sa_schedule_list.SAScheduleTuple.arrayLen = 1;

Need to add more logs to figure out what is going in here for our current working scenario, and then how we can extend it going forward....

the-bay-kay commented 1 month ago

Tracing through the repos to see where we'll need to add DepartureTime. It helps to know that this is of the type "EVChargeParameterType", and is an optional field of of the AC_EVChargeParameterType. Knowing this, we can go through the repos to figure out what needs changed.

It seems there are three variations of the AC_EVChargeParameterType that are defined:

Tracing through now to see exactly when these EVChargeParameterTypes are used, should shed some light on exactly where changes are needed

the-bay-kay commented 1 month ago

Drawing out a call graph, mostly to make sure I'm not missing anything when tracing through the code. I'll keep the diagrams updated below a fold, if folks are curious about my process. EDIT: Since we can ignore ext-openv2g, I've updated the graph accordingly. See edits below the cut.

Call Graph ![image](https://github.com/user-attachments/assets/b3648cc9-0e2e-4c1b-be45-d17021eda9b4)
shankari commented 1 month ago

ok so the evse_sa_schedule_list is set in modules/EvseV2G/v2g_ctx.cpp, but I only see one entry being set, and I don't see how it is hooked up to the local_energy_limits.

What I see is that there is a MQTT message to set the limits.

# grep -rl set_external_limits modules | grep -v OCPP
modules/API/API.cpp
modules/EvseManager/tests/EvseManagerStub.hpp
modules/EvseManager/evse/evse_managerImpl.cpp
modules/EvseManager/evse/evse_managerImpl.hpp
modules/EnergyNode/energy_grid/energyImpl.hpp
modules/EnergyNode/energy_grid/energyImpl.cpp
modules/EnergyNode/external_limits/external_energy_limitsImpl.cpp
modules/EnergyNode/external_limits/external_energy_limitsImpl.hpp

modules/EnergyNode/external_limits/external_energy_limitsImpl.cpp calls mod->signalExternalLimit(value); in modules/EnergyNode/energy_grid/energyImpl.cpp which calls void energyImpl::set_external_limits

In the EVSE manager, I see

void evse_managerImpl::handle_set_external_limits(types::energy::ExternalLimits& value) {
    mod->updateLocalEnergyLimit(value);
}                 

I do note

    // wait for EnergyManager to assign optimized current on next opimizer run                             

commented in some logs from the energy manager, let's see how the clamping actually gets passed through...

shankari commented 1 month ago
Tracethrough for a single schedule ``` 024-07-16 14:36:13.203502 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 14:36:14.297764 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 14:36:15.392452 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 14:36:16.565686 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 14:36:17.659685 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W ... 2024-07-16 14:37:52.310423 [INFO] ocpp:OCPP201 :: Received SetChargingProfile: { "chargingProfile": { "chargingProfileKind": "Absolute", "chargingProfilePurpose": "TxDefaultProfile", "chargingSchedule": [ { "chargingRateUnit": "A", "chargingSchedulePeriod": [ { "limit": 20.0, "numberPhases": 3, "startPeriod": 0 } ], "duration": 172800, "id": 0, "minChargingRate": 0.0, "startSchedule": "2024-07-16T00:00:00.000Z" } ], "id": 1, "recurrencyKind": "Daily", "stackLevel": 1 }, "evseId": 0 } with messageId: 5659bddd-959d-4c5c-9772-e86dae7e742b 2024-07-16 14:37:52.318355 [WARN] ocpp:OCPP201 module::OCPP201::ready():: :: Received a new Charging Schedules from the CSMS or another actor. 2024-07-16 14:37:52.318528 [INFO] ocpp:OCPP201 :: ProfileId #1 Kind: Absolute 2024-07-16 14:37:52.319332 [INFO] ocpp:OCPP201 :: #1 find_period_at> 2024-07-16T00:00:00.000Z 2024-07-16 14:37:52.319439 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-16T14:37:52.318Z 2024-07-16 14:37:52.319580 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-16T00:00:00.000Z 2024-07-16 14:37:52.319777 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-18T00:00:00.000Z 2024-07-16 14:37:52.319970 [INFO] ocpp:OCPP201 :: PeriodDateTimePair> period: { "limit": 20.0, "numberPhases": 3, "startPeriod": 0 } end_time: 2024-07-18T00:00:00.000Z 2024-07-16 14:37:52.320061 [INFO] ocpp:OCPP201 :: period.has_value() limit = 13800 2024-07-16 14:37:52.320193 [INFO] ocpp:OCPP201 :: period.has_value() stackLevel = 13800 2024-07-16 14:37:52.320363 [INFO] ocpp:OCPP201 :: ProfileId #1 Kind: Absolute 2024-07-16 14:37:52.320489 [INFO] ocpp:OCPP201 :: #1 find_period_at> 2024-07-16T00:00:00.000Z 2024-07-16 14:37:52.320624 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-16T14:37:52.320Z 2024-07-16 14:37:52.320751 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-16T00:00:00.000Z 2024-07-16 14:37:52.320814 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-18T00:00:00.000Z 2024-07-16 14:37:52.320938 [INFO] ocpp:OCPP201 :: PeriodDateTimePair> period: { "limit": 20.0, "numberPhases": 3, "startPeriod": 0 } end_time: 2024-07-18T00:00:00.000Z 2024-07-16 14:37:52.321113 [INFO] ocpp:OCPP201 :: period.has_value() limit = 13800 2024-07-16 14:37:52.321212 [INFO] ocpp:OCPP201 :: period.has_value() stackLevel = 13800 2024-07-16 14:37:52.333571 [WARN] evse_manager_1: virtual void module::evse::evse_managerImpl::handle_set_external_limits(types::energy::ExternalLimits&) :: In the EVSE manager, received external energy limit { "schedule_import": [ { "limits_to_leaves": { "total_power_W": 13800.0 }, "limits_to_root": {}, "timestamp": "2024-07-16T14:37:52.321Z" } ] } 2024-07-16 14:37:52.334509 [WARN] evse_manager_1: bool module::EvseManager::updateLocalEnergyLimit(types::energy::ExternalLimits) :: External limits are lower, applying them { "schedule_import": [ { "limits_to_leaves": { "total_power_W": 13800.0 }, "limits_to_root": {}, "timestamp": "2024-07-16T14:37:52.321Z" } ] } 2024-07-16 14:37:52.368285 [INFO] ocpp:OCPP201 :: Received profile validity: Validsetting response to { "status": "Accepted" } 2024-07-16 14:37:53.115735 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 14:37:54.252971 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 14:39:16.416786 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 14:39:17.550394 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 14:39:18.684171 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 14:39:19.853086 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 14:40:00.381452 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "2B978B6FEFEFE5B7"}, "Body": {"ChargeParameterDiscoveryReq": {"RequestedEnergyTransferMode": "AC_three_phase_core", "AC_EVChargeParameter": {"DepartureTime": 0, "EAmount": {"Value": 60, "Multiplier": 0, "Unit": "Wh"}, "EVMaxVoltage": {"Value": 400, "Multiplier": 0, "Unit": "V"}, "EVMaxCurrent": {"Value": 32000, "Multiplier": -3, "Unit": "A"}, "EVMinCurrent": {"Value": 10, "Multiplier": 0, "Unit": "A"}}}}}} 2024-07-16 14:40:01.073155 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Sent ChargeParameterDiscoveryReq2024-07-16 14:40:01.073178 [INFO] iso15118_charge :: Parameter-phase started 2024-07-16 14:40:01.073333 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Entered state ChargeParameterDiscovery 2024-07-16 14:40:01.075056 [INFO] iso15118_charge :: Selected energy transfer mode: AC_three_phase_core 2024-07-16 14:40:01.157703 [INFO] evse_manager_1: :: CAR ISO V2G ChargeParameterDiscoveryReq 2024-07-16 14:40:01.230939 [INFO] evse_manager_1: :: EVSE ISO V2G ChargeParameterDiscoveryRes 2024-07-16 14:40:01.248810 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 14:40:01.293935 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"2B978B6FEFEFE5B7"},"Body":{"ChargeParameterDiscoveryRes":{"ResponseCode":"OK","EVSEProcessing":"Finished","SAScheduleList":{"SAScheduleTuple":[{"SAScheduleTupleID":1,"PMaxSchedule":{"PMaxScheduleEntry":[{"RelativeTimeInterval":{"start":0,"duration":86400},"PMax":{"Multiplier":0,"Unit":"W","Value":13800}}]}}]},"AC_EVSEChargeParameter":{"AC_EVSEStatus":{"NotificationMaxDelay":0,"EVSENotification":"None","RCD":false},"EVSENominalVoltage":{"Multiplier":-1,"Unit":"V","Value":2300},"EVSEMaxCurrent":{"Multiplier":-1,"Unit":"A","Value":200}}}}}} ```
Multi schedule ``` { "id": 1, "chargingProfileKind": "Absolute", "chargingProfilePurpose": "TxDefaultProfile", "chargingSchedule": [ { "id": 0, "chargingRateUnit": "A", "chargingSchedulePeriod": [ { "limit": 3.0, "numberPhases": 3, "startPeriod": 0 } ], "duration": 3600, "minChargingRate": 0.0, "startSchedule": "2024-07-16T00:00:00.000Z" }, { "id": 1, "chargingRateUnit": "A", "chargingSchedulePeriod": [ { "limit": 5.0, "numberPhases": 3, "startPeriod": 0 } ], "duration": 3600, "minChargingRate": 0.0, "startSchedule": "2024-07-16T01:00:00.000Z" }, { "id": 3, "chargingRateUnit": "A", "chargingSchedulePeriod": [ { "limit": 2.0, "numberPhases": 3, "startPeriod": 0 } ], "duration": 3600, "minChargingRate": 0.0, "startSchedule": "2024-07-16T00:02:00.000Z" } ], "recurrencyKind": "Daily", "stackLevel": 1 } ```

Fails with

2024-07-16 15:11:25.227606 [WARN] ocpp:OCPP201    ocpp::DateTime ocpp::v201::SmartChargingHandler::get_next_temp_time(ocpp::DateTime, const std::vector<ocpp::v201::ChargingProfile>&, int32_t) :: Charging Profiles with more than one ChargingSchedule are not currently supported.
shankari commented 1 month ago
New multi-schedule with multiple periods in the day ``` 2024-07-16 15:15:28.531018 [INFO] ocpp:OCPP201 :: Received SetChargingProfile: { "chargingProfile": { "chargingProfileKind": "Absolute", "chargingProfilePurpose": "TxDefaultProfile", "chargingSchedule": [ { "chargingRateUnit": "A", "chargingSchedulePeriod": [ { "limit": 3.0, "numberPhases": 3, "startPeriod": 0 }, { "limit": 5.0, "numberPhases": 3, "startPeriod": 3600 }, { "limit": 2.0, "numberPhases": 3, "startPeriod": 7200 } ], "duration": 86400, "id": 0, "minChargingRate": 0.0, "startSchedule": "2024-07-16T00:00:00.000Z" } ], "id": 1, "recurrencyKind": "Daily", "stackLevel": 1 }, "evseId": 0 } with messageId: 8077d06f-1e92-4efd-870b-f218202f027e 2024-07-16 15:15:28.532022 [WARN] ocpp:OCPP201 module::OCPP201::ready():: :: Received a new Charging Schedules from the CSMS or another actor. 2024-07-16 15:15:28.532131 [INFO] ocpp:OCPP201 :: ProfileId #1 Kind: Absolute 2024-07-16 15:15:28.532215 [INFO] ocpp:OCPP201 :: #1 find_period_at> 2024-07-16T00:00:00.000Z 2024-07-16 15:15:28.532313 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-16T15:15:28.532Z 2024-07-16 15:15:28.532505 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-16T00:00:00.000Z 2024-07-16 15:15:28.532597 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-16T01:00:00.000Z 2024-07-16 15:15:28.532651 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-16T15:15:28.532Z 2024-07-16 15:15:28.532685 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-16T01:00:00.000Z 2024-07-16 15:15:28.532717 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-16T02:00:00.000Z 2024-07-16 15:15:28.532749 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-16T15:15:28.532Z 2024-07-16 15:15:28.532779 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-16T02:00:00.000Z 2024-07-16 15:15:28.532809 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-17T00:00:00.000Z 2024-07-16 15:15:28.533136 [INFO] ocpp:OCPP201 :: PeriodDateTimePair> period: { "limit": 2.0, "numberPhases": 3, "startPeriod": 7200 } end_time: 2024-07-17T00:00:00.000Z 2024-07-16 15:15:28.533251 [INFO] ocpp:OCPP201 :: period.has_value() limit = 1380 2024-07-16 15:15:28.533369 [INFO] ocpp:OCPP201 :: period.has_value() stackLevel = 1380 2024-07-16 15:15:28.533584 [INFO] ocpp:OCPP201 :: ProfileId #1 Kind: Absolute 2024-07-16 15:15:28.533635 [INFO] ocpp:OCPP201 :: #1 find_period_at> 2024-07-16T00:00:00.000Z 2024-07-16 15:15:28.533741 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-16T15:15:28.533Z 2024-07-16 15:15:28.533792 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-16T00:00:00.000Z 2024-07-16 15:15:28.533867 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-16T01:00:00.000Z 2024-07-16 15:15:28.533945 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-16T15:15:28.533Z 2024-07-16 15:15:28.534005 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-16T01:00:00.000Z 2024-07-16 15:15:28.534089 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-16T02:00:00.000Z 2024-07-16 15:15:28.534194 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-16T15:15:28.533Z 2024-07-16 15:15:28.534295 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-16T02:00:00.000Z 2024-07-16 15:15:28.534608 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-17T00:00:00.000Z 2024-07-16 15:15:28.534848 [INFO] ocpp:OCPP201 :: PeriodDateTimePair> period: { "limit": 2.0, "numberPhases": 3, "startPeriod": 7200 } end_time: 2024-07-17T00:00:00.000Z 2024-07-16 15:15:28.534933 [INFO] ocpp:OCPP201 :: period.has_value() limit = 1380 2024-07-16 15:15:28.534985 [INFO] ocpp:OCPP201 :: period.has_value() stackLevel = 1380 2024-07-16 15:15:28.538997 [WARN] evse_manager_1: virtual void module::evse::evse_managerImpl::handle_set_external_limits(types::energy::ExternalLimits&) :: In the EVSE manager, received external energy limit { "schedule_import": [ { "limits_to_leaves": { "total_power_W": 1380.0 }, "limits_to_root": {}, "timestamp": "2024-07-16T15:15:28.535Z" } ] } 2024-07-16 15:15:28.539186 [WARN] evse_manager_1: bool module::EvseManager::updateLocalEnergyLimit(types::energy::ExternalLimits) :: External limits are lower, applying them { "schedule_import": [ { "limits_to_leaves": { "total_power_W": 1380.0 }, "limits_to_root": {}, "timestamp": "2024-07-16T15:15:28.535Z" } ] } 2024-07-16 15:15:28.578860 [INFO] ocpp:OCPP201 :: Received profile validity: Validsetting response to { "status": "Accepted" } 2024-07-16 15:15:28.597725 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 15:15:29.649187 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 0A 0W 2024-07-16 15:15:30.746741 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 0A 0W 2024-07-16 15:15:31.866096 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 0A 0W ```

But now the limits are set to 0A. Why? It looks like it finds the correct period. I bet it is because the current is below the min (should add logs to verify). But for now, we can just bump up the amps....

shankari commented 1 month ago
Bumping up the amps by x 10, we get the correct limits, but the last period is the one that is valid. ``` 2024-07-16 15:21:51.526192 [INFO] ocpp:OCPP201 :: period.has_value() limit = 13800 2024-07-16 15:21:51.526250 [INFO] ocpp:OCPP201 :: period.has_value() stackLevel = 13800 2024-07-16 15:21:51.526477 [INFO] ocpp:OCPP201 :: ProfileId #1 Kind: Absolute 2024-07-16 15:21:51.526591 [INFO] ocpp:OCPP201 :: #1 find_period_at> 2024-07-16T00:00:00.000Z 2024-07-16 15:21:51.527036 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-16T15:21:51.526Z 2024-07-16 15:21:51.527216 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-16T00:00:00.000Z 2024-07-16 15:21:51.527319 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-16T01:00:00.000Z 2024-07-16 15:21:51.527469 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-16T15:21:51.526Z 2024-07-16 15:21:51.527539 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-16T01:00:00.000Z 2024-07-16 15:21:51.527598 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-16T02:00:00.000Z 2024-07-16 15:21:51.527666 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-16T15:21:51.526Z 2024-07-16 15:21:51.527724 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-16T02:00:00.000Z 2024-07-16 15:21:51.527968 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-17T00:00:00.000Z 2024-07-16 15:21:51.528132 [INFO] ocpp:OCPP201 :: PeriodDateTimePair> period: { "limit": 20.0, "numberPhases": 3, "startPeriod": 7200 } end_time: 2024-07-17T00:00:00.000Z 2024-07-16 15:21:51.528224 [INFO] ocpp:OCPP201 :: period.has_value() limit = 13800 2024-07-16 15:21:51.528338 [INFO] ocpp:OCPP201 :: period.has_value() stackLevel = 13800 2024-07-16 15:21:51.571891 [WARN] evse_manager_1: virtual void module::evse::evse_managerImpl::handle_set_external_limits(types::energy::ExternalLimits&) :: In the EVSE manager, received external energy limit { "schedule_import": [ { "limits_to_leaves": { "total_power_W": 13800.0 }, "limits_to_root": {}, "timestamp": "2024-07-16T15:21:51.528Z" } ] } 2024-07-16 15:21:51.572105 [WARN] evse_manager_1: bool module::EvseManager::updateLocalEnergyLimit(types::energy::ExternalLimits) :: External limits are lower, applying them { "schedule_import": [ { "limits_to_leaves": { "total_power_W": 13800.0 }, "limits_to_root": {}, "timestamp": "2024-07-16T15:21:51.528Z" } ] } 2024-07-16 15:21:51.575528 [INFO] ocpp:OCPP201 :: Received profile validity: Validsetting response to { "status": "Accepted" } 2024-07-16 15:21:51.702667 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 0A 0W 2024-07-16 15:21:52.798328 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:21:53.895156 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:21:54.989252 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:21:56.125233 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:21:57.224404 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:21:58.360300 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:21:59.418406 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:00.591170 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:01.687073 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:02.780232 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:03.833069 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:04.968330 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:06.106089 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:07.162219 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:08.219222 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:09.352950 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:10.446061 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:11.608998 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:12.702205 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:13.757494 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:14.811088 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:15.905048 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:16.999038 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:18.093100 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:19.188310 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:20.282066 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:21.376391 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:22.470083 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:23.566002 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:24.675210 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:25.730184 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:26.828686 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W 2024-07-16 15:22:27.967246 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 20A 13800W ```
Let's adjust the start time so that we can have multiple future schedules ``` 2024-07-16 15:25:43.591721 [INFO] ocpp:OCPP201 :: ProfileId #1 Kind: Absolute 2024-07-16 15:25:43.591783 [INFO] ocpp:OCPP201 :: #1 find_period_at> 2024-07-16T15:00:00.000Z 2024-07-16 15:25:43.592335 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-16T15:25:43.591Z 2024-07-16 15:25:43.592509 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-16T15:00:00.000Z 2024-07-16 15:25:43.592693 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-16T16:00:00.000Z 2024-07-16 15:25:43.592939 [INFO] ocpp:OCPP201 :: PeriodDateTimePair> period: { "limit": 10.0, "numberPhases": 3, "startPeriod": 0 } end_time: 2024-07-16T16:00:00.000Z 2024-07-16 15:25:43.593056 [INFO] ocpp:OCPP201 :: period.has_value() limit = 6900 2024-07-16 15:25:43.593236 [INFO] ocpp:OCPP201 :: period.has_value() stackLevel = 6900 2024-07-16 15:25:43.593441 [INFO] ocpp:OCPP201 :: ProfileId #1 Kind: Absolute 2024-07-16 15:25:43.593561 [INFO] ocpp:OCPP201 :: #1 find_period_at> 2024-07-16T15:00:00.000Z 2024-07-16 15:25:43.593712 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-16T15:25:43.593Z 2024-07-16 15:25:43.593909 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-16T15:00:00.000Z 2024-07-16 15:25:43.594291 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-16T16:00:00.000Z 2024-07-16 15:25:43.594567 [INFO] ocpp:OCPP201 :: PeriodDateTimePair> period: { "limit": 10.0, "numberPhases": 3, "startPeriod": 0 } end_time: 2024-07-16T16:00:00.000Z 2024-07-16 15:25:43.594667 [INFO] ocpp:OCPP201 :: period.has_value() limit = 6900 2024-07-16 15:25:43.594751 [INFO] ocpp:OCPP201 :: period.has_value() stackLevel = 6900 2024-07-16 15:25:43.597813 [WARN] evse_manager_1: virtual void module::evse::evse_managerImpl::handle_set_external_limits(types::energy::ExternalLimits&) :: In the EVSE manager, received external energy limit { "schedule_import": [ { "limits_to_leaves": { "total_power_W": 6900.0 }, "limits_to_root": {}, "timestamp": "2024-07-16T15:25:43.594Z" } ] } 2024-07-16 15:25:43.598107 [WARN] evse_manager_1: bool module::EvseManager::updateLocalEnergyLimit(types::energy::ExternalLimits) :: External limits are lower, applying them { "schedule_import": [ { "limits_to_leaves": { "total_power_W": 6900.0 }, "limits_to_root": {}, "timestamp": "2024-07-16T15:25:43.594Z" } ] } 2024-07-16 15:25:43.638801 [INFO] ocpp:OCPP201 :: Received profile validity: Validsetting response to { "status": "Accepted" } 2024-07-16 15:25:43.696389 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 15:25:44.802562 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 10A 6900W 2024-07-16 15:25:45.948495 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 10A 6900W 2024-07-16 15:25:47.085433 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 10A 6900W 2024-07-16 15:25:48.223086 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 10A 6900W ```
Now to plug in the car again ``` 2024-07-16 15:27:06.990023 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "42A1CFBD7F36EF7D"}, "Body": {"ChargeParameterDiscoveryReq": {"RequestedEnergyTransferMode": "AC_three_phase_core", "AC_EVChargeParameter": {"DepartureTime": 0, "EAmount": {"Value": 60, "Multiplier": 0, "Unit": "Wh"}, "EVMaxVoltage": {"Value": 400, "Multiplier": 0, "Unit": "V"}, "EVMaxCurrent": {"Value": 32000, "Multiplier": -3, "Unit": "A"}, "EVMinCurrent": {"Value": 10, "Multiplier": 0, "Unit": "A"}}}}}} 2024-07-16 15:27:07.580390 [INFO] iso15118_charge :: Parameter-phase started2024-07-16 15:27:07.580374 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Sent ChargeParameterDiscoveryReq 2024-07-16 15:27:07.580664 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Entered state ChargeParameterDiscovery 2024-07-16 15:27:07.582664 [INFO] iso15118_charge :: Selected energy transfer mode: AC_three_phase_core 2024-07-16 15:27:07.624863 [INFO] evse_manager_1: :: CAR ISO V2G ChargeParameterDiscoveryReq 2024-07-16 15:27:07.626222 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 10A 6900W 2024-07-16 15:27:07.717601 [INFO] evse_manager_1: :: EVSE ISO V2G ChargeParameterDiscoveryRes 2024-07-16 15:27:08.142249 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"42A1CFBD7F36EF7D"},"Body":{"ChargeParameterDiscoveryRes":{"ResponseCode":"OK","EVSEProcessing":"Finished","SAScheduleList":{"SAScheduleTuple":[{"SAScheduleTupleID":1,"PMaxSchedule":{"PMaxScheduleEntry":[{"RelativeTimeInterval":{"start":0,"duration":86400},"PMax":{"Multiplier":0,"Unit":"W","Value":6900}}]}}]},"AC_EVSEChargeParameter":{"AC_EVSEStatus":{"NotificationMaxDelay":0,"EVSENotification":"None","RCD":false},"EVSENominalVoltage":{"Multiplier":-1,"Unit":"V","Value":2300},"EVSEMaxCurrent":{"Multiplier":-1,"Unit":"A","Value":100}}}}}} ```

Again, we get a single SA schedule with 6900W for one day (86400 duration). But we are only requesting 60 Wh. Let's bump that up to 60 kWh and see what happens.

the-bay-kay commented 1 month ago

Keeping a tally of the locations I'll need to add DepartureTime. First, just consolidating the iso requirements for my ease of reading...

15118-2 `DepartureTime` requirements > Figure 5 on page 15 gives a helpful seq. diagram for the ChargeParameterDiscoveryReq(), the message carrying the ChargeParameterType (DepartureTime) payload. Where implementation is needed: - [ ] EVCC Resumes previous paused V2G Communication [V2G2-742] Constraints: - [x] If no DepartureTime, the extension should not be included [V2G2-215] (Presumably, this is what we're already doing) - [ ] Sum of individual intervals in PMaxSchedule & SalesTariff in `ChargeParamDiscoveryRes` shall match the period indicated in `DepartureTime` ChargeParameterDisoveryReq [V2G2-303] - [x] If no DepartureTime, sum of PMaxSchedule intervals & SalesTariff shall be >= 24 hours [V2G-304] (Likewise, assuming this is the current behavior. Will check later.) - [ ] If the number of SalesTariffEntry elements or PMaxSchedule elements does not cover the entire period of time until Departuretime, the Target Setting EAmmount has not been met and communication has not been finished. It is the responsibility of the EVCC to request a new SAScheduleList via another ChargeParameterDiscoveryReq type as soon as the last SalesTariffEntry / PMaxSchedule entry becomes active[V2G-305] - [ ] If #(SalesTariffEntry) is not covering until DepartureTime, it is responsibility of EVCC to optimize the schedule

With the info above, it seems we need to send & handle the DepartureTime whenever a ChargeParameterDiscoverReq is being sent. As I understand it, this will occur (i) when a new session has been started, and (ii) when a session has been resumed after a pause.

Now to hunt down these occurrences in PyEVJosev and JsEvManager. At a glance, the JsEvManager changes seem like they will be somewhat straightforward...

shankari commented 1 month ago

Changing the defaults in build/dist/libexec/everest/3rd_party/josev/iso15118/secc/states/iso15118_2_states.py to bump up the power and set the departure time to see if it makes a difference...

            p_e_amount: float = e_amount.value * pow(10, e_amount.multiplier + 3)

        departure_time = (                                    
            ev_data_context.departure_time if ev_data_context.departure_time else 21600
        )                                                  
Pnc is now stuck in Authorization Req/Res ``` 2024-07-16 16:03:05.849775 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=http://www.w3.org/2000/09/xmldsig#): {"SignedInfo": {"CanonicalizationMethod": {"Algorithm": "http://www.w3.org/TR/canonical-exi/"}, "SignatureMethod": {"Algorithm": "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"}, "Reference": [{"Transforms": {"Transform": [{"Algorithm": "http://www.w3.org/TR/canonical-exi/"}]}, "DigestMethod": {"Algorithm": "http://www.w3.org/2001/04/xmlenc#sha256"}, "DigestValue": "tQU4I0aGz6D6qZtjjNpeLmZV70/6/jWN+Ew7B9cTVq8=", "URI": "#id1"}]}} 2024-07-16 16:03:06.381961 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "1BFEFA7BFFFFF7BB", "Signature": {"SignedInfo": {"CanonicalizationMethod": {"Algorithm": "http://www.w3.org/TR/canonical-exi/"}, "SignatureMethod": {"Algorithm": "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"}, "Reference": [{"Transforms": {"Transform": [{"Algorithm": "http://www.w3.org/TR/canonical-exi/"}]}, "DigestMethod": {"Algorithm": "http://www.w3.org/2001/04/xmlenc#sha256"}, "DigestValue": "tQU4I0aGz6D6qZtjjNpeLmZV70/6/jWN+Ew7B9cTVq8=", "URI": "#id1"}]}, "SignatureValue": {"value": "NmKlHwYsVCQuXgV0tDIzZbNLuDFIMIKMKH1u9Ir3/rR42dqVSB5TXeQHuX97qQOB+MHRPFgTx/bUAPk4Q0xlgw=="}}}, "Body": {"AuthorizationReq": {"Id": "id1", "GenChallenge": "ajHCFwWA+Q8gyoax/ZYwpw=="}}}} 2024-07-16 16:03:06.502111 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 16:03:07.678986 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 16:03:07.763007 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Sent AuthorizationReq 2024-07-16 16:03:07.763968 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Entered state Authorization 2024-07-16 16:03:07.864598 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: Response message (type 6) not configured within 98 ms (took 102 ms) 2024-07-16 16:03:07.869701 [INFO] evse_manager_1: :: CAR ISO V2G AuthorizationReq 2024-07-16 16:03:07.873175 [INFO] evse_manager_1: :: EVSE ISO V2G AuthorizationRes 2024-07-16 16:03:08.657887 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"1BFEFA7BFFFFF7BB"},"Body":{"AuthorizationRes":{"ResponseCode":"OK","EVSEProcessing":"Ongoing"}}}} 2024-07-16 16:03:08.660089 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: AuthorizationRes received 2024-07-16 16:03:08.665176 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "1BFEFA7BFFFFF7BB"}, "Body": {"AuthorizationReq": {}}}} 2024-07-16 16:03:08.840837 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 16:03:09.604521 [WARN] ocpp:OCPP201 void ocpp::MessageQueue::handle_timeout_or_callerror(const std::optional >&) [with M = ocpp::v201::MessageType] :: Message timeout for: TransactionEvent (eeee3f10-332c-49f8-ae6d-d3e8fc46fb87) 2024-07-16 16:03:09.604837 [WARN] ocpp:OCPP201 void ocpp::MessageQueue::handle_timeout_or_callerror(const std::optional >&) [with M = ocpp::v201::MessageType] :: Message is transaction related and will therefore be sent again 2024-07-16 16:03:09.611485 [WARN] ocpp:OCPP201 void ocpp::MessageQueue::handle_timeout_or_callerror(const std::optional >&) [with M = ocpp::v201::MessageType] :: Attempt: 2/5 will be sent at 2024-07-16T15:46:02.225Z 2024-07-16 16:03:09.861305 [INFO] ocpp:OCPP201 :: Unsolicited client close reason: read limited at 32769 bytes close code: 1009 2024-07-16 16:03:09.861784 [ERRO] ocpp:OCPP201 void ocpp::WebsocketTlsTPM::on_conn_fail() :: OCPP client connection to server failed 2024-07-16 16:03:09.862404 [INFO] ocpp:OCPP201 :: Reconnecting in: 3000ms, attempt: 1 2024-07-16 16:03:10.007064 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 16:03:10.238957 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Sent AuthorizationReq 2024-07-16 16:03:10.242011 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Entered state Authorization 2024-07-16 16:03:10.249295 [INFO] evse_manager_1: :: CAR ISO V2G AuthorizationReq 2024-07-16 16:03:10.379931 [INFO] evse_manager_1: :: EVSE ISO V2G AuthorizationRes 2024-07-16 16:03:11.139473 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"1BFEFA7BFFFFF7BB"},"Body":{"AuthorizationRes":{"ResponseCode":"OK","EVSEProcessing":"Ongoing"}}}} 2024-07-16 16:03:11.143823 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: AuthorizationRes received 2024-07-16 16:03:11.145803 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "1BFEFA7BFFFFF7BB"}, "Body": {"AuthorizationReq": {}}}} 2024-07-16 16:03:11.205276 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 16:03:12.418666 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 16:03:12.689119 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Sent AuthorizationReq 2024-07-16 16:03:12.690228 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Entered state Authorization 2024-07-16 16:03:12.695324 [INFO] evse_manager_1: :: CAR ISO V2G AuthorizationReq 2024-07-16 16:03:12.826622 [INFO] evse_manager_1: :: EVSE ISO V2G AuthorizationRes 2024-07-16 16:03:12.863556 [INFO] ocpp:OCPP201 :: Connecting to uri: wss://host.docker.internal/ws/cp001 with security-profile 3 2024-07-16 16:03:12.914853 [INFO] evse_security:E :: Requesting leaf certificate info: CSMS 2024-07-16 16:03:12.924662 [INFO] evse_security:E :: Found valid leaf: ["/ext/source/build/dist/etc/everest/certs/client/csms/CSMS_LEAF.pem"] 2024-07-16 16:03:12.932135 [WARN] evse_security:E evse_security::GetCertificateInfoResult evse_security::EvseSecurity::get_leaf_certificate_info_internal(evse_security::LeafCertificateType, evse_security::EncodingFormat, bool) :: CSMS leaf requires full bundle, but full bundle not found at path: "/ext/source/build/dist/etc/everest/certs/client/csms" 2024-07-16 16:03:12.991871 [INFO] evse_security:E :: Building new certificate hierarchy! 2024-07-16 16:03:13.066321 [INFO] evse_security:E :: Requesting certificate file: [CSMS] file:"/ext/source/build/dist/etc/everest/certs/ca/v2g/V2G_ROOT_CA.pem" 2024-07-16 16:03:13.103639 [INFO] ocpp:OCPP201 :: Loading CA csms bundle to verify server certificate: /ext/source/build/dist/etc/everest/certs/ca/v2g/V2G_ROOT_CA.pem 2024-07-16 16:03:13.408975 [INFO] ocpp:OCPP201 :: LWS connect with info port: [443] address: [host.docker.internal] path: [/ws/cp001] protocol: [ocpp2.0.1] 2024-07-16 16:03:13.518293 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 16:03:13.588124 [INFO] ocpp:OCPP201 :: OCPP client successfully connected to server 2024-07-16 16:03:13.589208 [WARN] ocpp:OCPP201 int ocpp::callback_minimal(lws*, lws_callback_reasons, void*, void*, size_t) :: callback_minimal called, but data->owner is nullptr. Reason: 80 2024-07-16 16:03:13.593802 [WARN] ocpp:OCPP201 int ocpp::callback_minimal(lws*, lws_callback_reasons, void*, void*, size_t) :: callback_minimal called, but data->owner is nullptr. Reason: 75 2024-07-16 16:03:13.595700 [WARN] ocpp:OCPP201 int ocpp::callback_minimal(lws*, lws_callback_reasons, void*, void*, size_t) :: callback_minimal called, but data->owner is nullptr. Reason: 30 2024-07-16 16:03:13.835819 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"1BFEFA7BFFFFF7BB"},"Body":{"AuthorizationRes":{"ResponseCode":"OK","EVSEProcessing":"Ongoing"}}}} 2024-07-16 16:03:13.837436 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: AuthorizationRes received 2024-07-16 16:03:13.839237 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "1BFEFA7BFFFFF7BB"}, "Body": {"AuthorizationReq": {}}}} 2024-07-16 16:03:14.749933 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 16:03:15.557712 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Sent AuthorizationReq 2024-07-16 16:03:15.558783 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Entered state Authorization 2024-07-16 16:03:15.583010 [INFO] evse_manager_1: :: CAR ISO V2G AuthorizationReq 2024-07-16 16:03:15.669615 [INFO] evse_manager_1: :: EVSE ISO V2G AuthorizationRes 2024-07-16 16:03:15.873702 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 16:03:16.496160 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"1BFEFA7BFFFFF7BB"},"Body":{"AuthorizationRes":{"ResponseCode":"OK","EVSEProcessing":"Ongoing"}}}} 2024-07-16 16:03:16.510183 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: AuthorizationRes received 2024-07-16 16:03:16.514556 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "1BFEFA7BFFFFF7BB"}, "Body": {"AuthorizationReq": {}}}} 2024-07-16 16:03:17.134916 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 16:03:17.416761 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Sent AuthorizationReq 2024-07-16 16:03:17.419487 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Entered state Authorization 2024-07-16 16:03:17.434044 [INFO] evse_manager_1: :: CAR ISO V2G AuthorizationReq 2024-07-16 16:03:17.519517 [INFO] evse_manager_1: :: EVSE ISO V2G AuthorizationRes 2024-07-16 16:03:18.054654 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"1BFEFA7BFFFFF7BB"},"Body":{"AuthorizationRes":{"ResponseCode":"OK","EVSEProcessing":"Ongoing"}}}} 2024-07-16 16:03:18.056217 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: AuthorizationRes received 2024-07-16 16:03:18.059287 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "1BFEFA7BFFFFF7BB"}, "Body": {"AuthorizationReq": {}}}} 2024-07-16 16:03:18.233329 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 16:03:19.025228 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Sent AuthorizationReq 2024-07-16 16:03:19.026175 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Entered state Authorization 2024-07-16 16:03:19.032420 [INFO] evse_manager_1: :: CAR ISO V2G AuthorizationReq 2024-07-16 16:03:19.134195 [INFO] evse_manager_1: :: EVSE ISO V2G AuthorizationRes 2024-07-16 16:03:19.440722 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"1BFEFA7BFFFFF7BB"},"Body":{"AuthorizationRes":{"ResponseCode":"OK","EVSEProcessing":"Ongoing"}}}} 2024-07-16 16:03:19.447558 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: AuthorizationRes received 2024-07-16 16:03:19.450531 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "1BFEFA7BFFFFF7BB"}, "Body": {"AuthorizationReq": {}}}} 2024-07-16 16:03:19.506529 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 16:03:20.446637 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Sent AuthorizationReq 2024-07-16 16:03:20.448412 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Entered state Authorization 2024-07-16 16:03:20.454068 [INFO] evse_manager_1: :: CAR ISO V2G AuthorizationReq 2024-07-16 16:03:20.551506 [INFO] evse_manager_1: :: EVSE ISO V2G AuthorizationRes 2024-07-16 16:03:20.726106 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 16:03:20.858116 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"1BFEFA7BFFFFF7BB"},"Body":{"AuthorizationRes":{"ResponseCode":"OK","EVSEProcessing":"Ongoing"}}}} 2024-07-16 16:03:20.859713 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: AuthorizationRes received 2024-07-16 16:03:20.864215 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "1BFEFA7BFFFFF7BB"}, "Body": {"AuthorizationReq": {}}}} 2024-07-16 16:03:21.820007 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 16:03:21.839351 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Sent AuthorizationReq 2024-07-16 16:03:21.840325 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Entered state Authorization ... 2024-07-16 16:08:04.416407 [ERRO] auth:Auth Everest::json Everest::Everest::call_cmd(const Requirement&, const std::string&, Everest::json) :: Timeout while waiting for result of ocpp:OCPP201->auth_validator:auth_token_validator->validate_token() terminate called after throwing an instance of 'boost::wrapexcept' what(): Timeout while waiting for result of ocpp:OCPP201->auth_validator:auth_token_validator->validate_token() 2024-07-16 16:08:05.366852 [WARN] energy_manager: void module::EnergyManager::enforce_limits(const std::vector&) :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 16:08:05.732677 [CRIT] manager int boot(const boost::program_options::variables_map&) :: Module auth (pid: 6258) exited with status: 6. Terminating all modules. 2024-07-16 16:08:05.768883 [INFO] manager :: SIGTERM of child: api (pid: 6257) succeeded. 2024-07-16 16:08:05.774743 [INFO] manager :: SIGTERM of child: car_simulator_1 (pid: 6259) succeeded. 2024-07-16 16:08:05.784776 [INFO] manager :: SIGTERM of child: energy_manager (pid: 6260) succeeded. 2024-07-16 16:08:05.840433 [INFO] manager :: SIGTERM of child: evse_manager_1 (pid: 6261) succeeded. 2024-07-16 16:08:05.840984 [INFO] manager :: SIGTERM of child: evse_security (pid: 6267) succeeded. 2024-07-16 16:08:05.841217 [INFO] manager :: SIGTERM of child: grid_connection_point (pid: 6269) succeeded. 2024-07-16 16:08:05.841350 [INFO] manager :: SIGTERM of child: iso15118_car (pid: 6270) succeeded. 2024-07-16 16:08:05.860398 [INFO] manager :: SIGTERM of child: iso15118_charger (pid: 6271) succeeded. 2024-07-16 16:08:05.886850 [INFO] manager :: SIGTERM of child: ocpp (pid: 6272) succeeded. 2024-07-16 16:08:05.899151 [INFO] manager :: SIGTERM of child: slac (pid: 6273) succeeded. 2024-07-16 16:08:05.900147 [INFO] manager :: SIGTERM of child: system (pid: 6274) succeeded. 2024-07-16 16:08:05.922880 [INFO] manager :: SIGTERM of child: token_provider_1 (pid: 6280) succeeded. 2024-07-16 16:08:05.923692 [INFO] manager :: SIGTERM of child: yeti_driver_1 (pid: 6282) succeeded. 2024-07-16 16:08:05.924463 [CRIT] manager int boot(const boost::program_options::variables_map&) :: Exiting manager. /ext/source/build # ```

Even after reverting changes.

Restarting even further after saving a patch with the logs

the-bay-kay commented 1 month ago

Starting with JsEvManager/index.js some observations:

From what I can gather, the mutation of variables like mod.maxCurrent is handled by external packages -- as such, I don't believe we need to make any other changes to this file beyond setting the default of mod.iso_departure_time = null...

shankari commented 1 month ago

Restarted everything. It works again.

For the record, and to help in debugging again, here's what a successful auth *should* look like ``` 2024-07-16 17:12:49.700348 [INFO] evse_security:E :: Verifying leaf certificate: MO 2024-07-16 17:12:49.700850 [INFO] evse_security:E :: Building new certificate hierarchy! 2024-07-16 17:12:49.702983 [INFO] evse_security:E :: Building new certificate hierarchy! 2024-07-16 17:12:49.708433 [INFO] ocpp:OCPP201 :: Local contract validation result: Valid 2024-07-16 17:12:49.719646 [INFO] ocpp:OCPP201 :: Online: Pass generated OCSP data to CSMS 2024-07-16 17:12:49.839650 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"AuthorizationReq": {"Id": "id1", "GenChallenge": "AW5ao2VeCrL6l0hePq/8Zg=="}} 2024-07-16 17:12:49.899228 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=http://www.w3.org/2000/09/xmldsig#): {"SignedInfo": {"CanonicalizationMethod": {"Algorithm": "http://www.w3.org/TR/canonical-exi/"}, "SignatureMethod": {"Algorithm": "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"}, "Reference": [{"Transforms": {"Transform": [{"Algorithm": "http://www.w3.org/TR/canonical-exi/"}]}, "DigestMethod": {"Algorithm": "http://www.w3.org/2001/04/xmlenc#sha256"}, "DigestValue": "9yFpODfSMBDrbQA2T6oQsKv5JFBYvI6b4QbwozA27rw=", "URI": "#id1"}]}} 2024-07-16 17:12:49.951302 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "77EA5F7FD63DFEEF", "Signature": {"SignedInfo": {"CanonicalizationMethod": {"Algorithm": "http://www.w3.org/TR/canonical-exi/"}, "SignatureMethod": {"Algorithm": "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"}, "Reference": [{"Transforms": {"Transform": [{"Algorithm": "http://www.w3.org/TR/canonical-exi/"}]}, "DigestMethod": {"Algorithm": "http://www.w3.org/2001/04/xmlenc#sha256"}, "DigestValue": "9yFpODfSMBDrbQA2T6oQsKv5JFBYvI6b4QbwozA27rw=", "URI": "#id1"}]}, "SignatureValue": {"value": "zrDorSH8GT7q2GQjmvXMzrbu29oYeWB8RzLaDkCRYhfFHD+72BCl/COw3O8Gq4VkIgLK7oCJyFKPVCG2VZjGLA=="}}}, "Body": {"AuthorizationReq": {"Id": "id1", "GenChallenge": "AW5ao2VeCrL6l0hePq/8Zg=="}}}} 2024-07-16 17:12:50.527150 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Sent AuthorizationReq 2024-07-16 17:12:50.527474 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Entered state Authorization 2024-07-16 17:12:50.534481 [INFO] ocpp:OCPP201 :: CSMS idToken status: Accepted 2024-07-16 17:12:50.534584 [INFO] ocpp:OCPP201 :: CSMS certificate status: Accepted 2024-07-16 17:12:50.534605 [ERRO] ocpp:OCPP201 void ocpp::v201::ChargePoint::handle_message(const ocpp::EnhancedMessage&) :: Handle_message called: [3,"daafe391-ffef-4980-ad32-84e73d097da3",{"certificateStatus":"Accepted","idTokenInfo":{"status":"Accepted"}}] 2024-07-16 17:12:50.534751 [ERRO] ocpp:OCPP201 void ocpp::v201::ChargePoint::handle_message(const ocpp::EnhancedMessage&) :: json_message called: [3,"daafe391-ffef-4980-ad32-84e73d097da3",{"certificateStatus":"Accepted","idTokenInfo":{"status":"Accepted"}}] 2024-07-16 17:12:50.536751 [INFO] auth:Auth :: Providing authorization to connector#1 ``` ``` 2024-07-16 10:12:00 time=2024-07-16T17:12:00.548Z level=INFO msg="POST /api/v0/cs/cp001/setchargingprofile" remote_addr=192.168.65.1:48446 status=201 bytes=0 duration=2.257924ms 2024-07-16 10:12:00 time=2024-07-16T17:12:00.598Z level=ERROR msg="unable to route message" chargeStationId=cp001 action=SetChargingProfile err="routing request: NotImplemented: SetChargingProfile result not implemented" 2024-07-16 10:12:00 time=2024-07-16T17:12:00.598Z level=ERROR msg="cs/in/ocpp2.0.1/# receive" duration=103.775Āµs messaging.system=mqtt messaging.consumer.id=manager-GFDaQ messaging.message.payload_size_bytes=588 messaging.operation=receive csId=cp001 ocpp.version=2.0.1 call_result.action=SetChargingProfile messaging.message.conversation_id=edf9ca5f-5875-4bb4-aab7-a556f28f1e60 2024-07-16 10:12:00 time=2024-07-16T17:12:00.598Z level=ERROR msg=exception exception.type=*fmt.wrapError exception.message="routing request: NotImplemented: SetChargingProfile result not implemented" 2024-07-16 10:12:05 time=2024-07-16T17:12:00.547Z level=INFO msg="cs/out/ocpp2.0.1/# publish" duration=1.475038ms messaging.system=mqtt messaging.message.payload_size_bytes=555 messaging.operation=publish messaging.message.conversation_id=edf9ca5f-5875-4bb4-aab7-a556f28f1e60 csId=cp001 call.action=SetChargingProfile 2024-07-16 10:12:25 time=2024-07-16T17:12:25.782Z level=INFO msg="checking for pending charge station certificates changes" 2024-07-16 10:12:25 time=2024-07-16T17:12:25.784Z level=INFO msg="checking for pending charge station settings changes" 2024-07-16 10:12:25 time=2024-07-16T17:12:25.780Z level=INFO msg="sync triggers" duration=4.453844ms sync.trigger.previous="" sync.trigger.count=0 2024-07-16 10:12:45 time=2024-07-16T17:12:42.785Z level=INFO msg="cs/in/ocpp2.0.1/# receive" duration=349.616Āµs messaging.system=mqtt messaging.consumer.id=manager-GFDaQ messaging.message.payload_size_bytes=191 messaging.operation=receive csId=cp001 ocpp.version=2.0.1 call.action=StatusNotification messaging.message.conversation_id=03fb6a01-6ad1-4677-9c32-c25853c0c574 status.evse_id=1 status.connector_id=1 status.connector_status=Occupied 2024-07-16 10:12:45 time=2024-07-16T17:12:42.785Z level=INFO msg="cs/out/ocpp2.0.1/# publish" duration=72.589Āµs messaging.system=mqtt messaging.message.payload_size_bytes=98 messaging.operation=publish messaging.message.conversation_id=03fb6a01-6ad1-4677-9c32-c25853c0c574 csId=cp001 call_result.action=StatusNotification 2024-07-16 10:12:50 time=2024-07-16T17:12:50.532Z level=WARN msg="ocsp check" attempt=1 maxAttempts=1 error="parsing ocsp response: asn1: structure error: tags don't match (16 vs {class:0 tag:28 length:33 isCompound:true}) {optional:false explicit:false application:false private:false defaultValue: tag: stringType:0 timeType:0 set:false omitEmpty:false} responseASN1 @2" 2024-07-16 10:12:50 time=2024-07-16T17:12:50.611Z level=INFO msg="transaction event" chargeStationId=cp001 transactionId=12ab48fc-820a-4243-8332-e34f2cd52cbe eventType=Started triggerReason=Authorized seqNo=0 2024-07-16 10:12:50 time=2024-07-16T17:12:49.721Z level=INFO msg="cs/in/ocpp2.0.1/# receive" duration=811.00724ms messaging.system=mqtt messaging.consumer.id=manager-GFDaQ messaging.message.payload_size_bytes=948 messaging.operation=receive csId=cp001 ocpp.version=2.0.1 call.action=Authorize messaging.message.conversation_id=daafe391-ffef-4980-ad32-84e73d097da3 authorize.certificate=hash token_auth.id=UKSWI123456789G token_auth.type=eMAID token_auth.status=Accepted authorize.cert_warn="No OCSP, but ignoring for testing purpose." request.status=Accepted 2024-07-16 10:12:50 time=2024-07-16T17:12:49.725Z level=INFO msg="HTTP POST" duration=807.121357ms http.method=POST http.url=https://www.example.com/ net.peer.name=www.example.com http.request_content_length=97 http.status_code=200 http.response_content_length=1256 2024-07-16 10:12:50 time=2024-07-16T17:12:50.532Z level=INFO msg="cs/out/ocpp2.0.1/# publish" duration=88.681Āµs messaging.system=mqtt messaging.message.payload_size_bytes=155 messaging.operation=publish messaging.message.conversation_id=daafe391-ffef-4980-ad32-84e73d097da3 csId=cp001 call_result.action=Authorize 2024-07-16 10:12:50 time=2024-07-16T17:12:50.610Z level=INFO msg="cs/in/ocpp2.0.1/# receive" duration=11.894652ms messaging.system=mqtt messaging.consumer.id=manager-GFDaQ messaging.message.payload_size_bytes=1605 messaging.operation=receive csId=cp001 ocpp.version=2.0.1 call.action=TransactionEvent messaging.message.conversation_id=193336cd-a66f-437d-92d6-0062a8734ada token_auth.id=UKSWI123456789G token_auth.type=eMAID token_auth.status=Accepted 2024-07-16 10:12:50 time=2024-07-16T17:12:50.622Z level=INFO msg="cs/out/ocpp2.0.1/# publish" duration=73.971Āµs messaging.system=mqtt messaging.message.payload_size_bytes=131 messaging.operation=publish messaging.message.conversation_id=193336cd-a66f-437d-92d6-0062a8734ada csId=cp001 call_result.action=TransactionEvent 2024-07-16 10:12:52 time=2024-07-16T17:12:52.744Z level=INFO msg="transaction event" chargeStationId=cp001 transactionId=12ab48fc-820a-4243-8332-e34f2cd52cbe eventType=Updated triggerReason=ChargingStateChanged seqNo=1 2024-07-16 10:12:55 time=2024-07-16T17:12:52.743Z level=INFO msg="cs/in/ocpp2.0.1/# receive" duration=9.621107ms messaging.system=mqtt messaging.consumer.id=manager-GFDaQ messaging.message.payload_size_bytes=322 messaging.operation=receive csId=cp001 ocpp.version=2.0.1 call.action=TransactionEvent messaging.message.conversation_id=615822f6-7887-4301-a381-a289e102517a 2024-07-16 10:12:55 time=2024-07-16T17:12:52.752Z level=INFO msg="cs/out/ocpp2.0.1/# publish" duration=122.01Āµs messaging.system=mqtt messaging.message.payload_size_bytes=96 messaging.operation=publish messaging.message.conversation_id=615822f6-7887-4301-a381-a289e102517a csId=cp001 call_result.action=TransactionEvent ```
Making the pyjosev changes without adding any other logs ``` 2024-07-16 17:48:36.189938 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "DE20EB55FEFCBC67"}, "Body": {"ChargeParameterDiscoveryReq": {"RequestedEnergyTransferMode": "AC_three_phase_core", "AC_EVChargeParameter": {"DepartureTime": 0, "EAmount": {"Value": 60, "Multiplier": 0, "Unit": "Wh"}, "EVMaxVoltage": {"Value": 400, "Multiplier": 0, "Unit": "V"}, "EVMaxCurrent": {"Value": 32000, "Multiplier": -3, "Unit": "A"}, "EVMinCurrent": {"Value": 10, "Multiplier": 0, "Unit": "A"}}}}}} ```
shankari commented 1 month ago

I note that the construction of the charge parameter discovery request/response also has some SA schedule creation

        sa_schedule_list = await self.comm_session.evse_controller.get_sa_schedule_list(                
            ev_data_context,                                                                            
            self.comm_session.config.free_charging_service,                                             
            max_schedule_entries,                                                                       
            departure_time,                                                                             
        )                                                                                       

But the current message doesn't seem to use that so we will ignore for simplicity

the-bay-kay commented 1 month ago

Taking some time to set up the Node-RED UI, I think that's the best place to start (knowing what signals we can / will send will help define the message behavior, and so on as the call graph grows). Some initial notes on the UI nodes available:

UI Node Choices - We can't use the `date` node, as it only gives us per-day granularity - departureTime is defined as a 32-bit unsigned integer, that represents an offset in seconds from the point of time the message is sent. As much as I'd like to have a fancy UI (pick the time, and it handles it for you), let's hack together a solution that uses that input. - The text node _does_ have a time picker option. In the interest of time, I won't be using this: just wanted to note that this is an avenue for improvement! - The integer node is not a viable option, for two reasons: - We cannot set the max of 32u - Even if we could, it would be _so_ slow to use the click widget to implement charging 1 second at a time. - For these reasons, I think the best course of action is to add a text node, and then interpret the text into an integer.

Here is where we run into our first design quirk. Per [V2H2-215]...

If there is no DepartureTime information available, the EVCC shall not include this message in the ChargeParameterDiscoveryReq message

This means we cannot simply have 0 be our base case for the input component (or use some value like -1 as the "null" - this value must be unsigned).

Without piping through any of the messages, below is a mock up of the module

UI Screenshots ![image](https://github.com/user-attachments/assets/6892db96-5cf6-4054-9cc9-70de16f25449) ![image](https://github.com/user-attachments/assets/e868d704-1636-4d63-b5fa-699e77a5fa80) (I believe we won't need a default injection, we actually want the value to be null) **EDIT:** I think we actually need to hook up the departure time to the BufferSimCommands...

When sketching up these values, I'm left one concern. As sketched up, the proposed "setDepartureTime" command will send every time the number is set. How can we make sure that we only change the DepartureTime value when starting or resuming a charging session? Will have to spend more time with JsEVManager to figure out how this will look in practice.

the-bay-kay commented 1 month ago

Still getting used to the Node-RED workflow, setting up the message flow -- writing these notes down mostly for my own understanding...


As I understand it, the Buffer sim commands function node takes the inputs from each of the input nodes, and adjusts the payload according to the topic.

Screenshot of nodes, example code ![image](https://github.com/user-attachments/assets/fbbca2dd-9490-40c0-aafe-7cce012da9e7) ```js if (msg.topic.indexOf('sim_commands') > -1) { const s = msg.payload.split('#'); flow.set('sim_commands_start', s[0]); // the code continues... ```

After some searching, it seems the sim_commands topic is defined within the injection of the CarSimulation node, but I cannot find the flows for sim_commands_pause, etc... Am I misunderstanding how the flow get command works? Where are these being defined?

This leads me to the question: do I even need to filter through the buffer?? For example, the values set by the MaxCurrentSlider aren't being filtered. I'm going to just assume we don't have to filter it for now, I think that should be OK...

shankari commented 1 month ago

Aha! It looks like the pyjosev library is in two locations

# find / -name states.py
/ext/cache/cpm/josev/dd7dc8e95662d54aca01374e5283ead8d4793261/Josev/iso15118/shared/states.py
/ext/source/build/dist/libexec/everest/3rd_party/josev/iso15118/shared/states.py

I have been editing the one in build/dist, but it may be that the code is getting pulled from the cache. Not sure how the original patch ever worked; maybe some parts are pulled from each location?!

Trying to modify an existing log to see which one is loaded (modifying the one in states.py)

2024-07-16 19:24:00.442684 [DEBG] iso15118_car    pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: IN BUILD_DIST: Entered state ServiceDiscovery
2024-07-16 19:24:01.223707 [DEBG] iso15118_car    pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: IN BUILD_DIST: Entered state PaymentServiceSelection
2024-07-16 19:24:01.952899 [DEBG] iso15118_car    pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: IN BUILD_DIST: Entered state PaymentDetails
2024-07-16 19:24:02.769054 [DEBG] iso15118_car    pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: IN BUILD_DIST: Entered state Authorization
2024-07-16 19:24:03.475439 [DEBG] iso15118_car    pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: IN BUILD_DIST: Entered state ChargeParameterDiscovery

Let's make sure that the loggers are set up in the same way...

shankari commented 1 month ago

I might have made changes in the SECC implementation of pyjosev, which is unused in EVerest. The actual values are here: https://github.com/EVerest/ext-switchev-iso15118/blob/7f16c4b2c1307ce73798215f34b8fe06862bbae1/iso15118/evcc/controller/simulator.py#L276C15-L276C35

            e_amount = PVEAmount(multiplier=3, value=60,        
                                 unit=UnitSymbol.WATT_HOURS)    

            ac_charge_params = ACEVChargeParameter(
                departure_time=21600,         
                e_amount=e_amount,            
                ev_max_voltage=ev_max_voltage,
                ev_max_current=ev_max_current,    
                ev_min_current=ev_min_current,                      
            )                                                                       

Bingo!

2024-07-16 19:33:51.232377 [DEBG] iso15118_car    pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "BDF67F7EFD4FCEDD"}, "Body": {"ChargeParameterDiscoveryReq": {"RequestedEnergyTransferMode": "AC_three_phase_core", "AC_EVChargeParameter": {"DepartureTime": 21600, "EAmount": {"Value": 60, "Multiplier": 3, "Unit": "Wh"}, "EVMaxVoltage": {"Value": 400, "Multiplier": 0, "Unit": "V"}, "EVMaxCurrent": {"Value": 32000, "Multiplier": -3, "Unit": "A"}, "EVMinCurrent": {"Value": 10, "Multiplier": 0, "Unit": "A"}}}}}}

2024-07-16 19:33:51.944143 [DEBG] iso15118_car    pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"BDF67F7EFD4FCEDD"},"Body":{"ChargeParameterDiscoveryRes":{"ResponseCode":"OK","EVSEProcessing":"Finished","SAScheduleList":{"SAScheduleTuple":[{"SAScheduleTupleID":1,"PMaxSchedule":{"PMaxScheduleEntry":[{"RelativeTimeInterval":{"start":0,"duration":86400},"PMax":{"Multiplier":0,"Unit":"W","Value":22080}}]}}]},"AC_EVSEChargeParameter":{"AC_EVSEStatus":{"NotificationMaxDelay":0,"EVSENotification":"None","RCD":false},"EVSENominalVoltage":{"Multiplier":-1,"Unit":"V","Value":2300},"EVSEMaxCurrent":{"Multiplier":-1,"Unit":"A","Value":320}}}}}}

Now, we set our charging profile

2024-07-16 19:37:02.768247 [INFO] ocpp:OCPP201     :: period.has_value() limit = 6900
2024-07-16 19:37:02.768315 [INFO] ocpp:OCPP201     :: period.has_value() stackLevel = 6900
2024-07-16 19:37:02.768429 [INFO] ocpp:OCPP201     :: ProfileId #1 Kind: Absolute
2024-07-16 19:37:02.768507 [INFO] ocpp:OCPP201     :: #1 find_period_at> 2024-07-16T19:00:00.000Z
2024-07-16 19:37:02.768611 [INFO] ocpp:OCPP201     ::    find_period_at>        start_time> 2024-07-16T19:37:02.768Z
2024-07-16 19:37:02.768690 [INFO] ocpp:OCPP201     ::    find_period_at> period_start_time> 2024-07-16T19:00:00.000Z
2024-07-16 19:37:02.768808 [INFO] ocpp:OCPP201     ::    find_period_at>   period_end_time> 2024-07-16T20:00:00.000Z
2024-07-16 19:37:02.769048 [INFO] ocpp:OCPP201     :: PeriodDateTimePair>  period: {
    "limit": 10.0,
    "numberPhases": 3,
    "startPeriod": 0
} end_time: 2024-07-16T20:00:00.000Z
2024-07-16 19:37:02.769080 [INFO] ocpp:OCPP201     :: period.has_value() limit = 6900
2024-07-16 19:37:02.769131 [INFO] ocpp:OCPP201     :: period.has_value() stackLevel = 6900

And now we plug in the car, and we send the correct request, but the response still has only one SASchedule, which is 6900W for the entire day ("duration":86400).

2024-07-16 19:38:02.521698 [DEBG] iso15118_car    pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "BFF27B0FED3BDBFE"}, "Body": {"ChargeParameterDiscoveryReq": {"RequestedEnergyTransferMode": "AC_three_phase_core", "AC_EVChargeParameter": {"DepartureTime": 21600, "EAmount": {"Value": 60, "Multiplier": 3, "Unit": "Wh"}, "EVMaxVoltage": {"Value": 400, "Multiplier": 0, "Unit": "V"}, "EVMaxCurrent": {"Value": 32000, "Multiplier": -3, "Unit": "A"}, "EVMinCurrent": {"Value": 10, "Multiplier": 0, "Unit": "A"}}}}}}

2024-07-16 19:38:03.085580 [DEBG] iso15118_car    pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Sent ChargeParameterDiscoveryReq
2024-07-16 19:38:03.085726 [INFO] iso15118_charge  :: Parameter-phase started
2024-07-16 19:38:03.086015 [DEBG] iso15118_car    pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: IN BUILD_DIST: Entered state ChargeParameterDiscovery

2024-07-16 19:38:03.088033 [INFO] iso15118_charge  :: Selected energy transfer mode: AC_three_phase_core
2024-07-16 19:38:03.129469 [INFO] evse_manager_1:  ::                                     CAR ISO V2G ChargeParameterDiscoveryReq
2024-07-16 19:38:03.185479 [INFO] evse_manager_1:  :: EVSE ISO V2G ChargeParameterDiscoveryRes
2024-07-16 19:38:03.240756 [DEBG] iso15118_car    pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"BFF27B0FED3BDBFE"},"Body":{"ChargeParameterDiscoveryRes":{"ResponseCode":"OK","EVSEProcessing":"Finished","SAScheduleList":{"SAScheduleTuple":[{"SAScheduleTupleID":1,"PMaxSchedule":{"PMaxScheduleEntry":[{"RelativeTimeInterval":{"start":0,"duration":86400},"PMax":{"Multiplier":0,"Unit":"W","Value":6900}}]}}]},"AC_EVSEChargeParameter":{"AC_EVSEStatus":{"NotificationMaxDelay":0,"EVSENotification":"None","RCD":false},"EVSENominalVoltage":{"Multiplier":-1,"Unit":"V","Value":2300},"EVSEMaxCurrent":{"Multiplier":-1,"Unit":"A","Value":100}}}}}}
shankari commented 1 month ago

So it is fairly clear that the current ISO 15118-2 implementation does not work the way we had hoped in https://github.com/EVerest/everest-demo/issues/64#issue-2409427125

Concretely, the EVSE does not send a list of SASchedules; it only sends a single SASchedule that corresponds to the current limits. When the EVSE sent the ChargeParameterDiscoveryRes, it basically said that you can get 6900 W for the rest of the day. This is technically correct because we started with the lowest current, but I don't think it will give us the energy we requested.

To run some numbers:

So basically, departure time does not work, and we only send a single SA Schedule as I had speculated from the code earlier. Not sure if it is super easy to fix this, but I have the afternoon to try!

the-bay-kay commented 1 month ago

Parsing the syntax & design behind the MQTT routes... My current understanding is that the DepartureTime should be send via the /carsim/cmd/{} route, as the DepartureTime is set by the EVCC (read: vehicle). When looking at the docs for these routes (The (EVManager), we can see that there are several commands that are sent within a execute_charging_session or modify_charging_session message. As such, it doesn't seem appropriate to create an entirely new route; rather, I think the goal is to add a separate command within the execute_charging_session packet. This goes back to my explorations earlier -- turns out I should be adding to the sim commands. I'm still a bit confused as to this process, but will do some digging into JsEvManager and EvManager's car_simulatorImpl.cpp. Should also probably take some time to investigate the testing code that covers these functions...

shankari commented 1 month ago

First, where is the limit computation coming from?

It is

int SmartChargingHandler::get_power_limit(const int limit, const int nr_phases,                                        
                                          const ChargingRateUnitEnum& unit_of_limit) {                                 
    if (unit_of_limit == ChargingRateUnitEnum::W) {                                                                    
        return limit;                                                                                                  
    } else {                                                                                                           
        return limit * LOW_VOLTAGE * nr_phases;                                                                        
    }                                                                                                                  
}                                                                                                                      

ah

const int LOW_VOLTAGE = 230;

updating the power limits in https://github.com/EVerest/everest-demo/issues/64#issuecomment-2231736589

Next question: why are we not handling the departure time correctly, and why are we returning exactly one SASchedule?

shankari commented 1 month ago

Confirmed that the return SASchedules (EVSE -> car) are created in the modules/EvseV2G/iso_server.cpp, in handle_iso_charge_parameter_discovery. We create one SASchedule with one PMax entry, and we set it to the entire day.

            conn->ctx->evse_v2g_data.evse_sa_schedule_list.SAScheduleTuple.array[0]                          
                .PMaxSchedule.PMaxScheduleEntry.array[0]                                                     
                .RelativeTimeInterval.start = 0;                                                             
            conn->ctx->evse_v2g_data.evse_sa_schedule_list.SAScheduleTuple.array[0]                          
                .PMaxSchedule.PMaxScheduleEntry.array[0]                                                 
                .RelativeTimeInterval.duration_isUsed = 1;                                                   
            conn->ctx->evse_v2g_data.evse_sa_schedule_list.SAScheduleTuple.array[0]                          
                .PMaxSchedule.PMaxScheduleEntry.array[0]                                                     
                .RelativeTimeInterval.duration = SA_SCHEDULE_DURATION;                                       
            conn->ctx->evse_v2g_data.evse_sa_schedule_list.SAScheduleTuple.array[0]                          
                .PMaxSchedule.PMaxScheduleEntry.arrayLen = 1;                                                
            conn->ctx->evse_v2g_data.evse_sa_schedule_list.SAScheduleTuple.arrayLen = 1;                     
shankari commented 1 month ago

So achieving our original goals, with multiple SASchedules is going to be fairly complex. Given the short timeframe, let us at least try for a much simpler option in with there is a single charging profile set, but the user specifies a departure time and energy need, and we spread the energy out over the entire charging period.

the-bay-kay commented 1 month ago

It seems that once you add a command to /carsim/cmd/{}, it needs to be registered in both JsEvManager and EVManager's car_simulatorImpl.cpp.

So, we need to finally answer the question: How do we add commands to the message?

Looking at the Buffer sim commands function node's code:

if (msg.topic.indexOf('sim_commands') > -1) {
    const s = msg.payload.split('#');
    flow.set('sim_commands_start', s[0]);
    flow.set('sim_commands_stop', s[1]);
    flow.set('sim_commands_pause', s[2]);
    flow.set('sim_commands_resume', s[3]);
} 
// Code continues...

We can use the default injection to understand exactly how the payload is generated. The following string...

sleep 1;iec_wait_pwr_ready;sleep 1;draw_power_regulated 16,3;sleep 36000#unplug#pause;sleep 3600#draw_power_regulated 16,3;sleep 36000

Assigns itself to each of the sim commands, as follows...

Flow Variable (Command) Flow Value (Commands)
Start sleep 1;iec_wait_pwr_ready;sleep 1;draw_power_regulated 16,3;sleep 36000
Stop unplug
Pause pause;sleep 3600
Resume draw_power_regulated 16,3;sleep 36000

Ah, that makes more sense -- we set a series of commands for each possible method of interacting with the simulation loop! Cool. Know this, we finally have some steps to move forward: EDIT: Updating checklist.

shankari commented 1 month ago

Ok, so I can confirm that I can read the values correctly in the ISO server code,

2024-07-16 23:30:07.580610 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: max_current 32.000000, nom_voltage 230, pmax 22080
2024-07-16 23:30:07.580705 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: Requested departure time 0, requested energy 60.000000

now to actually use the departure time and requested energy...

the-bay-kay commented 1 month ago

First design hiccup: We cannot simply pipe the set_departure_time command into the buffer like the other commands. Consider the following scenario:

Solution: We still need have the set_departure_time send its message through the buffer*, but we should also set a flag somewhere that the other that the car simulation node can check. I think this will be done via a "Flow Variable", as we have done is done with the sim_commands. Once I figure out how to set one of these scoped variables, this should be a relatively fix

*Caveat: I think this part of the function will behave quite similar to the simulation selection. That is, the change will be fed into the buffer, but the message will not propagate through to the mqtt server (This is because should only send departure time during a Start or Resume vent)

shankari commented 1 month ago

So I am not quite sure how we go from a complex set of schedule periods to a single limit. OCPP calls OCPP201::set_external_limits which passes in a composite schedule. But when we get to the energy manager, we only return one optimized schedule

2024-07-16 23:59:55.150578 [INFO] energy_manager:  :: Sending enfored limits (import) to :evse_manager_1 {
    "ac_max_current_A": 32.0
}
2024-07-16 23:59:55.150671 [INFO] energy_manager:  :: returning optimized values vector of length 1
2024-07-16 23:59:55.150816 [INFO] energy_manager:  :: evse_manager_1 Enforce limits 32A -9999W 
2024-07-16 23:59:55.277531 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000

If I can figure out how to pass this through, we might be able to do a better demo. Also checking to see whether the schedules are automatically recalculated (there is a timer that sets the limits)

None of them are valid ``` 2024-07-16 23:56:11.012269 [WARN] ocpp:OCPP201 module::OCPP201::ready():: :: Received a new Charging Schedules from the CSMS or another actor. 2024-07-16 23:56:11.012377 [INFO] ocpp:OCPP201 :: ProfileId #1 Kind: Absolute 2024-07-16 23:56:11.012454 [INFO] ocpp:OCPP201 :: #1 find_period_at> 2024-07-17T00:00:00.000Z 2024-07-16 23:56:11.012531 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-16T23:56:11.012Z 2024-07-16 23:56:11.012617 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-17T00:00:00.000Z 2024-07-16 23:56:11.012693 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-17T01:00:00.000Z 2024-07-16 23:56:11.012797 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-16T23:56:11.012Z 2024-07-16 23:56:11.012897 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-17T01:00:00.000Z 2024-07-16 23:56:11.012973 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-17T02:00:00.000Z 2024-07-16 23:56:11.013047 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-16T23:56:11.012Z 2024-07-16 23:56:11.013118 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-17T02:00:00.000Z 2024-07-16 23:56:11.013267 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-18T00:00:00.000Z 2024-07-16 23:56:11.013349 [INFO] ocpp:OCPP201 :: PeriodDateTimePair> end_time: 2080-03-01T16:33:27.779Z 2024-07-16 23:56:11.013443 [INFO] ocpp:OCPP201 :: ProfileId #1 Kind: Absolute 2024-07-16 23:56:11.013473 [INFO] ocpp:OCPP201 :: #1 find_period_at> 2024-07-17T00:00:00.000Z 2024-07-16 23:56:11.013502 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-16T23:56:11.013Z 2024-07-16 23:56:11.013529 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-17T00:00:00.000Z 2024-07-16 23:56:11.013612 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-17T01:00:00.000Z 2024-07-16 23:56:11.013721 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-16T23:56:11.013Z 2024-07-16 23:56:11.013799 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-17T01:00:00.000Z 2024-07-16 23:56:11.013839 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-17T02:00:00.000Z 2024-07-16 23:56:11.013986 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-16T23:56:11.013Z 2024-07-16 23:56:11.014055 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-17T02:00:00.000Z 2024-07-16 23:56:11.014151 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-18T00:00:00.000Z 2024-07-16 23:56:11.014379 [INFO] ocpp:OCPP201 :: PeriodDateTimePair> end_time: 2080-03-01T16:33:27.779Z 2024-07-16 23:56:11.098733 [ERRO] ocpp:OCPP201 void ocpp::v201::ChargePoint::handle_set_charging_profile_req(ocpp::Call) :: Received profile validity: Validsetting response to { "status": "Accepted" } 2024-07-16 23:56:11.329473 [INFO] energy_manager: :: NO TRADE 2024-07-16 23:56:11.329732 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } ```
Day switched over (in UTC), but the timer doesn't seem to be recalculating ``` 2024-07-16 23:59:59.613293 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-16 23:59:59.613351 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-16 23:59:59.701427 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:00.012011 [ERRO] ocpp:OCPP201 void ocpp::v201::ChargePoint::handle_message(const ocpp::EnhancedMessage&) :: Handle_message called: [3,"6459f8b8-bc74-4cf0-a946-20f0007d2338",{}] 2024-07-17 00:00:00.012105 [ERRO] ocpp:OCPP201 void ocpp::v201::ChargePoint::handle_message(const ocpp::EnhancedMessage&) :: json_message called: [3,"6459f8b8-bc74-4cf0-a946-20f0007d2338",{}] 2024-07-17 00:00:00.792140 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:00.792267 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:00.792492 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:00.792576 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:00.881991 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:01.929852 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:01.930111 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:01.930357 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:01.930521 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:01.977783 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:03.024977 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:03.025242 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:03.025353 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:03.025468 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:03.073103 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:04.119963 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:04.120263 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:04.120372 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:04.120509 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:04.208647 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:05.297367 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:05.297640 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:05.297807 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:05.297898 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:05.386170 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:06.434387 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:06.434612 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:06.434808 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:06.434921 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:06.523742 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:07.570195 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:07.570478 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:07.570590 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:07.570651 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:07.618045 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:08.663480 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:08.663657 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:08.663806 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:08.663845 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:08.752327 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:09.839791 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:09.840045 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:09.840189 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:09.840265 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:09.888312 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:10.975204 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:10.975472 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:10.975792 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:10.975854 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:10.982449 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:12.028872 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:12.029073 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:12.029182 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:12.029243 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:12.075557 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:13.162296 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:13.162551 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:13.162727 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:13.162803 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:13.210296 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:14.259348 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:14.259736 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:14.259860 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:14.259930 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:14.307981 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:15.316521 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:15.316672 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:15.316752 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:15.316797 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:15.429489 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:16.476905 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:16.477109 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:16.477219 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:16.477280 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:16.564772 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:17.611086 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:17.611292 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:17.611411 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:17.611671 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:17.659640 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:18.708795 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:18.708973 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:18.709107 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:18.709204 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:18.755105 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:19.803908 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:19.804180 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:19.804335 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:19.804417 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:19.852383 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:20.901811 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:20.902077 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:20.902219 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:20.902298 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:20.950124 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:21.998977 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:21.999181 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:21.999287 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:21.999345 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:22.005213 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:23.053485 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:23.053674 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:23.053760 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:23.053805 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:23.140427 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:24.189693 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:24.189949 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:24.190099 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:24.190178 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:24.197073 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:25.285275 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:25.285501 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:25.285684 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:25.285745 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:25.333425 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:26.421466 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:26.421780 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:26.421897 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:26.421958 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:26.459672 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:27.508468 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:27.508760 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:27.508947 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:27.509105 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:27.557371 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:28.604746 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:28.604951 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:28.605049 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:28.605155 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:28.652187 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:29.741137 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:29.741400 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:29.741673 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:29.741871 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:29.830648 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:30.876287 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:30.876542 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:30.876706 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:30.876767 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:30.882841 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:31.928334 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:31.928511 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:31.928593 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:31.928635 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:32.014657 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:33.061162 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:33.061422 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:33.061626 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:33.061730 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:33.109183 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:34.200705 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:34.200998 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:34.201159 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:34.201341 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:34.208331 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:35.254159 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:35.254723 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:35.254863 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:35.255011 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:35.311777 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:36.336359 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:36.336616 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:36.336756 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:36.336835 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:36.343761 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:37.391450 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:37.391636 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:37.391733 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:37.391787 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:37.397841 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:38.485356 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:38.485579 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:38.485676 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:38.485839 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:38.532511 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:39.620220 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:39.620662 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:39.620795 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:39.620870 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:39.626831 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:40.673955 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:40.674196 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:40.674377 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:40.674611 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:40.721364 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:41.811856 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:41.812144 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:41.812277 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:41.812338 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:41.901316 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:42.989366 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:42.989549 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:42.989683 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:42.989739 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:43.037266 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:44.125913 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:44.126223 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:44.126531 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:44.126617 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:44.173596 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:45.219017 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:45.219339 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:45.219520 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:45.219652 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:45.306465 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:46.355596 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:46.355803 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:46.355912 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:46.355973 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:46.403151 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:47.449671 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:47.449877 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:47.449985 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:47.450046 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:47.456590 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:48.548042 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:48.548305 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:48.548422 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:48.548484 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:48.596305 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:49.642440 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:49.642696 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:49.642835 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:49.642914 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:49.690390 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:50.737078 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:50.737253 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:50.737339 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:50.737409 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:50.782754 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:51.829982 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:51.830249 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:51.830452 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:51.830515 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:51.877462 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:52.924249 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:52.924422 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:52.924520 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:52.924571 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:52.970958 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:54.019200 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:54.019504 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:54.019645 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:54.019723 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:54.068059 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:55.117471 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:55.117729 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:55.117869 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:55.117946 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:55.166134 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:56.253945 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:56.254246 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:56.254446 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:56.254576 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:56.344033 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:57.433494 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:57.433754 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:57.433894 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:57.434032 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:57.482176 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:58.530312 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:58.530578 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:58.530750 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:58.530829 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:58.562756 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:00:59.611335 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:00:59.611658 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:00:59.611842 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:00:59.611931 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:00:59.660272 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:01:00.707389 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:01:00.707572 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:01:00.707675 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:01:00.707727 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:01:00.796434 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:01:01.842880 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:01:01.843087 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } ```
Resending the setChargingProfile, the limits are now clamped, but there is still only one limit from the energy manager ``` 2024-07-17 00:06:22.566084 [WARN] ocpp:OCPP201 module::OCPP201::ready():: :: Received a new Charging Schedules from the CSMS or another actor. 2024-07-17 00:06:22.566365 [INFO] ocpp:OCPP201 :: ProfileId #1 Kind: Absolute 2024-07-17 00:06:22.566447 [INFO] ocpp:OCPP201 :: #1 find_period_at> 2024-07-17T00:00:00.000Z 2024-07-17 00:06:22.566551 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-17T00:06:22.566Z 2024-07-17 00:06:22.566625 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-17T00:00:00.000Z 2024-07-17 00:06:22.566717 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-17T01:00:00.000Z 2024-07-17 00:06:22.566881 [INFO] ocpp:OCPP201 :: PeriodDateTimePair> period: { "limit": 10.0, "numberPhases": 3, "startPeriod": 0 } end_time: 2024-07-17T01:00:00.000Z 2024-07-17 00:06:22.566953 [INFO] ocpp:OCPP201 :: period.has_value() limit = 6900 2024-07-17 00:06:22.567066 [INFO] ocpp:OCPP201 :: period.has_value() stackLevel = 6900 2024-07-17 00:06:22.567298 [INFO] ocpp:OCPP201 :: ProfileId #1 Kind: Absolute 2024-07-17 00:06:22.567369 [INFO] ocpp:OCPP201 :: #1 find_period_at> 2024-07-17T00:00:00.000Z 2024-07-17 00:06:22.567425 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-17T00:06:22.567Z 2024-07-17 00:06:22.567493 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-17T00:00:00.000Z 2024-07-17 00:06:22.567536 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-17T01:00:00.000Z 2024-07-17 00:06:22.567692 [INFO] ocpp:OCPP201 :: PeriodDateTimePair> period: { "limit": 10.0, "numberPhases": 3, "startPeriod": 0 } end_time: 2024-07-17T01:00:00.000Z 2024-07-17 00:06:22.567758 [INFO] ocpp:OCPP201 :: period.has_value() limit = 6900 2024-07-17 00:06:22.567819 [INFO] ocpp:OCPP201 :: period.has_value() stackLevel = 6900 2024-07-17 00:06:22.611970 [ERRO] ocpp:OCPP201 void ocpp::v201::ChargePoint::handle_set_charging_profile_req(ocpp::Call) :: Received profile validity: Validsetting response to { "status": "Accepted" } 2024-07-17 00:06:22.670534 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:06:22.670733 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 00:06:22.670840 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 00:06:22.670897 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 00:06:22.718080 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 00:06:23.765308 [INFO] energy_manager: :: NO TRADE 2024-07-17 00:06:23.765548 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 10.0, "total_power_W": 6900.0 } 2024-07-17 00:06:23.765665 [INFO] energy_manager: :: returning optimized values vector of length 1 ```
the-bay-kay commented 1 month ago

Will we need a separate command to clear the departureTime once it's sent? Or will re-starting (resuming) without the command sufficient?

For now, let's assume we have to delete the command. With some initial futzing, this has proven to be somewhat non trivial. Below is my exploration of this first approach.

Method: Command Insertion / Deletion First, we define a command insertion as changing a string as follows: ```js // Old Command List: sleep 1;iso_wait_slac_matched;iso_start_v2g_session externalpayment,ac;iso_wait_pwr_ready;iso_draw_power_regulated 16,3;sleep 36000 flow.set('sim_commands_start', flow.get('sim_commands_start').splice(2, 0, 'iso_set_departure_time')); // New Command List: sleep 1;iso_wait_slac_matched; iso_set_departure_time; iso_start_v2g_session externalpayment,ac;iso_wait_pwr_ready;iso_draw_power_regulated 16,3;sleep 36000 ``` To pick apart my thought process, let's draw up a truth table: | | departure_time_msg has value | departure_time_msg empty | |-|-----------------------------|------------------------------| | **departure_time_cmd in start/resume** | Update current commands to new command | Remove Existing command | | **departure_time_cmd _not_ in start/resume** | Insert new cmd | NOOP | Likewise, as defined [above](https://github.com/EVerest/everest-demo/issues/64#issuecomment-2231988330), we need to account for the profile reset. Let's assume we've re-set the profile, and are now checking whether or not the user has defined a departureTime. Drawing up another table... | | Update Simulation Profile | |-|-----------------------------| | **departure_time_cmd defined** | Insert cmd | | **departure_time_cmd undefined** | NOOP |

Well, after drafting that up, I think it's time to take a step back: we can do better. Instead of removing or adding the commands (which starts to add complications), what happens if we simply mutate the value within the command? Let's re-do the truth tables from my first attempt

User Inputs new Departure Time

departure_time_msg has value departure_time_msg empty
departure_time_cmd in start/resume Update current commands to new value Update current commands to new value
departure_time_cmd not in start/resume Command will always be present N/A N/A
Update Simulation Profile
departure_time_cmd defined Update Command
departure_time_cmd undefined Update Command

Phew!! I was really gilding the lily with the first approach -- this is way simpler.


To summarize: Going forward, each "simulation profile" will have a iso_set_departure_time command. This command will be one of two values: null, or a 32u value. This means that the signal being sent here is not in absolute parity with the spec, but this approach (i) allows us to include / exclude the extension on the EVManager, and (ii) greatly simplifies the UI code.

shankari commented 1 month ago

Yay! with some fairly obvious changes, this now works!

2024-07-17 00:41:59.842439 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: before adjusting for departure time, max_current 32.000000, nom_voltage 230, pmax 22080

2024-07-17 00:41:59.842500 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: Requested departure time 21600, requested energy 60000.000000

2024-07-17 00:41:59.842541 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: Min hours to charge 2.717391, requested departure time in hours 6.000000, plenty of time to charge, lowering pmax = 1.000000

2024-07-17 00:41:59.843014 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: CHECKME: when is this called and do we need to modify it as well
2024-07-17 00:41:59.925920 [INFO] evse_manager_1:  ::                                     CAR ISO V2G ChargeParameterDiscoveryReq
2024-07-17 00:41:59.981000 [INFO] evse_manager_1:  :: EVSE ISO V2G ChargeParameterDiscoveryRes
2024-07-17 00:41:59.990256 [DEBG] iso15118_car    pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"3968BF77DD9EBDB9"},"Body":{"ChargeParameterDiscoveryRes":{"ResponseCode":"OK","EVSEProcessing":"Finished","SAScheduleList":{"SAScheduleTuple":[{"SAScheduleTupleID":1,"PMaxSchedule":{"PMaxScheduleEntry":[{"RelativeTimeInterval":{"start":0,"duration":21600},"PMax":{"Multiplier":0,"Unit":"W","Value":10000}}]}}]},"AC_EVSEChargeParameter":{"AC_EVSEStatus":{"NotificationMaxDelay":0,"EVSENotification":"None","RCD":false},"EVSENominalVoltage":{"Multiplier":-1,"Unit":"V","Value":2300},"EVSEMaxCurrent":{"Multiplier":-1,"Unit":"A","Value":320}}}}}}

However, the EVSEMaxCurrent needs to be fixed, in the second part of the handler. Not quite sure why we are handling it twice, but whatever...

the-bay-kay commented 1 month ago

Hm, more hiccups -- it doesn't seem to be as simple as "slotting in a new command", I think I'm missing some key aspect of Node-RED. When adding the command with the following code...

function handleDepartureTime() {
    const cmd = flow.get('sim_departure_time');
    let start = flow.get('sim_commands_start').split(';');
    let resume = flow.get('sim_commands_resume').split(';');
    start.splice(3, 1, cmd);
    resume.splice(3, 1, cmd);
    flow.set('sim_comands_start', start.join())
    flow.set('sim_commands_resume', resume.join())
}
if (msg.topic.indexOf('sim_commands') > -1) {
    const s = msg.payload.split('#');
    flow.set('sim_commands_start', s[0]);
    flow.set('sim_commands_stop', s[1]);
    flow.set('sim_commands_pause', s[2]);
    flow.set('sim_commands_resume', s[3]);
    handleDepartureTime();
} else if (msg.topic == 'departure_time') {
    cmd = 'iso_set_departure_time ' + msg.payload
    flow.set('sim_departure_time', cmd);
    handleDepartureTimeUpdate();
} else if (msg.payload == 'start') {
// Code Continues...

And updating the charging profiles accordingly, it appears that the flow contexts are not being properly set: image

What gives? Clearly I'm missing something -- the ",ac" is being interpreted into a full string, and `flow.set('sim_departure_time') does not initialize the context.

the-bay-kay commented 1 month ago

Reading the docs of nodered, I was assuming the addition of a context should be as simple as .set(). It seems there is some initialization step that I've missed, as all 4 contexts are populated upon a fresh deployment. This doesn't seem to occur within the initialize Connector nodes -- I guess I need to do more reading...

the-bay-kay commented 1 month ago

Well, that's an embarrassing typo to miss -- it helps if you spell your context variable names correctly šŸ¤¦ Issue seems to be that I misspelled the start command. Making some tweaks now, will update accordingly.

the-bay-kay commented 1 month ago

Woohoo!! The UI is finally tee'ing up the commands properly. Below is a video of the functionality, and the JSON file of the flow diagram.

https://github.com/user-attachments/assets/6f67939e-2040-4fcb-b03c-e980fc8b5966

flow_with_departureTimes.json

shankari commented 1 month ago

Great! @the-bay-kay now I think you just need to set it in the connection context (similar to the payment mode) and then populate the departure time in PyJosev from that instead of hardcoding it to 0 in build/dist/libexec/everest/3rd_party/josev/iso15118/evcc/controller/simulator.py line 302.

shankari commented 1 month ago

I am fully done with my changes, and they appear to work. We cannot demo what we had originally planned to demo, but we can demo something interesting with departure times. I'm going to edit the main description here (https://github.com/EVerest/everest-demo/issues/64#issue-2409427125) to outline our plans for the this demo and create a follow-up issue for the more complex demo in the future.

EDIT: created issue https://github.com/EVerest/everest-demo/issues/68

the-bay-kay commented 1 month ago

Alright! Time to start setting the commands in context. Since we snuck the command into the start and resume commands sequences, we luckily don't have to edit any of the mqtt routes. So, let's start (somewhat arbitrarily) with JsEvManager.

First things first, I think we can ignore the corresponding mainfest.yaml file, as nothing here pertains to the departureTime changes. Then, we need to look at the index.js. Within this file, it appears there's a few functions we'll need to edit:

It seems like those are the only two places where this file'll need to be changed. The changes themselves seem simple (I already have them mocked up), but I have to go back and tweak the UI so that the base case (no input) passes the length(c.args) check. Once these are written, I need to see where the value should be used in the JsEvManager simulation loop

the-bay-kay commented 1 month ago

Finally figured out how to check for a non-input. I expected "null", or "", but you had to leave the check entirely blank. Now that this is sorted, we have a default value of "null", which can then be parsed in JsEvManager's index.js. Woot!
image

the-bay-kay commented 1 month ago

Cool! I think we can now check off the two boxes. We can incorporate the new command as follows...

JS code added to `index.js` ```js function simdata_reset_defaults(mod) { // More definitions above... mod.v2g_finished = false; mod.iso_stopped = false; mod.iso_departure_time = null; // null if not sent, otherwise 32u // More below... } // intermediate code... function registerAllCommands(mod) { // more definitions above... registerCmd(mod, 'iso_set_departure_time', 1, (mod, c) => { if(length(c.args[0]) !== 'null') { try { // wrap this in a try/catch to filter bad inputs const dt = Number(c.args[0]) mod.iso_departure_time = dt } catch { // We should add some rigerous error handling here. mod.iso_departure_time = null } return // Should this return anything? Let's say no for now. } // "empty" input of null. mod.iso_departure_time = null }) // more below... } ```

Next task is figuring out where we need to use this new mod.iso_departure_time variable!

shankari commented 1 month ago

Checking through all the use cases in https://github.com/EVerest/everest-demo/issues/64#issue-2409427125 before creating the patches and rebuilding the image...

āœ… ISO 15118-2 with EIM ``` 2024-07-17 05:26:52.858781 [INFO] evse_manager_1: :: CAR ISO V2G AuthorizationReq 2024-07-17 05:26:52.946452 [INFO] evse_manager_1: :: EVSE ISO V2G AuthorizationRes 2024-07-17 05:26:52.969742 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"38495F5FD7F4FEF8"},"Body":{"AuthorizationRes":{"ResponseCode":"OK","EVSEProcessing":"Ongoing_WaitingForCustomerInteraction"}}}} 2024-07-17 05:26:52.970081 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: AuthorizationRes received 2024-07-17 05:26:52.970443 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "38495F5FD7F4FEF8"}, "Body": {"AuthorizationReq": {}}}} 2024-07-17 05:26:53.108889 [INFO] token_provider_ :: Publishing new dummy token: {"id_token":{"value":"DEADBEEF","type":"ISO14443"},"authorization_type":"RFID","prevalidated":false,"connectors":[1]} 2024-07-17 05:26:53.111436 [INFO] auth:Auth :: Received new token: { "authorization_type": "RFID", "connectors": [ 1 ], "id_token": { "type": "ISO14443", "value": "DEADBEEF" }, "prevalidated": false } 2024-07-17 05:26:53.119891 [ERRO] ocpp:OCPP201 void ocpp::v201::ChargePoint::handle_message(const ocpp::EnhancedMessage&) :: Handle_message called: [3,"ef4eb97f-c70f-4ef7-918b-558dfc87f4a0",{"idTokenInfo":{"status":"Accepted"}}] 2024-07-17 05:26:53.120003 [ERRO] ocpp:OCPP201 void ocpp::v201::ChargePoint::handle_message(const ocpp::EnhancedMessage&) :: json_message called: [3,"ef4eb97f-c70f-4ef7-918b-558dfc87f4a0",{"idTokenInfo":{"status":"Accepted"}}] 2024-07-17 05:26:53.154799 [INFO] auth:Auth :: Providing authorization to connector#1 2024-07-17 05:26:53.198815 [INFO] evse_manager_1: :: EVSE IEC EIM Authorization received 2024-07-17 05:26:53.243563 [INFO] auth:Auth :: Result for token: DEADBEEF: ACCEPTED 2024-07-17 05:26:53.284737 [INFO] evse_manager_1: :: EVSE IEC Transaction Started (0 kWh) 2024-07-17 05:26:53.285476 [INFO] evse_manager_1: :: EVSE IEC AC mode, HLC enabled(X1), matching already started. We are in X1 so we can go directly to nominal PWM. 2024-07-17 05:26:53.285866 [INFO] evse_manager_1: :: EVSE IEC Charger state: Wait for Auth->PrepareCharging 2024-07-17 05:26:53.286306 [INFO] evse_manager_1: :: EVSE IEC Set PWM On (53.33333611488342%) took 0 ms 2024-07-17 05:26:53.322824 [ERRO] ocpp:OCPP201 void ocpp::v201::ChargePoint::handle_message(const ocpp::EnhancedMessage&) :: Handle_message called: [3,"0e47e5be-2723-4766-9c3e-f8a3c5884c82",{"idTokenInfo":{"status":"Accepted"}}] 2024-07-17 05:26:53.322934 [ERRO] ocpp:OCPP201 void ocpp::v201::ChargePoint::handle_message(const ocpp::EnhancedMessage&) :: json_message called: [3,"0e47e5be-2723-4766-9c3e-f8a3c5884c82",{"idTokenInfo":{"status":"Accepted"}}] 2024-07-17 05:26:53.511130 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Sent AuthorizationReq 2024-07-17 05:26:53.511346 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: IN CPM: Entered state Authorization 2024-07-17 05:26:53.512614 [INFO] evse_manager_1: :: CAR ISO V2G AuthorizationReq 2024-07-17 05:26:53.612152 [INFO] evse_manager_1: :: EVSE ISO V2G AuthorizationRes 2024-07-17 05:26:53.657368 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"38495F5FD7F4FEF8"},"Body":{"AuthorizationRes":{"ResponseCode":"OK","EVSEProcessing":"Finished"}}}} 2024-07-17 05:26:53.658770 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "38495F5FD7F4FEF8"}, "Body": {"ChargeParameterDiscoveryReq": {"RequestedEnergyTransferMode": "AC_three_phase_core", "AC_EVChargeParameter": {"DepartureTime": 0, "EAmount": {"Value": 60, "Multiplier": 3, "Unit": "Wh"}, "EVMaxVoltage": {"Value": 400, "Multiplier": 0, "Unit": "V"}, "EVMaxCurrent": {"Value": 32000, "Multiplier": -3, "Unit": "A"}, "EVMinCurrent": {"Value": 10, "Multiplier": 0, "Unit": "A"}}}}}} 2024-07-17 05:26:53.669817 [INFO] energy_manager: :: NO TRADE 2024-07-17 05:26:53.670003 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 05:26:53.670173 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 05:26:53.670229 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 05:26:53.798979 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 05:26:54.221176 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Sent ChargeParameterDiscoveryReq2024-07-17 05:26:54.221200 [INFO] iso15118_charge :: Parameter-phase started 2024-07-17 05:26:54.221597 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: IN CPM: Entered state ChargeParameterDiscovery 2024-07-17 05:26:54.222291 [INFO] iso15118_charge :: Selected energy transfer mode: AC_three_phase_core 2024-07-17 05:26:54.222384 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: before adjusting for departure time, max_current 32.000000, nom_voltage 230, pmax 22080, departure_duration 0 2024-07-17 05:26:54.222472 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: Requested departure time 0, requested energy 60000.000000 2024-07-17 05:26:54.222630 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: No departure time specified, not modifying defaults 2024-07-17 05:26:54.345396 [INFO] evse_manager_1: :: CAR ISO V2G ChargeParameterDiscoveryReq 2024-07-17 05:26:54.345918 [INFO] evse_manager_1: :: EVSE ISO V2G ChargeParameterDiscoveryRes 2024-07-17 05:26:54.361148 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"38495F5FD7F4FEF8"},"Body":{"ChargeParameterDiscoveryRes":{"ResponseCode":"OK","EVSEProcessing":"Finished","SAScheduleList":{"SAScheduleTuple":[{"SAScheduleTupleID":1,"PMaxSchedule":{"PMaxScheduleEntry":[{"RelativeTimeInterval":{"start":0,"duration":86400},"PMax":{"Multiplier":0,"Unit":"W","Value":22080}}]}}]},"AC_EVSEChargeParameter":{"AC_EVSEStatus":{"NotificationMaxDelay":0,"EVSENotification":"None","RCD":false},"EVSENominalVoltage":{"Multiplier":-1,"Unit":"V","Value":2300},"EVSEMaxCurrent":{"Multiplier":-1,"Unit":"A","Value":320}}}}}} ```
āœ… ISO 15118-2 with PnC ``` 2024-07-17 05:29:42.580675 [INFO] evse_security:E :: Verifying leaf certificate: MO 2024-07-17 05:29:42.581188 [INFO] evse_security:E :: Building new certificate hierarchy! 2024-07-17 05:29:42.583688 [INFO] evse_security:E :: Building new certificate hierarchy! 2024-07-17 05:29:42.590223 [INFO] ocpp:OCPP201 :: Local contract validation result: Valid 2024-07-17 05:29:42.602074 [INFO] ocpp:OCPP201 :: Online: Pass generated OCSP data to CSMS 2024-07-17 05:29:42.673267 [INFO] evse_manager_1: :: EVSE ISO V2G PaymentDetailsRes 2024-07-17 05:29:42.733027 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"1DAFFFFC9FFFCBFD"},"Body":{"PaymentDetailsRes":{"ResponseCode":"OK","GenChallenge":"SHW/LuZPgYXBA2IORcV0KA==","EVSETimeStamp":1721194182}}}} 2024-07-17 05:29:42.733471 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: PaymentDetailsRes received 2024-07-17 05:29:42.733834 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"AuthorizationReq": {"Id": "id1", "GenChallenge": "SHW/LuZPgYXBA2IORcV0KA=="}} 2024-07-17 05:29:42.807949 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=http://www.w3.org/2000/09/xmldsig#): {"SignedInfo": {"CanonicalizationMethod": {"Algorithm": "http://www.w3.org/TR/canonical-exi/"}, "SignatureMethod": {"Algorithm": "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"}, "Reference": [{"Transforms": {"Transform": [{"Algorithm": "http://www.w3.org/TR/canonical-exi/"}]}, "DigestMethod": {"Algorithm": "http://www.w3.org/2001/04/xmlenc#sha256"}, "DigestValue": "igy86RSjDnqr0zgJyHvmA22sw2Pa4MZUjls1fD4wr6Q=", "URI": "#id1"}]}} 2024-07-17 05:29:42.866226 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "1DAFFFFC9FFFCBFD", "Signature": {"SignedInfo": {"CanonicalizationMethod": {"Algorithm": "http://www.w3.org/TR/canonical-exi/"}, "SignatureMethod": {"Algorithm": "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"}, "Reference": [{"Transforms": {"Transform": [{"Algorithm": "http://www.w3.org/TR/canonical-exi/"}]}, "DigestMethod": {"Algorithm": "http://www.w3.org/2001/04/xmlenc#sha256"}, "DigestValue": "igy86RSjDnqr0zgJyHvmA22sw2Pa4MZUjls1fD4wr6Q=", "URI": "#id1"}]}, "SignatureValue": {"value": "7fErTqgPm8AavdXoO66LzuTcm99sXi7jtuCIPEeYdicJFddMk069TeD3BbkrDd7a0DHniDdoIoxQtudSrzktHA=="}}}, "Body": {"AuthorizationReq": {"Id": "id1", "GenChallenge": "SHW/LuZPgYXBA2IORcV0KA=="}}}} 2024-07-17 05:29:43.195410 [INFO] energy_manager: :: NO TRADE 2024-07-17 05:29:43.195570 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 05:29:43.195653 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 05:29:43.195698 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 05:29:43.239967 [INFO] ocpp:OCPP201 :: CSMS idToken status: Accepted 2024-07-17 05:29:43.240037 [ERRO] ocpp:OCPP201 void ocpp::v201::ChargePoint::handle_message(const ocpp::EnhancedMessage&) :: Handle_message called: [3,"c4a03b06-2c3e-4fa2-87ba-e2f429cf7518",{"certificateStatus":"Accepted","idTokenInfo":{"status":"Accepted"}}] 2024-07-17 05:29:43.240078 [INFO] ocpp:OCPP201 :: CSMS certificate status: Accepted 2024-07-17 05:29:43.240163 [ERRO] ocpp:OCPP201 void ocpp::v201::ChargePoint::handle_message(const ocpp::EnhancedMessage&) :: json_message called: [3,"c4a03b06-2c3e-4fa2-87ba-e2f429cf7518",{"certificateStatus":"Accepted","idTokenInfo":{"status":"Accepted"}}] 2024-07-17 05:29:43.242539 [INFO] auth:Auth :: Providing authorization to connector#1 2024-07-17 05:29:43.335486 [INFO] evse_manager_1: :: EVSE IEC Transaction Started (0 kWh) 2024-07-17 05:29:43.336958 [INFO] evse_manager_1: :: EVSE IEC PnC Authorization received 2024-07-17 05:29:43.337172 [INFO] auth:Auth :: Result for token: UKSWI123456789G: ACCEPTED 2024-07-17 05:29:43.337266 [INFO] evse_manager_1: :: EVSE IEC AC mode, HLC enabled, PnC auth received. We will continue with 5percent independent on how we started. 2024-07-17 05:29:43.337710 [INFO] evse_manager_1: :: EVSE IEC Charger state: Wait for Auth->PrepareCharging 2024-07-17 05:29:43.584358 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "1DAFFFFC9FFFCBFD"}, "Body": {"ChargeParameterDiscoveryReq": {"RequestedEnergyTransferMode": "AC_three_phase_core", "AC_EVChargeParameter": {"DepartureTime": 0, "EAmount": {"Value": 60, "Multiplier": 3, "Unit": "Wh"}, "EVMaxVoltage": {"Value": 400, "Multiplier": 0, "Unit": "V"}, "EVMaxCurrent": {"Value": 32000, "Multiplier": -3, "Unit": "A"}, "EVMinCurrent": {"Value": 10, "Multiplier": 0, "Unit": "A"}}}}}} 2024-07-17 05:29:44.130266 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: IN CPM: Entered state ChargeParameterDiscovery 2024-07-17 05:29:44.131397 [INFO] iso15118_charge :: Selected energy transfer mode: AC_three_phase_core 2024-07-17 05:29:44.131434 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: before adjusting for departure time, max_current 32.000000, nom_voltage 230, pmax 22080, departure_duration 0 2024-07-17 05:29:44.131487 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: Requested departure time 0, requested energy 60000.000000 2024-07-17 05:29:44.131639 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: No departure time specified, not modifying defaults 2024-07-17 05:29:44.173059 [INFO] evse_manager_1: :: CAR ISO V2G ChargeParameterDiscoveryReq 2024-07-17 05:29:44.230977 [INFO] evse_manager_1: :: EVSE ISO V2G ChargeParameterDiscoveryRes 2024-07-17 05:29:44.251371 [INFO] energy_manager: :: NO TRADE 2024-07-17 05:29:44.251528 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 05:29:44.251608 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 05:29:44.251649 [INFO] energy_manager: :: evse_manager_1 Enforce limits 32A -9999W 2024-07-17 05:29:44.272120 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 32.000000, we get 32.000000 2024-07-17 05:29:44.280874 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"1DAFFFFC9FFFCBFD"},"Body":{"ChargeParameterDiscoveryRes":{"ResponseCode":"OK","EVSEProcessing":"Finished","SAScheduleList":{"SAScheduleTuple":[{"SAScheduleTupleID":1,"PMaxSchedule":{"PMaxScheduleEntry":[{"RelativeTimeInterval":{"start":0,"duration":86400},"PMax":{"Multiplier":0,"Unit":"W","Value":22080}}]}}]},"AC_EVSEChargeParameter":{"AC_EVSEStatus":{"NotificationMaxDelay":0,"EVSENotification":"None","RCD":false},"EVSENominalVoltage":{"Multiplier":-1,"Unit":"V","Value":2300},"EVSEMaxCurrent":{"Multiplier":-1,"Unit":"A","Value":320}}}}}} ```
āœ… Grid control only: ``` 2024-07-17 05:34:52.012809 [ERRO] ocpp:OCPP201 void ocpp::v201::ChargePoint::handle_set_charging_profile_req(ocpp::Call) :: Received SetChargingProfile: { "chargingProfile": { "chargingProfileKind": "Absolute", "chargingProfilePurpose": "TxDefaultProfile", "chargingSchedule": [ { "chargingRateUnit": "A", "chargingSchedulePeriod": [ { "limit": 10.0, "numberPhases": 3, "startPeriod": 0 } ], "duration": 14400, "id": 0, "minChargingRate": 0.0, "startSchedule": "2024-07-17T05:00:00.000Z" } ], "id": 1, "recurrencyKind": "Daily", "stackLevel": 1 }, "evseId": 0 } with messageId: d68997ec-3f34-4c07-a0b2-35696bb4d236 2024-07-17 05:34:52.013904 [WARN] ocpp:OCPP201 module::OCPP201::ready():: :: Received a new Charging Schedules from the CSMS or another actor. 2024-07-17 05:34:52.014023 [INFO] ocpp:OCPP201 :: ProfileId #1 Kind: Absolute 2024-07-17 05:34:52.015490 [INFO] ocpp:OCPP201 :: #1 find_period_at> 2024-07-17T05:00:00.000Z 2024-07-17 05:34:52.015572 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-17T05:34:52.013Z 2024-07-17 05:34:52.015641 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-17T05:00:00.000Z 2024-07-17 05:34:52.015680 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-17T09:00:00.000Z 2024-07-17 05:34:52.015788 [INFO] ocpp:OCPP201 :: PeriodDateTimePair> period: { "limit": 10.0, "numberPhases": 3, "startPeriod": 0 } end_time: 2024-07-17T09:00:00.000Z 2024-07-17 05:34:52.015854 [INFO] ocpp:OCPP201 :: period.has_value() limit = 6900 2024-07-17 05:34:52.015883 [INFO] ocpp:OCPP201 :: period.has_value() stackLevel = 6900 2024-07-17 05:34:52.015946 [INFO] ocpp:OCPP201 :: ProfileId #1 Kind: Absolute 2024-07-17 05:34:52.016023 [INFO] ocpp:OCPP201 :: #1 find_period_at> 2024-07-17T05:00:00.000Z 2024-07-17 05:34:52.016108 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-17T05:34:52.015Z 2024-07-17 05:34:52.016191 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-17T05:00:00.000Z 2024-07-17 05:34:52.016267 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-17T09:00:00.000Z 2024-07-17 05:34:52.016359 [INFO] ocpp:OCPP201 :: PeriodDateTimePair> period: { "limit": 10.0, "numberPhases": 3, "startPeriod": 0 } end_time: 2024-07-17T09:00:00.000Z 2024-07-17 05:34:52.016552 [INFO] ocpp:OCPP201 :: period.has_value() limit = 6900 2024-07-17 05:34:52.016642 [INFO] ocpp:OCPP201 :: period.has_value() stackLevel = 6900 2024-07-17 05:34:52.016741 [WARN] ocpp:OCPP201 void module::OCPP201::set_external_limits(const std::map&) :: OCPP sets the following external limits for EVSE 1: { "schedule_import": [ { "limits_to_leaves": { "total_power_W": 6900.0 }, "limits_to_root": {}, "timestamp": "2024-07-17T05:34:52.016Z" } ] } 2024-07-17 05:34:52.101397 [ERRO] ocpp:OCPP201 void ocpp::v201::ChargePoint::handle_set_charging_profile_req(ocpp::Call) :: Received profile validity: Validsetting response to { "status": "Accepted" } 2024-07-17 05:34:53.627015 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 10.0, "total_power_W": 6900.0 } 2024-07-17 05:34:53.627201 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 05:34:53.627355 [INFO] energy_manager: :: evse_manager_1 Enforce limits 10A 6900W 2024-07-17 05:37:34.852689 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "04BEFFFD5E3E2D1F"}, "Body": {"ChargeParameterDiscoveryReq": {"RequestedEnergyTransferMode": "AC_three_phase_core", "AC_EVChargeParameter": {"DepartureTime": 0, "EAmount": {"Value": 60, "Multiplier": 3, "Unit": "Wh"}, "EVMaxVoltage": {"Value": 400, "Multiplier": 0, "Unit": "V"}, "EVMaxCurrent": {"Value": 32000, "Multiplier": -3, "Unit": "A"}, "EVMinCurrent": {"Value": 10, "Multiplier": 0, "Unit": "A"}}}}}} 2024-07-17 05:37:35.191665 [INFO] energy_manager: :: NO TRADE 2024-07-17 05:37:35.191813 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 10.0, "total_power_W": 6900.0 } 2024-07-17 05:37:35.191897 [INFO] energy_manager: :: returning optimized values vector of length 1 2024-07-17 05:37:35.191941 [INFO] energy_manager: :: evse_manager_1 Enforce limits 10A 6900W 2024-07-17 05:37:35.237998 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 10.000000, we get 10.000000 2024-07-17 05:37:35.419301 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Sent ChargeParameterDiscoveryReq 2024-07-17 05:37:35.419390 [INFO] iso15118_charge :: Parameter-phase started 2024-07-17 05:37:35.419529 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: IN CPM: Entered state ChargeParameterDiscovery 2024-07-17 05:37:35.421443 [INFO] iso15118_charge :: Selected energy transfer mode: AC_three_phase_core 2024-07-17 05:37:35.421574 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: before adjusting for departure time, max_current 10.000000, nom_voltage 230, pmax 6900, departure_duration 0 2024-07-17 05:37:35.421708 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: Requested departure time 0, requested energy 60000.000000 2024-07-17 05:37:35.421760 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: No departure time specified, not modifying defaults 2024-07-17 05:37:35.464370 [INFO] evse_manager_1: :: CAR ISO V2G ChargeParameterDiscoveryReq 2024-07-17 05:37:35.540813 [INFO] evse_manager_1: :: EVSE ISO V2G ChargeParameterDiscoveryRes 2024-07-17 05:37:35.565544 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"04BEFFFD5E3E2D1F"},"Body":{"ChargeParameterDiscoveryRes":{"ResponseCode":"OK","EVSEProcessing":"Finished","SAScheduleList":{"SAScheduleTuple":[{"SAScheduleTupleID":1,"PMaxSchedule":{"PMaxScheduleEntry":[{"RelativeTimeInterval":{"start":0,"duration":86400},"PMax":{"Multiplier":0,"Unit":"W","Value":6900}}]}}]},"AC_EVSEChargeParameter":{"AC_EVSEStatus":{"NotificationMaxDelay":0,"EVSENotification":"None","RCD":false},"EVSENominalVoltage":{"Multiplier":-1,"Unit":"V","Value":2300},"EVSEMaxCurrent":{"Multiplier":-1,"Unit":"A","Value":100}}}}}} ```
āœ… Car control only: ``` 2024-07-17 05:40:17.936464 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "E99ADD77AEE9AB57"}, "Body": {"ChargeParameterDiscoveryReq": {"RequestedEnergyTransferMode": "AC_three_phase_core", "AC_EVChargeParameter": {"DepartureTime": 21600, "EAmount": {"Value": 60, "Multiplier": 3, "Unit": "Wh"}, "EVMaxVoltage": {"Value": 400, "Multiplier": 0, "Unit": "V"}, "EVMaxCurrent": {"Value": 32000, "Multiplier": -3, "Unit": "A"}, "EVMinCurrent": {"Value": 10, "Multiplier": 0, "Unit": "A"}}}}}} 2024-07-17 05:40:18.491092 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Sent ChargeParameterDiscoveryReq 2024-07-17 05:40:18.491239 [INFO] iso15118_charge :: Parameter-phase started 2024-07-17 05:40:18.491390 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: IN CPM: Entered state ChargeParameterDiscovery 2024-07-17 05:40:18.492649 [INFO] iso15118_charge :: Selected energy transfer mode: AC_three_phase_core 2024-07-17 05:40:18.492750 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: before adjusting for departure time, max_current 32.000000, nom_voltage 230, pmax 22080, departure_duration 21600 2024-07-17 05:40:18.492852 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: Requested departure time 21600, requested energy 60000.000000 2024-07-17 05:40:18.492998 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: Departure time specified, checking to see if we can lower requirements 2024-07-17 05:40:18.493082 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: Min hours to charge 2.717391, requested departure time in hours 6, plenty of time to charge 2024-07-17 05:40:18.493173 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: lowering pmax = 10000, max_current = 15.000000, pmax float = 10000.000000 2024-07-17 05:40:18.536658 [INFO] evse_manager_1: :: CAR ISO V2G ChargeParameterDiscoveryReq 2024-07-17 05:40:18.591812 [INFO] evse_manager_1: :: EVSE ISO V2G ChargeParameterDiscoveryRes 2024-07-17 05:40:18.642948 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"E99ADD77AEE9AB57"},"Body":{"ChargeParameterDiscoveryRes":{"ResponseCode":"OK","EVSEProcessing":"Finished","SAScheduleList":{"SAScheduleTuple":[{"SAScheduleTupleID":1,"PMaxSchedule":{"PMaxScheduleEntry":[{"RelativeTimeInterval":{"start":0,"duration":21600},"PMax":{"Multiplier":0,"Unit":"W","Value":10000}}]}}]},"AC_EVSEChargeParameter":{"AC_EVSEStatus":{"NotificationMaxDelay":0,"EVSENotification":"None","RCD":false},"EVSENominalVoltage":{"Multiplier":-1,"Unit":"V","Value":2300},"EVSEMaxCurrent":{"Multiplier":-1,"Unit":"A","Value":150}}}}}} ```
āœ… Car control only: ``` 2024-07-17 05:42:55.825199 [ERRO] ocpp:OCPP201 void ocpp::v201::ChargePoint::handle_set_charging_profile_req(ocpp::Call) :: Received SetChargingProfile: { "chargingProfile": { "chargingProfileKind": "Absolute", "chargingProfilePurpose": "TxDefaultProfile", "chargingSchedule": [ { "chargingRateUnit": "A", "chargingSchedulePeriod": [ { "limit": 10.0, "numberPhases": 3, "startPeriod": 0 } ], "duration": 14400, "id": 0, "minChargingRate": 0.0, "startSchedule": "2024-07-17T05:00:00.000Z" } ], "id": 1, "recurrencyKind": "Daily", "stackLevel": 1 }, "evseId": 0 } with messageId: e2335550-296a-4788-945c-1ab12d9db16b 2024-07-17 05:42:55.825956 [WARN] ocpp:OCPP201 module::OCPP201::ready():: :: Received a new Charging Schedules from the CSMS or another actor. 2024-07-17 05:42:55.826071 [INFO] ocpp:OCPP201 :: ProfileId #1 Kind: Absolute 2024-07-17 05:42:55.826156 [INFO] ocpp:OCPP201 :: #1 find_period_at> 2024-07-17T05:00:00.000Z 2024-07-17 05:42:55.826229 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-17T05:42:55.826Z 2024-07-17 05:42:55.826295 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-17T05:00:00.000Z 2024-07-17 05:42:55.826379 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-17T09:00:00.000Z 2024-07-17 05:42:55.826485 [INFO] ocpp:OCPP201 :: PeriodDateTimePair> period: { "limit": 10.0, "numberPhases": 3, "startPeriod": 0 } end_time: 2024-07-17T09:00:00.000Z 2024-07-17 05:42:55.826542 [INFO] ocpp:OCPP201 :: period.has_value() limit = 6900 2024-07-17 05:42:55.826599 [INFO] ocpp:OCPP201 :: period.has_value() stackLevel = 6900 2024-07-17 05:42:55.826708 [INFO] ocpp:OCPP201 :: ProfileId #1 Kind: Absolute 2024-07-17 05:42:55.826780 [INFO] ocpp:OCPP201 :: #1 find_period_at> 2024-07-17T05:00:00.000Z 2024-07-17 05:42:55.826818 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-17T05:42:55.826Z 2024-07-17 05:42:55.826874 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-17T05:00:00.000Z 2024-07-17 05:42:55.826914 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-17T09:00:00.000Z 2024-07-17 05:42:55.827017 [INFO] ocpp:OCPP201 :: PeriodDateTimePair> period: { "limit": 10.0, "numberPhases": 3, "startPeriod": 0 } end_time: 2024-07-17T09:00:00.000Z 2024-07-17 05:42:55.827078 [INFO] ocpp:OCPP201 :: period.has_value() limit = 6900 2024-07-17 05:42:55.827183 [INFO] ocpp:OCPP201 :: period.has_value() stackLevel = 6900 2024-07-17 05:42:55.827403 [WARN] ocpp:OCPP201 void module::OCPP201::set_external_limits(const std::map&) :: OCPP sets the following external limits for EVSE 1: { "schedule_import": [ { "limits_to_leaves": { "total_power_W": 6900.0 }, "limits_to_root": {}, "timestamp": "2024-07-17T05:42:55.827Z" } ] } 2024-07-17 05:42:55.870185 [ERRO] ocpp:OCPP201 void ocpp::v201::ChargePoint::handle_set_charging_profile_req(ocpp::Call) :: Received profile validity: Validsetting response to { "status": "Accepted" } 2024-07-17 05:42:56.506056 [INFO] energy_manager: :: NO TRADE 2024-07-17 05:42:56.506315 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 32.0 } 2024-07-17 05:43:51.483290 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "0738DD6AFFFFB167"}, "Body": {"ChargeParameterDiscoveryReq": {"RequestedEnergyTransferMode": "AC_three_phase_core", "AC_EVChargeParameter": {"DepartureTime": 10800, "EAmount": {"Value": 60, "Multiplier": 3, "Unit": "Wh"}, "EVMaxVoltage": {"Value": 400, "Multiplier": 0, "Unit": "V"}, "EVMaxCurrent": {"Value": 32000, "Multiplier": -3, "Unit": "A"}, "EVMinCurrent": {"Value": 10, "Multiplier": 0, "Unit": "A"}}}}}} 2024-07-17 05:43:51.503903 [ERRO] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: In ISO15118 charger impl, after updating AC max current to 10.000000, we get 10.000000 2024-07-17 05:43:52.031880 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Sent ChargeParameterDiscoveryReq 2024-07-17 05:43:52.031926 [INFO] iso15118_charge :: Parameter-phase started 2024-07-17 05:43:52.032167 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: IN CPM: Entered state ChargeParameterDiscovery 2024-07-17 05:43:52.033775 [INFO] iso15118_charge :: Selected energy transfer mode: AC_three_phase_core 2024-07-17 05:43:52.033891 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: before adjusting for departure time, max_current 10.000000, nom_voltage 230, pmax 6900, departure_duration 10800 2024-07-17 05:43:52.033967 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: Requested departure time 10800, requested energy 60000.000000 2024-07-17 05:43:52.034149 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: Departure time specified, checking to see if we can lower requirements 2024-07-17 05:43:52.034241 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: Min hours to charge 8.695652, requested departure time in hours 0.000000, pmax is unchanged 2024-07-17 05:43:52.075350 [INFO] evse_manager_1: :: CAR ISO V2G ChargeParameterDiscoveryReq 2024-07-17 05:43:52.132122 [INFO] evse_manager_1: :: EVSE ISO V2G ChargeParameterDiscoveryRes 2024-07-17 05:43:52.183445 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"0738DD6AFFFFB167"},"Body":{"ChargeParameterDiscoveryRes":{"ResponseCode":"OK","EVSEProcessing":"Finished","SAScheduleList":{"SAScheduleTuple":[{"SAScheduleTupleID":1,"PMaxSchedule":{"PMaxScheduleEntry":[{"RelativeTimeInterval":{"start":0,"duration":10800},"PMax":{"Multiplier":0,"Unit":"W","Value":6900}}]}}]},"AC_EVSEChargeParameter":{"AC_EVSEStatus":{"NotificationMaxDelay":0,"EVSENotification":"None","RCD":false},"EVSENominalVoltage":{"Multiplier":-1,"Unit":"V","Value":2300},"EVSEMaxCurrent":{"Multiplier":-1,"Unit":"A","Value":100}}}}}} ```
āœ… Real world example: ``` 2024-07-17 05:52:13.701297 [ERRO] ocpp:OCPP201 void ocpp::v201::ChargePoint::handle_set_charging_profile_req(ocpp::Call) :: Received SetChargingProfile: { "chargingProfile": { "chargingProfileKind": "Absolute", "chargingProfilePurpose": "TxDefaultProfile", "chargingSchedule": [ { "chargingRateUnit": "A", "chargingSchedulePeriod": [ { "limit": 20.0, "numberPhases": 3, "startPeriod": 0 } ], "duration": 43200, "id": 0, "minChargingRate": 0.0, "startSchedule": "2024-07-17T05:00:00.000Z" } ], "id": 1, "recurrencyKind": "Daily", "stackLevel": 1 }, "evseId": 0 } with messageId: cc632a87-e852-4527-9c79-3468d337d2c2 2024-07-17 05:52:13.702079 [WARN] ocpp:OCPP201 module::OCPP201::ready():: :: Received a new Charging Schedules from the CSMS or another actor. 2024-07-17 05:52:13.702196 [INFO] ocpp:OCPP201 :: ProfileId #1 Kind: Absolute 2024-07-17 05:52:13.702241 [INFO] ocpp:OCPP201 :: #1 find_period_at> 2024-07-17T05:00:00.000Z 2024-07-17 05:52:13.702314 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-17T05:52:13.702Z 2024-07-17 05:52:13.702380 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-17T05:00:00.000Z 2024-07-17 05:52:13.702444 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-17T17:00:00.000Z 2024-07-17 05:52:13.702525 [INFO] ocpp:OCPP201 :: PeriodDateTimePair> period: { "limit": 20.0, "numberPhases": 3, "startPeriod": 0 } end_time: 2024-07-17T17:00:00.000Z 2024-07-17 05:52:13.702642 [INFO] ocpp:OCPP201 :: period.has_value() limit = 13800 2024-07-17 05:52:13.702673 [INFO] ocpp:OCPP201 :: period.has_value() stackLevel = 13800 2024-07-17 05:52:13.702794 [INFO] ocpp:OCPP201 :: ProfileId #1 Kind: Absolute 2024-07-17 05:52:13.702861 [INFO] ocpp:OCPP201 :: #1 find_period_at> 2024-07-17T05:00:00.000Z 2024-07-17 05:52:13.702939 [INFO] ocpp:OCPP201 :: find_period_at> start_time> 2024-07-17T05:52:13.702Z 2024-07-17 05:52:13.703029 [INFO] ocpp:OCPP201 :: find_period_at> period_start_time> 2024-07-17T05:00:00.000Z 2024-07-17 05:52:13.703185 [INFO] ocpp:OCPP201 :: find_period_at> period_end_time> 2024-07-17T17:00:00.000Z 2024-07-17 05:52:13.703336 [INFO] ocpp:OCPP201 :: PeriodDateTimePair> period: { "limit": 20.0, "numberPhases": 3, "startPeriod": 0 } end_time: 2024-07-17T17:00:00.000Z 2024-07-17 05:52:13.703417 [INFO] ocpp:OCPP201 :: period.has_value() limit = 13800 2024-07-17 05:52:13.703514 [INFO] ocpp:OCPP201 :: period.has_value() stackLevel = 13800 2024-07-17 05:52:13.703703 [WARN] ocpp:OCPP201 void module::OCPP201::set_external_limits(const std::map&) :: OCPP sets the following external limits for EVSE 1: { "schedule_import": [ { "limits_to_leaves": { "total_power_W": 13800.0 }, "limits_to_root": {}, "timestamp": "2024-07-17T05:52:13.703Z" } ] } 2024-07-17 05:52:13.746946 [ERRO] ocpp:OCPP201 void ocpp::v201::ChargePoint::handle_set_charging_profile_req(ocpp::Call) :: Received profile validity: Validsetting response to { "status": "Accepted" } 2024-07-17 05:52:14.744009 [INFO] energy_manager: :: NO TRADE 2024-07-17 05:52:14.744212 [INFO] energy_manager: :: Sending enfored limits (import) to :evse_manager_1 { "ac_max_current_A": 20.0, "total_power_W": 13800.0 } 2024-07-17 05:53:02.228504 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "7D7AD7F4FFBB7BF3"}, "Body": {"ChargeParameterDiscoveryReq": {"RequestedEnergyTransferMode": "AC_three_phase_core", "AC_EVChargeParameter": {"DepartureTime": 57600, "EAmount": {"Value": 85, "Multiplier": 3, "Unit": "Wh"}, "EVMaxVoltage": {"Value": 400, "Multiplier": 0, "Unit": "V"}, "EVMaxCurrent": {"Value": 32000, "Multiplier": -3, "Unit": "A"}, "EVMinCurrent": {"Value": 10, "Multiplier": 0, "Unit": "A"}}}}}} 2024-07-17 05:53:02.775731 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Sent ChargeParameterDiscoveryReq 2024-07-17 05:53:02.775782 [INFO] iso15118_charge :: Parameter-phase started 2024-07-17 05:53:02.775972 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: IN CPM: Entered state ChargeParameterDiscovery 2024-07-17 05:53:02.777052 [INFO] iso15118_charge :: Selected energy transfer mode: AC_three_phase_core 2024-07-17 05:53:02.777200 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: before adjusting for departure time, max_current 20.000000, nom_voltage 230, pmax 13800, departure_duration 57600 2024-07-17 05:53:02.777277 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: Requested departure time 57600, requested energy 85000.000000 2024-07-17 05:53:02.777381 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: Departure time specified, checking to see if we can lower requirements 2024-07-17 05:53:02.777478 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: Min hours to charge 6.159420, requested departure time in hours 16, plenty of time to charge 2024-07-17 05:53:02.777545 [WARN] iso15118_charge void dlog_func(dloglevel_t, const char*, int, const char*, const char*, ...) :: lowering pmax = 5313, max_current = 8.000000, pmax float = 5312.500000 2024-07-17 05:53:02.819216 [INFO] evse_manager_1: :: CAR ISO V2G ChargeParameterDiscoveryReq 2024-07-17 05:53:02.875625 [INFO] evse_manager_1: :: EVSE ISO V2G ChargeParameterDiscoveryRes 2024-07-17 05:53:02.923324 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&):: :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"7D7AD7F4FFBB7BF3"},"Body":{"ChargeParameterDiscoveryRes":{"ResponseCode":"OK","EVSEProcessing":"Finished","SAScheduleList":{"SAScheduleTuple":[{"SAScheduleTupleID":1,"PMaxSchedule":{"PMaxScheduleEntry":[{"RelativeTimeInterval":{"start":0,"duration":57600},"PMax":{"Multiplier":0,"Unit":"W","Value":5313}}]}}]},"AC_EVSEChargeParameter":{"AC_EVSEStatus":{"NotificationMaxDelay":0,"EVSENotification":"None","RCD":false},"EVSENominalVoltage":{"Multiplier":-1,"Unit":"V","Value":2300},"EVSEMaxCurrent":{"Multiplier":-1,"Unit":"A","Value":80}}}}}} ```

@the-bay-kay at worst, I can demo tomorrow by editing the python file!

the-bay-kay commented 1 month ago

at worst, I can demo tomorrow by editing the python file!

Oh wonderful! That's good to know at least -- I'll still try to push to get the UI connected, it'd be cool to see the full thing finished this afternoon : )

shankari commented 1 month ago

@the-bay-kay Absolutely! There will be other opportunities to demo the more polished version, including maybe at the JO All Hands!

shankari commented 1 month ago

You should also plumb through the EAmount (either after the departure time or in parallel, depending on whatever is easier). The request is really the combination of the two - think of it in terms of phone charging if you don't have experience with EV charging: "I'm here for 4 hours and I want to fill in enough charge to get to 80%".

"I'm here for 4 hours" alone is not as useful; do you want to just top up a bit before you go home, or do you have plans for a long subway ride and want to make sure that you will be able to listen to music the whole way?

the-bay-kay commented 1 month ago

Ok! Coffee's made, back to it:

shankari commented 1 month ago

@the-bay-kay

But great progress so far, and šŸ¤ž that this is wrapped up soon!

the-bay-kay commented 1 month ago

When adding EAmount:

EDIT: Some more notes on EAmount:

the-bay-kay commented 1 month ago

@shankari , quick clarifying question: Under the hood, the EAmount represents a number of Watt-Hours. Setting this by hand seems rather clunky -- should we make the input a percentage instead? We could then calculate the Watt-Hours needed to reach that percentage on the back-end (though I may need some help with that process!). Because of [V2G 742], we will already need to do some calculations to figure out the WH left in a given charge resumption, so this may be something we want to tack on. If we want completely granular control, however, I can leave the input as the raw EAmount.

shankari commented 1 month ago

We can make the input a %, but then we would need to also allow the user to specify the battery capacity. In cars, similar to phones, you can have a wide variety of battery capacities.

What would be really cool as a future change, IMHO, would be to find a mapping between car (make, model year) and battery capacity (ideally through an API) and then allow users to specify that and the %.

Actually, I think we can do that with the EPA database if we specify miles. EPA has an MPGe or similar rating for electric cars. If we can hook into that, we can allow users to specify make, model, year and miles needed. We should then be able to calculate MPGe and then convert that back to energy. And honestly that is what makes the most sense from a user perspective - I want to make sure that I have enough miles to get to my destination.

https://en.wikipedia.org/wiki/Miles_per_gallon_gasoline_equivalent

the-bay-kay commented 1 month ago

That would be cool! Makes sense -- for now, I'll stick with the raw EAmount for ease of implementation,

(Though ease may be the word, I don't know why setting a flow context is so finicky... Definitely still missing something lol)

the-bay-kay commented 1 month ago

OK -- I had to use change nodes to set flow contexts (I couldn't just set them from the JS, which seems bizarre to me -- everything I've read said you could do so without any initialization.....), so we've got both signal values being set now.

For bookkeeping, here's the JSON file: flow_w_eadt.json