| /* |
| * |
| * Copyright (c) 2023 Project CHIP Authors |
| * All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <EVSEManufacturerImpl.h> |
| #include <EnergyEvseManager.h> |
| #include <app/clusters/energy-evse-server/EnergyEvseTestEventTriggerDelegate.h> |
| |
| using namespace chip; |
| using namespace chip::app; |
| using namespace chip::app::Clusters; |
| using namespace chip::app::Clusters::EnergyEvse; |
| |
| CHIP_ERROR EVSEManufacturer::Init() |
| { |
| /* Manufacturers should modify this to do any custom initialisation */ |
| |
| /* Register callbacks */ |
| EnergyEvseDelegate * dg = GetEvseManufacturer()->GetDelegate(); |
| if (dg == nullptr) |
| { |
| ChipLogError(AppServer, "EVSE Delegate is not initialized"); |
| return CHIP_ERROR_UNINITIALIZED; |
| } |
| |
| dg->HwRegisterEvseCallbackHandler(ApplicationCallbackHandler, reinterpret_cast<intptr_t>(this)); |
| |
| /* |
| * This is an example implementation for manufacturers to consider |
| * |
| * For Manufacturer to specify the hardware capability in mA: |
| * dg->HwSetMaxHardwareCurrentLimit(32000); // 32A |
| * |
| * For Manufacturer to specify the CircuitCapacity in mA (e.g. from DIP switches) |
| * dg->HwSetCircuitCapacity(20000); // 20A |
| * |
| */ |
| |
| /* Once the system is initialised then check to see if the state was restored |
| * (e.g. after a power outage), and if the Enable timer check needs to be started |
| */ |
| dg->ScheduleCheckOnEnabledTimeout(); |
| |
| return CHIP_NO_ERROR; |
| } |
| |
| /* |
| * When the EV is plugged in, and asking for demand change the state |
| * and set the CableAssembly current limit |
| * |
| * EnergyEvseDelegate * dg = GetEvseManufacturer()->GetDelegate(); |
| * if (dg == nullptr) |
| * { |
| * ChipLogError(AppServer, "Delegate is not initialized"); |
| * return CHIP_ERROR_UNINITIALIZED; |
| * } |
| * |
| * dg->HwSetState(StateEnum::kPluggedInDemand); |
| * dg->HwSetCableAssemblyLimit(63000); // 63A = 63000mA |
| * |
| * |
| * If the vehicle ID can be retrieved (e.g. over Powerline) |
| * dg->HwSetVehicleID(CharSpan::fromCharString("TEST_VEHICLE_123456789")); |
| * |
| * |
| * If the EVSE has an RFID sensor, the RFID value read can cause an event to be sent |
| * (e.g. can be used to indicate if a user as tried to activate the charging) |
| * |
| * uint8_t uid[10] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE }; |
| * dg->HwSetRFID(ByteSpan(uid)); |
| */ |
| |
| CHIP_ERROR EVSEManufacturer::Shutdown() |
| { |
| return CHIP_NO_ERROR; |
| } |
| |
| /** |
| * @brief Main Callback handler - to be implemented by Manufacturer |
| * |
| * @param EVSECbInfo describes the type of call back, and a union of structs |
| * which contain relevant info for the specific callback type |
| * |
| * @param arg - optional pointer to some context information (see register function) |
| */ |
| void EVSEManufacturer::ApplicationCallbackHandler(const EVSECbInfo * cb, intptr_t arg) |
| { |
| EVSEManufacturer * pClass = reinterpret_cast<EVSEManufacturer *>(arg); |
| |
| switch (cb->type) |
| { |
| case EVSECallbackType::StateChanged: |
| ChipLogProgress(AppServer, "EVSE callback - state changed"); |
| break; |
| case EVSECallbackType::ChargeCurrentChanged: |
| ChipLogProgress(AppServer, "EVSE callback - maxChargeCurrent changed to %ld", |
| static_cast<long>(cb->ChargingCurrent.maximumChargeCurrent)); |
| break; |
| case EVSECallbackType::EnergyMeterReadingRequested: |
| ChipLogProgress(AppServer, "EVSE callback - EnergyMeterReadingRequested"); |
| if (cb->EnergyMeterReadingRequest.meterType == ChargingDischargingType::kCharging) |
| { |
| *(cb->EnergyMeterReadingRequest.energyMeterValuePtr) = pClass->mLastChargingEnergyMeter; |
| } |
| else |
| { |
| *(cb->EnergyMeterReadingRequest.energyMeterValuePtr) = pClass->mLastDischargingEnergyMeter; |
| } |
| break; |
| |
| default: |
| ChipLogError(AppServer, "Unhandled EVSE Callback type %d", static_cast<int>(cb->type)); |
| } |
| } |
| |
| struct EVSETestEventSaveData |
| { |
| int64_t mOldMaxHardwareCurrentLimit; |
| int64_t mOldCircuitCapacity; |
| int64_t mOldUserMaximumChargeCurrent; |
| int64_t mOldCableAssemblyLimit; |
| StateEnum mOldHwStateBasic; /* For storing hwState before Basic Func event */ |
| StateEnum mOldHwStatePluggedIn; /* For storing hwState before PluggedIn event */ |
| StateEnum mOldHwStatePluggedInDemand; /* For storing hwState before PluggedInDemand event */ |
| }; |
| |
| static EVSETestEventSaveData sEVSETestEventSaveData; |
| |
| EnergyEvseDelegate * GetEvseDelegate() |
| { |
| EVSEManufacturer * mn = GetEvseManufacturer(); |
| VerifyOrDieWithMsg(mn != nullptr, AppServer, "EVSEManufacturer is null"); |
| EnergyEvseDelegate * dg = mn->GetDelegate(); |
| VerifyOrDieWithMsg(dg != nullptr, AppServer, "EVSE Delegate is null"); |
| |
| return dg; |
| } |
| |
| void SetTestEventTrigger_BasicFunctionality() |
| { |
| EnergyEvseDelegate * dg = GetEvseDelegate(); |
| |
| sEVSETestEventSaveData.mOldMaxHardwareCurrentLimit = dg->HwGetMaxHardwareCurrentLimit(); |
| sEVSETestEventSaveData.mOldCircuitCapacity = dg->GetCircuitCapacity(); |
| sEVSETestEventSaveData.mOldUserMaximumChargeCurrent = dg->GetUserMaximumChargeCurrent(); |
| sEVSETestEventSaveData.mOldHwStateBasic = dg->HwGetState(); |
| |
| dg->HwSetMaxHardwareCurrentLimit(32000); |
| dg->HwSetCircuitCapacity(32000); |
| dg->SetUserMaximumChargeCurrent(32000); |
| dg->HwSetState(StateEnum::kNotPluggedIn); |
| } |
| void SetTestEventTrigger_BasicFunctionalityClear() |
| { |
| EnergyEvseDelegate * dg = GetEvseDelegate(); |
| |
| dg->HwSetMaxHardwareCurrentLimit(sEVSETestEventSaveData.mOldMaxHardwareCurrentLimit); |
| dg->HwSetCircuitCapacity(sEVSETestEventSaveData.mOldCircuitCapacity); |
| dg->SetUserMaximumChargeCurrent(sEVSETestEventSaveData.mOldUserMaximumChargeCurrent); |
| dg->HwSetState(sEVSETestEventSaveData.mOldHwStateBasic); |
| } |
| void SetTestEventTrigger_EVPluggedIn() |
| { |
| EnergyEvseDelegate * dg = GetEvseDelegate(); |
| |
| sEVSETestEventSaveData.mOldCableAssemblyLimit = dg->HwGetCableAssemblyLimit(); |
| sEVSETestEventSaveData.mOldHwStatePluggedIn = dg->HwGetState(); |
| |
| dg->HwSetCableAssemblyLimit(63000); |
| dg->HwSetState(StateEnum::kPluggedInNoDemand); |
| } |
| void SetTestEventTrigger_EVPluggedInClear() |
| { |
| EnergyEvseDelegate * dg = GetEvseDelegate(); |
| dg->HwSetCableAssemblyLimit(sEVSETestEventSaveData.mOldCableAssemblyLimit); |
| dg->HwSetState(sEVSETestEventSaveData.mOldHwStatePluggedIn); |
| } |
| |
| void SetTestEventTrigger_EVChargeDemand() |
| { |
| EnergyEvseDelegate * dg = GetEvseDelegate(); |
| |
| sEVSETestEventSaveData.mOldHwStatePluggedInDemand = dg->HwGetState(); |
| dg->HwSetState(StateEnum::kPluggedInDemand); |
| } |
| void SetTestEventTrigger_EVChargeDemandClear() |
| { |
| EnergyEvseDelegate * dg = GetEvseDelegate(); |
| |
| dg->HwSetState(sEVSETestEventSaveData.mOldHwStatePluggedInDemand); |
| } |
| void SetTestEventTrigger_EVSEGroundFault() |
| { |
| EnergyEvseDelegate * dg = GetEvseDelegate(); |
| |
| dg->HwSetFault(FaultStateEnum::kGroundFault); |
| } |
| |
| void SetTestEventTrigger_EVSEOverTemperatureFault() |
| { |
| EnergyEvseDelegate * dg = GetEvseDelegate(); |
| |
| dg->HwSetFault(FaultStateEnum::kOverTemperature); |
| } |
| |
| void SetTestEventTrigger_EVSEFaultClear() |
| { |
| EnergyEvseDelegate * dg = GetEvseDelegate(); |
| |
| dg->HwSetFault(FaultStateEnum::kNoError); |
| } |
| |
| void SetTestEventTrigger_EVSEDiagnosticsComplete() |
| { |
| EnergyEvseDelegate * dg = GetEvseDelegate(); |
| |
| dg->HwDiagnosticsComplete(); |
| } |
| |
| bool HandleEnergyEvseTestEventTrigger(uint64_t eventTrigger) |
| { |
| EnergyEvseTrigger trigger = static_cast<EnergyEvseTrigger>(eventTrigger); |
| |
| switch (trigger) |
| { |
| case EnergyEvseTrigger::kBasicFunctionality: |
| ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => Basic Functionality install"); |
| SetTestEventTrigger_BasicFunctionality(); |
| break; |
| case EnergyEvseTrigger::kBasicFunctionalityClear: |
| ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => Basic Functionality clear"); |
| SetTestEventTrigger_BasicFunctionalityClear(); |
| break; |
| case EnergyEvseTrigger::kEVPluggedIn: |
| ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EV plugged in"); |
| SetTestEventTrigger_EVPluggedIn(); |
| break; |
| case EnergyEvseTrigger::kEVPluggedInClear: |
| ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EV unplugged"); |
| SetTestEventTrigger_EVPluggedInClear(); |
| break; |
| case EnergyEvseTrigger::kEVChargeDemand: |
| ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EV Charge Demand"); |
| SetTestEventTrigger_EVChargeDemand(); |
| break; |
| case EnergyEvseTrigger::kEVChargeDemandClear: |
| ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EV Charge NoDemand"); |
| SetTestEventTrigger_EVChargeDemandClear(); |
| break; |
| case EnergyEvseTrigger::kEVSEGroundFault: |
| ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EVSE has a GroundFault fault"); |
| SetTestEventTrigger_EVSEGroundFault(); |
| break; |
| case EnergyEvseTrigger::kEVSEOverTemperatureFault: |
| ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EVSE has a OverTemperature fault"); |
| SetTestEventTrigger_EVSEOverTemperatureFault(); |
| break; |
| case EnergyEvseTrigger::kEVSEFaultClear: |
| ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EVSE faults have cleared"); |
| SetTestEventTrigger_EVSEFaultClear(); |
| break; |
| case EnergyEvseTrigger::kEVSEDiagnosticsComplete: |
| ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EVSE Diagnostics Completed"); |
| SetTestEventTrigger_EVSEDiagnosticsComplete(); |
| break; |
| |
| default: |
| return false; |
| } |
| |
| return true; |
| } |