diff --git a/SUPPORTED_DEVICE_TYPES.md b/SUPPORTED_DEVICE_TYPES.md index 2b3fec027..991716e5e 100644 --- a/SUPPORTED_DEVICE_TYPES.md +++ b/SUPPORTED_DEVICE_TYPES.md @@ -69,3 +69,4 @@ i. Appliance 6. Oven 7. Cook Surface 8. Cooktop +9. Energy Evse diff --git a/components/esp_matter/esp_matter_attribute.cpp b/components/esp_matter/esp_matter_attribute.cpp index fa8cb9c07..29f774e91 100644 --- a/components/esp_matter/esp_matter_attribute.cpp +++ b/components/esp_matter/esp_matter_attribute.cpp @@ -4443,5 +4443,127 @@ attribute_t *create_cumulative_energy_reset(cluster_t *cluster, const uint8_t* v } /* attribute */ } /* electrical_energy_measurement */ +namespace energy_evse { +namespace attribute { + +attribute_t *create_state(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::State::Id, ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_enum8(value)); +} + +attribute_t *create_supply_state(cluster_t *cluster, uint8_t value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::SupplyState::Id, ATTRIBUTE_FLAG_NONE, esp_matter_enum8(value)); +} + +attribute_t *create_fault_state(cluster_t *cluster, uint8_t value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::FaultState::Id, ATTRIBUTE_FLAG_NONE, esp_matter_enum8(value)); +} + +attribute_t *create_charging_enabled_until(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::ChargingEnabledUntil::Id, ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_nullable_uint32(value)); +} + +attribute_t *create_discharging_enabled_until(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::DischargingEnabledUntil::Id, ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_nullable_uint32(value)); +} + +attribute_t *create_circuit_capacity(cluster_t *cluster, int64_t value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::CircuitCapacity::Id, ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_int64(value)); +} + +attribute_t *create_minimum_charge_current(cluster_t *cluster, int64_t value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::MinimumChargeCurrent::Id, ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_int64(value)); +} + +attribute_t *create_maximum_charge_current(cluster_t *cluster, int64_t value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::MaximumChargeCurrent::Id, ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_int64(value)); +} + +attribute_t *create_maximum_discharge_current(cluster_t *cluster, int64_t value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::MaximumDischargeCurrent::Id, ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_int64(value)); +} + +attribute_t *create_user_maximum_charge_current(cluster_t *cluster, int64_t value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::UserMaximumChargeCurrent::Id, ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_int64(value)); +} + +attribute_t *create_randomization_delay_window(cluster_t *cluster, uint32_t value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::RandomizationDelayWindow::Id, ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_uint32(value)); +} + +attribute_t *create_next_charge_start_time(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::NextChargeStartTime::Id, ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint32(value)); +} + +attribute_t *create_next_charge_target_time(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::NextChargeTargetTime::Id, ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint32(value)); +} + +attribute_t *create_next_charge_required_energy(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::NextChargeRequiredEnergy::Id, ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_int64(value)); +} + +attribute_t *create_next_charge_target_soc(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::NextChargeTargetSoC::Id, ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); +} + +attribute_t *create_approximate_ev_efficiency(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::ApproximateEVEfficiency::Id, ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_nullable_uint16(value)); +} + +attribute_t *create_state_of_charge(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::StateOfCharge::Id, ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); +} + +attribute_t *create_battery_capacity(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::BatteryCapacity::Id, ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_int64(value)); +} + +attribute_t *create_vehicle_id(cluster_t *cluster, char *value, uint16_t length) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::VehicleID::Id, ATTRIBUTE_FLAG_NULLABLE, + esp_matter_char_str(value, length)); +} + +attribute_t *create_session_id(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::SessionID::Id, ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_nullable_uint32(value)); +} + +attribute_t *create_session_duration(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::SessionDuration::Id, ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_nullable_uint32(value)); +} + +attribute_t *create_session_energy_charged(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::SessionEnergyCharged::Id, ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_nullable_int64(value)); +} + +attribute_t *create_session_energy_discharged(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, EnergyEvse::Attributes::SessionEnergyDischarged::Id, ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_nullable_int64(value)); +} + +} /* attribute */ +} /* energy_evse */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_attribute.h b/components/esp_matter/esp_matter_attribute.h index 7945d0108..b4a7f61dd 100644 --- a/components/esp_matter/esp_matter_attribute.h +++ b/components/esp_matter/esp_matter_attribute.h @@ -1012,5 +1012,33 @@ attribute_t *create_cumulative_energy_reset(cluster_t *cluster, const uint8_t* v } /* attribute */ } /* electrical_energy_measurement */ +namespace energy_evse { +namespace attribute { +attribute_t *create_state(cluster_t *cluster, nullable value); +attribute_t *create_supply_state(cluster_t *cluster, uint8_t value); +attribute_t *create_fault_state(cluster_t *cluster, uint8_t value); +attribute_t *create_charging_enabled_until(cluster_t *cluster, nullable value); +attribute_t *create_discharging_enabled_until(cluster_t *cluster, nullable value); +attribute_t *create_circuit_capacity(cluster_t *cluster, int64_t value); +attribute_t *create_minimum_charge_current(cluster_t *cluster, int64_t value); +attribute_t *create_maximum_charge_current(cluster_t *cluster, int64_t value); +attribute_t *create_maximum_discharge_current(cluster_t *cluster, int64_t value); +attribute_t *create_user_maximum_charge_current(cluster_t *cluster, int64_t value); +attribute_t *create_randomization_delay_window(cluster_t *cluster, uint32_t value); +attribute_t *create_next_charge_start_time(cluster_t *cluster, nullable value); +attribute_t *create_next_charge_target_time(cluster_t *cluster, nullable value); +attribute_t *create_next_charge_required_energy(cluster_t *cluster, nullable value); +attribute_t *create_next_charge_target_soc(cluster_t *cluster, nullable value); +attribute_t *create_approximate_ev_efficiency(cluster_t *cluster, nullable value); +attribute_t *create_state_of_charge(cluster_t *cluster, nullable value); +attribute_t *create_battery_capacity(cluster_t *cluster, nullable value); +attribute_t *create_vehicle_id(cluster_t *cluster, char *value, uint16_t length); +attribute_t *create_session_id(cluster_t *cluster, nullable value); +attribute_t *create_session_duration(cluster_t *cluster, nullable value); +attribute_t *create_session_energy_charged(cluster_t *cluster, nullable value); +attribute_t *create_session_energy_discharged(cluster_t *cluster, nullable value); +} /* attribute */ +} /* energy_evse */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_cluster.cpp b/components/esp_matter/esp_matter_cluster.cpp index c760a3e09..526240dca 100644 --- a/components/esp_matter/esp_matter_cluster.cpp +++ b/components/esp_matter/esp_matter_cluster.cpp @@ -3691,6 +3691,112 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_ } } /* electrical_energy_measurement */ +namespace energy_evse_mode { +const function_generic_t *function_list = NULL; +const int function_flags = CLUSTER_FLAG_NONE; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) +{ + cluster_t *cluster = cluster::create(endpoint, EnergyEvseMode::Id, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + + if (flags & CLUSTER_FLAG_SERVER) { + if (config -> delegate != nullptr) { + static const auto delegate_init_cb = EnergyEvseModeDelegateInitCB; + set_delegate_and_init_callback(cluster, delegate_init_cb, config->delegate); + } + add_function_list(cluster, function_list, function_flags); + + /* Attributes managed internally */ + global::attribute::create_feature_map(cluster, 0); + global::attribute::create_event_list(cluster, NULL, 0, 0); + mode_base::attribute::create_supported_modes(cluster, NULL, 0, 0); + + /* Attributes not managed internally */ + if (config) { + global::attribute::create_cluster_revision(cluster, config->cluster_revision); + mode_base::attribute::create_current_mode(cluster, config->current_mode); + } else { + ESP_LOGE(TAG, "Config is NULL. Cannot add some attributes."); + } + } + + /* Commands */ + mode_base::command::create_change_to_mode(cluster); + + return cluster; +} +} /* energy_evse_mode */ + +namespace energy_evse { +const function_generic_t *function_list = NULL; +const int function_flags = CLUSTER_FLAG_NONE; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features) +{ + cluster_t *cluster = cluster::create(endpoint, EnergyEvse::Id, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + + if (flags & CLUSTER_FLAG_SERVER) { + if (config -> delegate != nullptr) { + static const auto delegate_init_cb = EnergyEvseDelegateInitCB; + set_delegate_and_init_callback(cluster, delegate_init_cb, config->delegate); + } + add_function_list(cluster, function_list, function_flags); + + /* Attributes managed internally */ + global::attribute::create_feature_map(cluster, 0); + global::attribute::create_event_list(cluster, NULL, 0, 0); + attribute::create_state(cluster, 0); + attribute::create_supply_state(cluster, 0); + attribute::create_fault_state(cluster, 0); + attribute::create_charging_enabled_until(cluster, 0); + attribute::create_circuit_capacity(cluster, 0); + attribute::create_minimum_charge_current(cluster, 0); + attribute::create_maximum_charge_current(cluster, 0); + attribute::create_session_id(cluster, 0); + attribute::create_session_duration(cluster, 0); + attribute::create_session_energy_charged(cluster, 0); + + /* Attributes not managed internally */ + if (config) { + global::attribute::create_cluster_revision(cluster, config->cluster_revision); + } else { + ESP_LOGE(TAG, "Config is NULL. Cannot add some attributes."); + } + } + + /* Features */ + if (features & feature::charging_preferences::get_id()) { + feature::charging_preferences::add(cluster); + } + if (features & feature::soc_reporting::get_id()) { + feature::soc_reporting::add(cluster); + } + if (features & feature::plug_and_charge::get_id()) { + feature::plug_and_charge::add(cluster); + } + if (features & feature::rfid::get_id()) { + feature::rfid::add(cluster); + } + if (features & feature::v2x::get_id()) { + feature::v2x::add(cluster); + } + + /* Commands */ + command::create_disable(cluster); + command::create_enable_charging(cluster); + + return cluster; +} +} /* energy_evse */ + // namespace binary_input_basic { // // ToDo // } /* binary_input_basic */ diff --git a/components/esp_matter/esp_matter_cluster.h b/components/esp_matter/esp_matter_cluster.h index 7890b61fb..5598e0cf1 100644 --- a/components/esp_matter/esp_matter_cluster.h +++ b/components/esp_matter/esp_matter_cluster.h @@ -886,5 +886,26 @@ typedef struct config { cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features); } /* electrical_energy_measurement */ +namespace energy_evse_mode { +typedef struct config { + uint16_t cluster_revision; + uint8_t current_mode; + void *delegate; + config() : cluster_revision(1), current_mode(0), delegate(nullptr) {} +} config_t; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); +} /* energy_evse_mode */ + +namespace energy_evse { +typedef struct config { + uint16_t cluster_revision; + void *delegate; + config() : cluster_revision(1), delegate(nullptr) {} +} config_t; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features); +} /* energy_evse */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_command.cpp b/components/esp_matter/esp_matter_command.cpp index d5698ff7a..9bb6a9848 100644 --- a/components/esp_matter/esp_matter_command.cpp +++ b/components/esp_matter/esp_matter_command.cpp @@ -2719,6 +2719,51 @@ command_t *create_enable_disable_alarm(cluster_t *cluster) } /* command */ } /* boolean_state_configuration */ +namespace energy_evse { +namespace command { +command_t *create_disable(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, EnergyEvse::Commands::Disable::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_enable_charging(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, EnergyEvse::Commands::EnableCharging::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_enable_discharging(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, EnergyEvse::Commands::EnableDischarging::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_start_diagnostics(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, EnergyEvse::Commands::StartDiagnostics::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_set_targets(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, EnergyEvse::Commands::SetTargets::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_get_targets(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, EnergyEvse::Commands::GetTargets::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_clear_targets(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, EnergyEvse::Commands::ClearTargets::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_get_targets_response(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, EnergyEvse::Commands::GetTargetsResponse::Id, COMMAND_FLAG_GENERATED, NULL); +} + +} /* command */ +} /* energy_evse */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_command.h b/components/esp_matter/esp_matter_command.h index 1948b60f3..5b783ed26 100644 --- a/components/esp_matter/esp_matter_command.h +++ b/components/esp_matter/esp_matter_command.h @@ -377,5 +377,18 @@ command_t *create_enable_disable_alarm(cluster_t *cluster); } /* command */ } /* boolean_state_configuration */ +namespace energy_evse { +namespace command { +command_t *create_disable(cluster_t *cluster); +command_t *create_enable_charging(cluster_t *cluster); +command_t *create_enable_discharging(cluster_t *cluster); +command_t *create_start_diagnostics(cluster_t *cluster); +command_t *create_set_targets(cluster_t *cluster); +command_t *create_get_targets(cluster_t *cluster); +command_t *create_clear_targets(cluster_t *cluster); +command_t *create_get_targets_response(cluster_t *cluster); +} /* command */ +} /* energy_evse */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_delegate_callbacks.cpp b/components/esp_matter/esp_matter_delegate_callbacks.cpp index bda884ad5..1d564fb5f 100644 --- a/components/esp_matter/esp_matter_delegate_callbacks.cpp +++ b/components/esp_matter/esp_matter_delegate_callbacks.cpp @@ -17,7 +17,7 @@ #include #include #include - +#include using namespace chip::app::Clusters; namespace esp_matter { @@ -76,6 +76,25 @@ void RvcCleanModeDelegateInitCB(void *delegate, uint16_t endpoint_id) InitModeDelegate(delegate, endpoint_id, RvcCleanMode::Id); } +void EnergyEvseModeDelegateInitCB(void *delegate, uint16_t endpoint_id) +{ + InitModeDelegate(delegate, endpoint_id, EnergyEvseMode::Id); +} + +void EnergyEvseDelegateInitCB(void *delegate, uint16_t endpoint_id) +{ + if(delegate == nullptr) + { + return; + } + static EnergyEvse::Instance * energyEvseInstance = nullptr; + EnergyEvse::Delegate *energy_evse_delegate = static_cast(delegate); + uint32_t feature_map = get_feature_map_value(endpoint_id, EnergyEvse::Id); + energyEvseInstance = new EnergyEvse::Instance(endpoint_id, *energy_evse_delegate, chip::BitMask(feature_map), + chip::BitMask(), chip::BitMask()); + energyEvseInstance->Init(); +} + } // namespace delegate_cb } // namespace cluster diff --git a/components/esp_matter/esp_matter_delegate_callbacks.h b/components/esp_matter/esp_matter_delegate_callbacks.h index 8b58eb72d..f95a76877 100644 --- a/components/esp_matter/esp_matter_delegate_callbacks.h +++ b/components/esp_matter/esp_matter_delegate_callbacks.h @@ -22,6 +22,8 @@ void DishWasherModeDelegateInitCB(void *delegate, uint16_t endpoint_id); void RefrigeratorAndTCCModeDelegateInitCB(void *delegate, uint16_t endpoint_id); void RvcRunModeDelegateInitCB(void *delegate, uint16_t endpoint_id); void RvcCleanModeDelegateInitCB(void *delegate, uint16_t endpoint_id); +void EnergyEvseModeDelegateInitCB(void *delegate, uint16_t endpoint_id); +void EnergyEvseDelegateInitCB(void *delegate, uint16_t endpoint_id); } // namespace delegate_cb } // namespace cluster diff --git a/components/esp_matter/esp_matter_endpoint.cpp b/components/esp_matter/esp_matter_endpoint.cpp index 4aa60d9a2..adce6ae40 100644 --- a/components/esp_matter/esp_matter_endpoint.cpp +++ b/components/esp_matter/esp_matter_endpoint.cpp @@ -1753,6 +1753,44 @@ esp_err_t add(endpoint_t *endpoint, config_t *config) } } /* cooktop */ +namespace energy_evse { +uint32_t get_device_type_id() +{ + return ESP_MATTER_ENERGY_EVSE_DEVICE_TYPE_ID; +} + +uint8_t get_device_type_version() +{ + return ESP_MATTER_ENERGY_EVSE_DEVICE_TYPE_VERSION; +} + +endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_data) +{ + endpoint_t *endpoint = endpoint::create(node, flags, priv_data); + add(endpoint, config); + return endpoint; +} + +esp_err_t add(endpoint_t *endpoint, config_t *config) +{ + if (!endpoint) { + ESP_LOGE(TAG, "Endpoint cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + esp_err_t err = add_device_type(endpoint, get_device_type_id(), get_device_type_version()); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to add device type id:%" PRIu32 ",err: %d", get_device_type_id(), err); + return err; + } + + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); + cluster::energy_evse::create(endpoint, &(config->energy_evse), CLUSTER_FLAG_SERVER, ESP_MATTER_NONE_FEATURE_ID); + energy_evse_mode::create(endpoint, &(config->energy_evse_mode), CLUSTER_FLAG_SERVER); + + return ESP_OK; +} +} /* energy_evse */ + } /* endpoint */ namespace node { diff --git a/components/esp_matter/esp_matter_endpoint.h b/components/esp_matter/esp_matter_endpoint.h index 7068936f6..b059b9a3d 100644 --- a/components/esp_matter/esp_matter_endpoint.h +++ b/components/esp_matter/esp_matter_endpoint.h @@ -110,6 +110,8 @@ #define ESP_MATTER_OVEN_DEVICE_TYPE_VERSION 1 #define ESP_MATTER_WATER_FREEZE_DETECTOR_DEVICE_TYPE_ID 0x0041 #define ESP_MATTER_WATER_FREEZE_DETECTOR_DEVICE_TYPE_VERSION 1 +#define ESP_MATTER_ENERGY_EVSE_DEVICE_TYPE_ID 0x050C +#define ESP_MATTER_ENERGY_EVSE_DEVICE_TYPE_VERSION 1 namespace esp_matter { @@ -707,6 +709,19 @@ endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_dat esp_err_t add(endpoint_t *endpoint, config_t *config); } /* cooktop */ +namespace energy_evse { +typedef struct config { + cluster::descriptor::config_t descriptor; + cluster::energy_evse::config_t energy_evse; + cluster::energy_evse_mode::config_t energy_evse_mode; +} config_t; + +uint32_t get_device_type_id(); +uint8_t get_device_type_version(); +endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_data); +esp_err_t add(endpoint_t *endpoint, config_t *config); +} /* energy_evse */ + } /* endpoint */ namespace node { diff --git a/components/esp_matter/esp_matter_feature.cpp b/components/esp_matter/esp_matter_feature.cpp index 715e76210..5c58608fc 100644 --- a/components/esp_matter/esp_matter_feature.cpp +++ b/components/esp_matter/esp_matter_feature.cpp @@ -4297,5 +4297,135 @@ esp_err_t add(cluster_t *cluster) } /* feature */ } /* door_lock */ +namespace energy_evse { +namespace feature { +namespace charging_preferences { + +uint32_t get_id() +{ + return (uint32_t)EnergyEvse::Feature::kChargingPreferences; +} + +esp_err_t add(cluster_t *cluster) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + update_feature_map(cluster, get_id()); + + /* Attributes managed internally */ + attribute::create_next_charge_start_time(cluster, 0); + attribute::create_next_charge_target_time(cluster, 0); + attribute::create_next_charge_required_energy(cluster, 0); + attribute::create_next_charge_target_soc(cluster, 0); + + /* Commands */ + command::create_set_targets(cluster); + command::create_get_targets(cluster); + command::create_clear_targets(cluster); + command::create_get_targets_response(cluster); + return ESP_OK; +} + +} /* charging_preferences */ + +namespace soc_reporting { + +uint32_t get_id() +{ + return (uint32_t)EnergyEvse::Feature::kSoCReporting; +} + +esp_err_t add(cluster_t *cluster) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + update_feature_map(cluster, get_id()); + + /* Attributes managed internally */ + attribute::create_state_of_charge(cluster, 0); + attribute::create_battery_capacity(cluster, 0); + + return ESP_OK; +} + +} /* soc_reporting */ + +namespace plug_and_charge { + +uint32_t get_id() +{ + return (uint32_t)EnergyEvse::Feature::kPlugAndCharge; +} + +esp_err_t add(cluster_t *cluster) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + update_feature_map(cluster, get_id()); + + /* Attributes managed internally */ + attribute::create_vehicle_id(cluster, NULL, 0); + + return ESP_OK; +} + +} /* plug_and_charge */ + +namespace rfid { + +uint32_t get_id() +{ + return (uint32_t)EnergyEvse::Feature::kRfid; +} + +esp_err_t add(cluster_t *cluster) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + update_feature_map(cluster, get_id()); + + return ESP_OK; +} + +} /* rfid */ + +namespace v2x { + +uint32_t get_id() +{ + return (uint32_t)EnergyEvse::Feature::kV2x; +} + +esp_err_t add(cluster_t *cluster) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + update_feature_map(cluster, get_id()); + + /* Attributes managed internally */ + attribute::create_discharging_enabled_until(cluster, 0); + attribute::create_maximum_discharge_current(cluster, 0); + attribute::create_session_energy_discharged(cluster, 0); + + /* Commands */ + command::create_enable_discharging(cluster); + return ESP_OK; +} + +} /* v2x*/ + +} /* feature */ +} /* energy_evse */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_feature.h b/components/esp_matter/esp_matter_feature.h index 9c6962f52..65854c63f 100644 --- a/components/esp_matter/esp_matter_feature.h +++ b/components/esp_matter/esp_matter_feature.h @@ -146,6 +146,7 @@ esp_err_t add(cluster_t *cluster); } /* feature */ } /* scenes_management */ + namespace icd_management { namespace feature { namespace check_in_protocol_support { @@ -1944,5 +1945,45 @@ esp_err_t add(cluster_t *cluster); } /* feature */ }/* door_lock */ +namespace energy_evse { +namespace feature { +namespace charging_preferences { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); + +} /* charging_preferences */ + +namespace soc_reporting { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); + +} /* soc_reporting */ + +namespace plug_and_charge { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); + +} /* plug_and_charge */ + +namespace rfid { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); + +} /* rfid */ + +namespace v2x { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); + +} /* v2x */ + +} /* feature */ +} /* energy_evse */ + } /* cluster */ } /* esp_matter */ diff --git a/docs/en/app_guide.rst b/docs/en/app_guide.rst index 9ad1671de..08d7daacb 100644 --- a/docs/en/app_guide.rst +++ b/docs/en/app_guide.rst @@ -58,7 +58,15 @@ ModeWaterHeater, ModeRefrigerator, ModeLaundryWasher and ModeMicrowaveOven. , `Laundry Washer Mode`_ , `Dish Washer Mode`_ , `Rvc Run And Rvc Clean Mode`_ + , `Energy Evse Mode`_ +9.1.2 Energy Evse Cluster +------------------------- + +.. csv-table:: Delegate and its impl + :header: "Delegate Class", "Reference Implementation" + + `Energy Evse`_, `Energy Evse Delegate`_ .. note:: Make sure that after implementing delegate class, you set the delegate class pointer at the time of creating cluster. @@ -74,3 +82,6 @@ ModeWaterHeater, ModeRefrigerator, ModeLaundryWasher and ModeMicrowaveOven. .. _`Laundry Washer Mode`: https://github.com/project-chip/connectedhomeip/blob/master/examples/all-clusters-app/all-clusters-common/include/laundry-washer-mode.h .. _`Dish Washer Mode`: https://github.com/project-chip/connectedhomeip/blob/master/examples/all-clusters-app/all-clusters-common/include/dishwasher-mode.h .. _`Rvc Run And Rvc Clean Mode`: https://github.com/project-chip/connectedhomeip/blob/master/examples/all-clusters-app/all-clusters-common/include/rvc-modes.h +.. _`Energy Evse Mode`: https://github.com/project-chip/connectedhomeip/blob/master/examples/all-clusters-app/all-clusters-common/include/energy-evse-modes.h +.. _`Energy Evse`: https://github.com/project-chip/connectedhomeip/blob/master/src/app/clusters/energy-evse-server/energy-evse-server.h +.. _`Energy Evse Delegate`: https://github.com/project-chip/connectedhomeip/blob/master/examples/energy-management-app/energy-management-common/include/EnergyEvseDelegateImpl.h diff --git a/examples/all_device_types_app/main/device_types.h b/examples/all_device_types_app/main/device_types.h index 7b9f64c32..b598c3415 100644 --- a/examples/all_device_types_app/main/device_types.h +++ b/examples/all_device_types_app/main/device_types.h @@ -44,6 +44,7 @@ enum device_type_enum { ESP_MATTER_ELECTRICAL_SENSOR, ESP_MATTER_OVEN, ESP_MATTER_COOKTOP, + ESP_MATTER_ENERGY_EVSE, ESP_MATTER_DEVICE_TYPE_MAX }; @@ -93,6 +94,7 @@ const device_type_name device_type_list[ESP_MATTER_DEVICE_TYPE_MAX] = { {"rain_sensor", ESP_MATTER_RAIN_SENSOR}, {"electrical_sensor", ESP_MATTER_ELECTRICAL_SENSOR}, {"oven", ESP_MATTER_OVEN}, - {"cooktop", ESP_MATTER_COOKTOP} + {"cooktop", ESP_MATTER_COOKTOP}, + {"energy_evse", ESP_MATTER_ENERGY_EVSE} }; } /* namespace esp_matter */ diff --git a/examples/all_device_types_app/main/esp_matter_console_helpers.cpp b/examples/all_device_types_app/main/esp_matter_console_helpers.cpp index 8b842467c..16c1582e5 100644 --- a/examples/all_device_types_app/main/esp_matter_console_helpers.cpp +++ b/examples/all_device_types_app/main/esp_matter_console_helpers.cpp @@ -404,6 +404,21 @@ int create(uint8_t device_type_index) endpoint = esp_matter::endpoint::cooktop::create(node, &cooktop_config, ENDPOINT_FLAG_NONE, NULL); break; } + case ESP_MATTER_ENERGY_EVSE: { + esp_matter::endpoint::energy_evse::config_t energy_evse_config; + endpoint = esp_matter::endpoint::energy_evse::create(node, &energy_evse_config, ENDPOINT_FLAG_NONE, NULL); + + esp_matter::endpoint::power_source_device::config_t power_source_config; + esp_matter::endpoint_t *ps_endpoint = esp_matter::endpoint::power_source_device::create(node, &power_source_config, ENDPOINT_FLAG_NONE, NULL); + esp_matter::endpoint::electrical_sensor::config_t electrical_sensor_config; + esp_matter::endpoint::electrical_sensor::add(ps_endpoint, &electrical_sensor_config); + + if (!ps_endpoint) { + ESP_LOGE(TAG, "Matter create endpoint failed"); + return 1; + } + break; + } default: { ESP_LOGE(TAG, "Please input a valid device type"); break;