diff --git a/components/esp_matter/esp_matter_attribute.cpp b/components/esp_matter/esp_matter_attribute.cpp index 6e91fa5f5..1d16c2047 100644 --- a/components/esp_matter/esp_matter_attribute.cpp +++ b/components/esp_matter/esp_matter_attribute.cpp @@ -263,7 +263,8 @@ namespace attribute { attribute_t *create_binding(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count) { - return esp_matter::attribute::create(cluster, Binding::Attributes::Binding::Id, ATTRIBUTE_FLAG_WRITABLE, + return esp_matter::attribute::create(cluster, Binding::Attributes::Binding::Id, + ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_array(value, length, count)); } @@ -276,7 +277,8 @@ namespace attribute { attribute_t *create_default_ota_providers(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count) { return esp_matter::attribute::create(cluster, OtaSoftwareUpdateRequestor::Attributes::DefaultOtaProviders::Id, - ATTRIBUTE_FLAG_WRITABLE, esp_matter_array(value, length, count)); + ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NONVOLATILE, + esp_matter_array(value, length, count)); } attribute_t *create_update_possible(cluster_t *cluster, bool value) @@ -291,10 +293,10 @@ attribute_t *create_update_state(cluster_t *cluster, uint8_t value) ATTRIBUTE_FLAG_NONE, esp_matter_enum8(value)); } -attribute_t *create_update_state_progress(cluster_t *cluster, uint8_t value) +attribute_t *create_update_state_progress(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, OtaSoftwareUpdateRequestor::Attributes::UpdateStateProgress::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint8(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); } } /* attribute */ @@ -369,10 +371,10 @@ attribute_t *create_interface_enabled(cluster_t *cluster, bool value) ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_bool(value)); } -attribute_t *create_last_networking_status(cluster_t *cluster, uint8_t value) +attribute_t *create_last_networking_status(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, NetworkCommissioning::Attributes::LastNetworkingStatus::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_enum8(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); } attribute_t *create_last_network_id(cluster_t *cluster, uint8_t *value, uint16_t length) @@ -381,10 +383,10 @@ attribute_t *create_last_network_id(cluster_t *cluster, uint8_t *value, uint16_t ATTRIBUTE_FLAG_NULLABLE, esp_matter_octet_str(value, length)); } -attribute_t *create_last_connect_error_value(cluster_t *cluster, int32_t value) +attribute_t *create_last_connect_error_value(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, NetworkCommissioning::Attributes::LastConnectErrorValue::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_int32(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_int32(value)); } } /* attribute */ @@ -520,76 +522,76 @@ attribute_t *create_bssid(cluster_t *cluster, uint8_t *value, uint16_t length) ATTRIBUTE_FLAG_NULLABLE, esp_matter_octet_str(value, length)); } -attribute_t *create_security_type(cluster_t *cluster, uint8_t value) +attribute_t *create_security_type(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, WiFiNetworkDiagnostics::Attributes::SecurityType::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_enum8(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_enum8(value)); } -attribute_t *create_wifi_version(cluster_t *cluster, uint8_t value) +attribute_t *create_wifi_version(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, WiFiNetworkDiagnostics::Attributes::WiFiVersion::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_enum8(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); } -attribute_t *create_channel_number(cluster_t *cluster, uint16_t value) +attribute_t *create_channel_number(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, WiFiNetworkDiagnostics::Attributes::ChannelNumber::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint16(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint16(value)); } -attribute_t *create_rssi(cluster_t *cluster, int8_t value) +attribute_t *create_rssi(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, WiFiNetworkDiagnostics::Attributes::Rssi::Id, ATTRIBUTE_FLAG_NULLABLE, - esp_matter_int8(value)); + esp_matter_nullable_int8(value)); } -attribute_t *create_beacon_lost_count(cluster_t *cluster, uint32_t value) +attribute_t *create_beacon_lost_count(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, WiFiNetworkDiagnostics::Attributes::BeaconLostCount::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint32(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint32(value)); } -attribute_t *create_beacon_rx_count(cluster_t *cluster, uint32_t value) +attribute_t *create_beacon_rx_count(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, WiFiNetworkDiagnostics::Attributes::BeaconRxCount::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint32(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint32(value)); } -attribute_t *create_packet_multicast_rx_count(cluster_t *cluster, uint32_t value) +attribute_t *create_packet_multicast_rx_count(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, WiFiNetworkDiagnostics::Attributes::PacketMulticastRxCount::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint32(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint32(value)); } -attribute_t *create_packet_multicast_tx_count(cluster_t *cluster, uint32_t value) +attribute_t *create_packet_multicast_tx_count(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, WiFiNetworkDiagnostics::Attributes::PacketMulticastTxCount::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint32(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint32(value)); } -attribute_t *create_packet_unicast_rx_count(cluster_t *cluster, uint32_t value) +attribute_t *create_packet_unicast_rx_count(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, WiFiNetworkDiagnostics::Attributes::PacketUnicastRxCount::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint32(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint32(value)); } -attribute_t *create_packet_unicast_tx_count(cluster_t *cluster, uint32_t value) +attribute_t *create_packet_unicast_tx_count(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, WiFiNetworkDiagnostics::Attributes::PacketUnicastTxCount::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint32(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint32(value)); } -attribute_t *create_current_max_rate(cluster_t *cluster, uint64_t value) +attribute_t *create_current_max_rate(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, WiFiNetworkDiagnostics::Attributes::CurrentMaxRate::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint64(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint64(value)); } -attribute_t *create_overrun_count(cluster_t *cluster, uint64_t value) +attribute_t *create_overrun_count(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, WiFiNetworkDiagnostics::Attributes::OverrunCount::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint64(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint64(value)); } } /* attribute */ @@ -598,16 +600,16 @@ attribute_t *create_overrun_count(cluster_t *cluster, uint64_t value) namespace diagnostics_network_thread { namespace attribute { -attribute_t *create_channel(cluster_t *cluster, uint16_t value) +attribute_t *create_channel(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, ThreadNetworkDiagnostics::Attributes::Channel::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint16(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint16(value)); } -attribute_t *create_routing_role(cluster_t *cluster, uint8_t value) +attribute_t *create_routing_role(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, ThreadNetworkDiagnostics::Attributes::RoutingRole::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_enum8(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); } attribute_t *create_network_name(cluster_t *cluster, char *value, uint16_t length) @@ -616,16 +618,16 @@ attribute_t *create_network_name(cluster_t *cluster, char *value, uint16_t lengt ATTRIBUTE_FLAG_NULLABLE, esp_matter_char_str(value, length)); } -attribute_t *create_pan_id(cluster_t *cluster, uint16_t value) +attribute_t *create_pan_id(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, ThreadNetworkDiagnostics::Attributes::PanId::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint16(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint16(value)); } -attribute_t *create_extended_pan_id(cluster_t *cluster, uint64_t value) +attribute_t *create_extended_pan_id(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, ThreadNetworkDiagnostics::Attributes::ExtendedPanId::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint64(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint64(value)); } attribute_t *create_mesh_local_prefix(cluster_t *cluster, uint8_t *value, uint16_t length) @@ -646,34 +648,34 @@ attribute_t *create_route_table(cluster_t *cluster, uint8_t *value, uint16_t len ATTRIBUTE_FLAG_NONE, esp_matter_array(value, length, count)); } -attribute_t *create_partition_id(cluster_t *cluster, uint32_t value) +attribute_t *create_partition_id(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, ThreadNetworkDiagnostics::Attributes::PartitionId::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint32(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint32(value)); } -attribute_t *create_weighting(cluster_t *cluster, uint8_t value) +attribute_t *create_weighting(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, ThreadNetworkDiagnostics::Attributes::Weighting::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint8(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); } -attribute_t *create_data_version(cluster_t *cluster, uint8_t value) +attribute_t *create_data_version(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, ThreadNetworkDiagnostics::Attributes::DataVersion::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint8(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); } -attribute_t *create_stable_data_version(cluster_t *cluster, uint8_t value) +attribute_t *create_stable_data_version(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, ThreadNetworkDiagnostics::Attributes::StableDataVersion::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint8(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); } -attribute_t *create_leader_router_id(cluster_t *cluster, uint8_t value) +attribute_t *create_leader_router_id(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, ThreadNetworkDiagnostics::Attributes::LeaderRouterId::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint8(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); } attribute_t *create_security_policy(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count) @@ -728,7 +730,8 @@ namespace attribute { attribute_t *create_label_list(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count) { - return esp_matter::attribute::create(cluster, UserLabel::Attributes::LabelList::Id, ATTRIBUTE_FLAG_WRITABLE, + return esp_matter::attribute::create(cluster, UserLabel::Attributes::LabelList::Id, + ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_array(value, length, count)); } @@ -834,23 +837,25 @@ attribute_t *create_global_scene_control(cluster_t *cluster, bool value) esp_matter_bool(value)); } -attribute_t *create_on_time(cluster_t *cluster, uint16_t value) +attribute_t *create_on_time(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, OnOff::Attributes::OnTime::Id, - ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint16(value)); + ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NULLABLE, + esp_matter_nullable_uint16(value)); } -attribute_t *create_off_wait_time(cluster_t *cluster, uint16_t value) +attribute_t *create_off_wait_time(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, OnOff::Attributes::OffWaitTime::Id, - ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint16(value)); + ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NULLABLE, + esp_matter_nullable_uint16(value)); } -attribute_t *create_start_up_on_off(cluster_t *cluster, uint8_t value) +attribute_t *create_start_up_on_off(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, OnOff::Attributes::StartUpOnOff::Id, ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NONVOLATILE | ATTRIBUTE_FLAG_NULLABLE, - esp_matter_enum8(value)); + esp_matter_nullable_enum8(value)); } } /* attribute */ @@ -859,16 +864,18 @@ attribute_t *create_start_up_on_off(cluster_t *cluster, uint8_t value) namespace level_control { namespace attribute { -attribute_t *create_current_level(cluster_t *cluster, uint8_t value) +attribute_t *create_current_level(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, LevelControl::Attributes::CurrentLevel::Id, - ATTRIBUTE_FLAG_NONVOLATILE | ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint8(value)); + ATTRIBUTE_FLAG_NONVOLATILE | ATTRIBUTE_FLAG_NULLABLE, + esp_matter_nullable_uint8(value)); } -attribute_t *create_on_level(cluster_t *cluster, uint8_t value) +attribute_t *create_on_level(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, LevelControl::Attributes::OnLevel::Id, - ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint8(value)); + ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NULLABLE, + esp_matter_nullable_uint8(value)); } attribute_t *create_options(cluster_t *cluster, uint8_t value, uint8_t min, uint8_t max) @@ -925,29 +932,32 @@ attribute_t *create_on_off_transition_time(cluster_t *cluster, uint16_t value) ATTRIBUTE_FLAG_WRITABLE, esp_matter_uint16(value)); } -attribute_t *create_on_transition_time(cluster_t* cluster, uint16_t value) +attribute_t *create_on_transition_time(cluster_t* cluster, nullable value) { return esp_matter::attribute::create(cluster, LevelControl::Attributes::OnTransitionTime::Id, - ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint16(value)); + ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NULLABLE, + esp_matter_nullable_uint16(value)); } -attribute_t *create_off_transition_time(cluster_t* cluster, uint16_t value) +attribute_t *create_off_transition_time(cluster_t* cluster, nullable value) { return esp_matter::attribute::create(cluster, LevelControl::Attributes::OffTransitionTime::Id, - ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint16(value)); + ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NULLABLE, + esp_matter_nullable_uint16(value)); } -attribute_t *create_default_move_rate(cluster_t* cluster, uint8_t value) +attribute_t *create_default_move_rate(cluster_t* cluster, nullable value) { return esp_matter::attribute::create(cluster, LevelControl::Attributes::DefaultMoveRate::Id, - ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint8(value)); + ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NULLABLE, + esp_matter_nullable_uint8(value)); } -attribute_t *create_start_up_current_level(cluster_t *cluster, uint8_t value) +attribute_t *create_start_up_current_level(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, LevelControl::Attributes::StartUpCurrentLevel::Id, ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_NONVOLATILE, - esp_matter_uint8(value)); + esp_matter_nullable_uint8(value)); } } /* attribute */ @@ -1022,10 +1032,11 @@ attribute_t *create_couple_color_temp_to_level_min_mireds(cluster_t *cluster, ui ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); } -attribute_t *create_startup_color_temperature_mireds(cluster_t *cluster, uint16_t value) +attribute_t *create_startup_color_temperature_mireds(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, ColorControl::Attributes::StartUpColorTemperatureMireds::Id, - ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_WRITABLE, esp_matter_uint16(value)); + ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_WRITABLE, + esp_matter_nullable_uint16(value)); } attribute_t *create_current_x(cluster_t *cluster, uint16_t value) @@ -1076,10 +1087,10 @@ attribute_t *create_color_loop_stored_enhanced_hue(cluster_t *cluster, uint16_t ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); } -attribute_t *create_number_of_primaries(cluster_t *cluster, uint8_t value) +attribute_t *create_number_of_primaries(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, ColorControl::Attributes::NumberOfPrimaries::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint8(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); } attribute_t *create_primary_n_x(cluster_t * cluster, uint16_t value, uint8_t index) @@ -1148,32 +1159,32 @@ attribute_t *create_primary_n_y(cluster_t * cluster, uint16_t value, uint8_t ind return NULL; } -attribute_t *create_primary_n_intensity(cluster_t * cluster, uint8_t value, uint8_t index) +attribute_t *create_primary_n_intensity(cluster_t * cluster, nullable value, uint8_t index) { switch (index) { case 1: return esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary1Intensity::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint8(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); break; case 2: return esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary2Intensity::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint8(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); break; case 3: return esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary3Intensity::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint8(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); break; case 4: return esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary4Intensity::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint8(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); break; case 5: return esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary5Intensity::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint8(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); break; case 6: return esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary6Intensity::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint8(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); break; default: break; @@ -1199,10 +1210,11 @@ attribute_t *create_fan_mode_sequence(cluster_t *cluster, uint8_t value) ATTRIBUTE_FLAG_NONVOLATILE | ATTRIBUTE_FLAG_WRITABLE, esp_matter_enum8(value)); } -attribute_t *create_percent_setting(cluster_t *cluster, uint8_t value) +attribute_t *create_percent_setting(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, FanControl::Attributes::PercentSetting::Id, - ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_WRITABLE, esp_matter_uint8(value)); + ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_WRITABLE, + esp_matter_nullable_uint8(value)); } attribute_t *create_percent_current(cluster_t *cluster, uint8_t value) @@ -1217,10 +1229,10 @@ attribute_t *create_percent_current(cluster_t *cluster, uint8_t value) namespace thermostat { namespace attribute { -attribute_t *create_local_temperature(cluster_t *cluster, int16_t value) +attribute_t *create_local_temperature(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, Thermostat::Attributes::LocalTemperature::Id, ATTRIBUTE_FLAG_NULLABLE, - esp_matter_int16(value)); + esp_matter_nullable_int16(value)); } attribute_t *create_occupied_cooling_setpoint(cluster_t *cluster, int16_t value) @@ -1268,10 +1280,10 @@ attribute_t *create_system_mode(cluster_t *cluster, uint8_t value, uint8_t min, namespace door_lock { namespace attribute { -attribute_t *create_lock_state(cluster_t *cluster, uint8_t value) +attribute_t *create_lock_state(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, DoorLock::Attributes::LockState::Id, ATTRIBUTE_FLAG_NULLABLE, - esp_matter_enum8(value)); + esp_matter_nullable_uint8(value)); } attribute_t *create_lock_type(cluster_t *cluster, uint8_t value) @@ -1334,16 +1346,18 @@ attribute_t *create_physical_closed_limit_tilt(cluster_t *cluster, uint16_t valu esp_matter_uint16(value)); } -attribute_t *create_current_position_lift(cluster_t *cluster, uint8_t value) +attribute_t *create_current_position_lift(cluster_t *cluster, nullable value) { - return esp_matter::attribute::create(cluster, WindowCovering::Attributes::CurrentPositionLift::Id, ATTRIBUTE_FLAG_NULLABLE | - ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_uint16(value)); + return esp_matter::attribute::create(cluster, WindowCovering::Attributes::CurrentPositionLift::Id, + ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_NONVOLATILE, + esp_matter_nullable_uint16(value)); } -attribute_t *create_current_position_tilt(cluster_t *cluster, uint8_t value) +attribute_t *create_current_position_tilt(cluster_t *cluster, nullable value) { - return esp_matter::attribute::create(cluster, WindowCovering::Attributes::CurrentPositionTilt::Id, ATTRIBUTE_FLAG_NULLABLE | - ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_uint16(value)); + return esp_matter::attribute::create(cluster, WindowCovering::Attributes::CurrentPositionTilt::Id, + ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_NONVOLATILE, + esp_matter_nullable_uint16(value)); } attribute_t *create_number_of_actuations_lift(cluster_t *cluster, uint16_t value) @@ -1364,34 +1378,36 @@ attribute_t *create_config_status(cluster_t *cluster, uint8_t value) esp_matter_bitmap8(value)); } -attribute_t *create_current_position_lift_percentage(cluster_t *cluster, uint8_t value) +attribute_t *create_current_position_lift_percentage(cluster_t *cluster, nullable value) { - return esp_matter::attribute::create(cluster, WindowCovering::Attributes::CurrentPositionLiftPercentage::Id, ATTRIBUTE_FLAG_NONVOLATILE | - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint8(value)); + return esp_matter::attribute::create(cluster, WindowCovering::Attributes::CurrentPositionLiftPercentage::Id, + ATTRIBUTE_FLAG_NONVOLATILE | ATTRIBUTE_FLAG_NULLABLE, + esp_matter_nullable_uint8(value)); } -attribute_t *create_current_position_tilt_percentage(cluster_t *cluster, uint8_t value) +attribute_t *create_current_position_tilt_percentage(cluster_t *cluster, nullable value) { - return esp_matter::attribute::create(cluster, WindowCovering::Attributes::CurrentPositionTiltPercentage::Id, ATTRIBUTE_FLAG_NONVOLATILE | - ATTRIBUTE_FLAG_NULLABLE, esp_matter_uint8(value)); + return esp_matter::attribute::create(cluster, WindowCovering::Attributes::CurrentPositionTiltPercentage::Id, + ATTRIBUTE_FLAG_NONVOLATILE | ATTRIBUTE_FLAG_NULLABLE, + esp_matter_nullable_uint8(value)); } -attribute_t *create_operational_status(cluster_t *cluster, uint8_t value) +attribute_t *create_operational_status(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, WindowCovering::Attributes::OperationalStatus::Id, ATTRIBUTE_FLAG_NULLABLE, - esp_matter_bitmap8(value)); + esp_matter_nullable_uint8(value)); } -attribute_t *create_target_position_lift_percent_100ths(cluster_t *cluster, uint16_t value) +attribute_t *create_target_position_lift_percent_100ths(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, WindowCovering::Attributes::TargetPositionLiftPercent100ths::Id, ATTRIBUTE_FLAG_NULLABLE, - esp_matter_uint16(value)); + esp_matter_nullable_uint16(value)); } -attribute_t *create_target_position_tilt_percent_100ths(cluster_t *cluster, uint16_t value) +attribute_t *create_target_position_tilt_percent_100ths(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, WindowCovering::Attributes::TargetPositionTiltPercent100ths::Id, ATTRIBUTE_FLAG_NULLABLE, - esp_matter_uint16(value)); + esp_matter_nullable_uint16(value)); } attribute_t *create_end_product_type(cluster_t *cluster, uint8_t value) @@ -1400,16 +1416,18 @@ attribute_t *create_end_product_type(cluster_t *cluster, uint8_t value) esp_matter_enum8(value)); } -attribute_t *create_current_position_lift_percent_100ths(cluster_t *cluster, uint16_t value) +attribute_t *create_current_position_lift_percent_100ths(cluster_t *cluster, nullable value) { - return esp_matter::attribute::create(cluster, WindowCovering::Attributes::CurrentPositionLiftPercent100ths::Id, ATTRIBUTE_FLAG_NULLABLE | - ATTRIBUTE_MASK_NONVOLATILE, esp_matter_uint16(value)); + return esp_matter::attribute::create(cluster, WindowCovering::Attributes::CurrentPositionLiftPercent100ths::Id, + ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_MASK_NONVOLATILE, + esp_matter_nullable_uint16(value)); } -attribute_t *create_current_position_tilt_percent_100ths(cluster_t *cluster, uint16_t value) +attribute_t *create_current_position_tilt_percent_100ths(cluster_t *cluster, nullable value) { - return esp_matter::attribute::create(cluster, WindowCovering::Attributes::CurrentPositionTiltPercent100ths::Id, ATTRIBUTE_FLAG_NULLABLE | - ATTRIBUTE_MASK_NONVOLATILE, esp_matter_uint16(value)); + return esp_matter::attribute::create(cluster, WindowCovering::Attributes::CurrentPositionTiltPercent100ths::Id, + ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_MASK_NONVOLATILE, + esp_matter_nullable_uint16(value)); } attribute_t *create_installed_open_limit_lift(cluster_t *cluster, uint16_t value) @@ -1478,22 +1496,22 @@ attribute_t *create_multi_press_max(cluster_t *cluster, uint8_t value) namespace temperature_measurement { namespace attribute { -attribute_t *create_temperature_measured_value(cluster_t *cluster, int16_t value) +attribute_t *create_temperature_measured_value(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, TemperatureMeasurement::Attributes::MeasuredValue::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_int16(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_int16(value)); } -attribute_t *create_temperature_min_measured_value(cluster_t *cluster, int16_t value) +attribute_t *create_temperature_min_measured_value(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, TemperatureMeasurement::Attributes::MinMeasuredValue::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_int16(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_int16(value)); } -attribute_t *create_temperature_max_measured_value(cluster_t *cluster, int16_t value) +attribute_t *create_temperature_max_measured_value(cluster_t *cluster, nullable value) { return esp_matter::attribute::create(cluster, TemperatureMeasurement::Attributes::MaxMeasuredValue::Id, - ATTRIBUTE_FLAG_NULLABLE, esp_matter_int16(value)); + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_int16(value)); } } /* attribute */ diff --git a/components/esp_matter/esp_matter_attribute.h b/components/esp_matter/esp_matter_attribute.h index c250ccf64..734c3c63a 100644 --- a/components/esp_matter/esp_matter_attribute.h +++ b/components/esp_matter/esp_matter_attribute.h @@ -76,7 +76,7 @@ attribute_t *create_software_version_string(cluster_t *cluster, char *value, uin attribute_t *create_capability_minima(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count); /** These attributes are optional for the cluster, but when added to this cluster, the value is maintained internally. - * If the attributes are added in some other cluster, then the value is not maintained internally. + * If the attributes are added in some other cluster, then the value is not maintained internally. **/ attribute_t *create_manufacturing_date(cluster_t *cluster, char *value, uint16_t length); attribute_t *create_part_number(cluster_t *cluster, char *value, uint16_t length); @@ -100,7 +100,7 @@ namespace attribute { attribute_t *create_default_ota_providers(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count); attribute_t *create_update_possible(cluster_t *cluster, bool value); attribute_t *create_update_state(cluster_t *cluster, uint8_t value); -attribute_t *create_update_state_progress(cluster_t *cluster, uint8_t value); +attribute_t *create_update_state_progress(cluster_t *cluster, nullable value); } /* attribute */ } /* ota_requestor */ @@ -121,9 +121,9 @@ attribute_t *create_networks(cluster_t *cluster, uint8_t *value, uint16_t length attribute_t *create_scan_max_time_seconds(cluster_t *cluster, uint8_t value); attribute_t *create_connect_max_time_seconds(cluster_t *cluster, uint8_t value); attribute_t *create_interface_enabled(cluster_t *cluster, bool value); -attribute_t *create_last_networking_status(cluster_t *cluster, uint8_t value); +attribute_t *create_last_networking_status(cluster_t *cluster, nullable value); attribute_t *create_last_network_id(cluster_t *cluster, uint8_t *value, uint16_t length); -attribute_t *create_last_connect_error_value(cluster_t *cluster, int32_t value); +attribute_t *create_last_connect_error_value(cluster_t *cluster, nullable value); } /* attribute */ } /* network_commissioning */ @@ -166,40 +166,40 @@ attribute_t *create_max_group_keys_per_fabric(cluster_t *cluster, uint16_t value namespace diagnostics_network_wifi { namespace attribute { attribute_t *create_bssid(cluster_t *cluster, uint8_t *value, uint16_t length); -attribute_t *create_security_type(cluster_t *cluster, uint8_t value); -attribute_t *create_wifi_version(cluster_t *cluster, uint8_t value); -attribute_t *create_channel_number(cluster_t *cluster, uint16_t value); -attribute_t *create_rssi(cluster_t *cluster, int8_t value); +attribute_t *create_security_type(cluster_t *cluster, nullable value); +attribute_t *create_wifi_version(cluster_t *cluster, nullable value); +attribute_t *create_channel_number(cluster_t *cluster, nullable value); +attribute_t *create_rssi(cluster_t *cluster, nullable value); /** These attributes are optional for the cluster, but when added to this cluster, the value is maintained internally. - * If the attributes are added in some other cluster, then the value is not maintained internally. + * If the attributes are added in some other cluster, then the value is not maintained internally. **/ -attribute_t *create_beacon_lost_count(cluster_t *cluster, uint32_t value); -attribute_t *create_beacon_rx_count(cluster_t *cluster, uint32_t value); -attribute_t *create_packet_multicast_rx_count(cluster_t *cluster, uint32_t value); -attribute_t *create_packet_multicast_tx_count(cluster_t *cluster, uint32_t value); -attribute_t *create_packet_unicast_rx_count(cluster_t *cluster, uint32_t value); -attribute_t *create_packet_unicast_tx_count(cluster_t *cluster, uint32_t value); -attribute_t *create_current_max_rate(cluster_t *cluster, uint64_t value); -attribute_t *create_overrun_count(cluster_t *cluster, uint64_t value); +attribute_t *create_beacon_lost_count(cluster_t *cluster, nullable value); +attribute_t *create_beacon_rx_count(cluster_t *cluster, nullable value); +attribute_t *create_packet_multicast_rx_count(cluster_t *cluster, nullable value); +attribute_t *create_packet_multicast_tx_count(cluster_t *cluster, nullable value); +attribute_t *create_packet_unicast_rx_count(cluster_t *cluster, nullable value); +attribute_t *create_packet_unicast_tx_count(cluster_t *cluster, nullable value); +attribute_t *create_current_max_rate(cluster_t *cluster, nullable value); +attribute_t *create_overrun_count(cluster_t *cluster, nullable value); } /* attribute */ } /* diagnostics_network_wifi */ namespace diagnostics_network_thread { namespace attribute { -attribute_t *create_channel(cluster_t *cluster, uint16_t value); -attribute_t *create_routing_role(cluster_t *cluster, uint8_t value); +attribute_t *create_channel(cluster_t *cluster, nullable value); +attribute_t *create_routing_role(cluster_t *cluster, nullable value); attribute_t *create_network_name(cluster_t *cluster, char *value, uint16_t length); -attribute_t *create_pan_id(cluster_t *cluster, uint16_t value); -attribute_t *create_extended_pan_id(cluster_t *cluster, uint64_t value); +attribute_t *create_pan_id(cluster_t *cluster, nullable value); +attribute_t *create_extended_pan_id(cluster_t *cluster, nullable value); attribute_t *create_mesh_local_prefix(cluster_t *cluster, uint8_t *value, uint16_t length); attribute_t *create_neighbor_table(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count); attribute_t *create_route_table(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count); -attribute_t *create_partition_id(cluster_t *cluster, uint32_t value); -attribute_t *create_weighting(cluster_t *cluster, uint8_t value); -attribute_t *create_data_version(cluster_t *cluster, uint8_t value); -attribute_t *create_stable_data_version(cluster_t *cluster, uint8_t value); -attribute_t *create_leader_router_id(cluster_t *cluster, uint8_t value); +attribute_t *create_partition_id(cluster_t *cluster, nullable value); +attribute_t *create_weighting(cluster_t *cluster, nullable value); +attribute_t *create_data_version(cluster_t *cluster, nullable value); +attribute_t *create_stable_data_version(cluster_t *cluster, nullable value); +attribute_t *create_leader_router_id(cluster_t *cluster, nullable value); attribute_t *create_security_policy(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count); attribute_t *create_channel_page0_mask(cluster_t *cluster, uint8_t *value, uint16_t length); attribute_t *create_operational_dataset_components(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count); @@ -253,16 +253,16 @@ namespace on_off { namespace attribute { attribute_t *create_on_off(cluster_t *cluster, bool value); attribute_t *create_global_scene_control(cluster_t *cluster, bool value); -attribute_t *create_on_time(cluster_t *cluster, uint16_t value); -attribute_t *create_off_wait_time(cluster_t *cluster, uint16_t value); -attribute_t *create_start_up_on_off(cluster_t *cluster, uint8_t value); +attribute_t *create_on_time(cluster_t *cluster, nullable value); +attribute_t *create_off_wait_time(cluster_t *cluster, nullable value); +attribute_t *create_start_up_on_off(cluster_t *cluster, nullable value); } /* attribute */ } /* on_off */ namespace level_control { namespace attribute { -attribute_t *create_current_level(cluster_t *cluster, uint8_t value); -attribute_t *create_on_level(cluster_t *cluster, uint8_t value); +attribute_t *create_current_level(cluster_t *cluster, nullable value); +attribute_t *create_on_level(cluster_t *cluster, nullable value); attribute_t *create_options(cluster_t *cluster, uint8_t value, uint8_t min, uint8_t max); attribute_t *create_remaining_time(cluster_t *cluster, uint16_t value); attribute_t *create_min_level(cluster_t *cluster, uint8_t value); @@ -271,10 +271,10 @@ attribute_t *create_current_frequency(cluster_t *cluster, uint16_t value); attribute_t *create_min_frequency(cluster_t *cluster, uint16_t value); attribute_t *create_max_frequency(cluster_t *cluster, uint16_t value); attribute_t *create_on_off_transition_time(cluster_t *cluster, uint16_t value); -attribute_t *create_on_transition_time(cluster_t* cluster, uint16_t value); -attribute_t *create_off_transition_time(cluster_t* cluster, uint16_t value); -attribute_t *create_default_move_rate(cluster_t* cluster, uint8_t value); -attribute_t *create_start_up_current_level(cluster_t *cluster, uint8_t value); +attribute_t *create_on_transition_time(cluster_t* cluster, nullable value); +attribute_t *create_off_transition_time(cluster_t* cluster, nullable value); +attribute_t *create_default_move_rate(cluster_t* cluster, nullable value); +attribute_t *create_start_up_current_level(cluster_t *cluster, nullable value); } /* attribute */ } /* level_control */ @@ -291,7 +291,7 @@ attribute_t *create_color_temperature_mireds(cluster_t *cluster, uint16_t value) attribute_t *create_color_temp_physical_min_mireds(cluster_t *cluster, uint16_t value); attribute_t *create_color_temp_physical_max_mireds(cluster_t *cluster, uint16_t value); attribute_t *create_couple_color_temp_to_level_min_mireds(cluster_t *cluster, uint16_t value); -attribute_t *create_startup_color_temperature_mireds(cluster_t *cluster, uint16_t value); +attribute_t *create_startup_color_temperature_mireds(cluster_t *cluster, nullable value); attribute_t *create_current_x(cluster_t *cluster, uint16_t value); attribute_t *create_current_y(cluster_t *cluster, uint16_t value); attribute_t *create_enhanced_current_hue(cluster_t *cluster, uint16_t value); @@ -300,10 +300,10 @@ attribute_t *create_color_loop_direction(cluster_t *cluster, uint8_t value); attribute_t *create_color_loop_time(cluster_t *cluster, uint16_t value); attribute_t *create_color_loop_start_enhanced_hue(cluster_t *cluster, uint16_t value); attribute_t *create_color_loop_stored_enhanced_hue(cluster_t *cluster, uint16_t value); -attribute_t *create_number_of_primaries(cluster_t *cluster, uint8_t value); +attribute_t *create_number_of_primaries(cluster_t *cluster, nullable value); attribute_t *create_primary_n_x(cluster_t * cluster, uint16_t value, uint8_t index); attribute_t *create_primary_n_y(cluster_t * cluster, uint16_t value, uint8_t index); -attribute_t *create_primary_n_intensity(cluster_t * cluster, uint8_t value, uint8_t index); +attribute_t *create_primary_n_intensity(cluster_t * cluster, nullable value, uint8_t index); } /* attribute */ } /* color_control */ @@ -311,14 +311,14 @@ namespace fan_control { namespace attribute { attribute_t *create_fan_mode(cluster_t *cluster, uint8_t value); attribute_t *create_fan_mode_sequence(cluster_t *cluster, uint8_t value); -attribute_t *create_percent_setting(cluster_t *cluster, uint8_t value); +attribute_t *create_percent_setting(cluster_t *cluster, nullable value); attribute_t *create_percent_current(cluster_t *cluster, uint8_t value); } /* attribute */ } /* fan_control */ namespace thermostat { namespace attribute { -attribute_t *create_local_temperature(cluster_t *cluster, int16_t value); +attribute_t *create_local_temperature(cluster_t *cluster, nullable value); attribute_t *create_occupied_cooling_setpoint(cluster_t *cluster, uint16_t value); attribute_t *create_occupied_heating_setpoint(cluster_t *cluster, uint16_t value); attribute_t *create_control_sequence_of_operation(cluster_t *cluster, uint8_t value, uint8_t min, uint8_t max); @@ -328,7 +328,7 @@ attribute_t *create_system_mode(cluster_t *cluster, uint8_t value, uint8_t min, namespace door_lock { namespace attribute { -attribute_t *create_lock_state(cluster_t *cluster, uint8_t value); +attribute_t *create_lock_state(cluster_t *cluster, nullable value); attribute_t *create_lock_type(cluster_t *cluster, uint8_t value); attribute_t *create_actuator_enabled(cluster_t *cluster, bool value); attribute_t *create_auto_relock_time(cluster_t *cluster, uint32_t value); @@ -342,19 +342,19 @@ namespace attribute { attribute_t *create_type(cluster_t *cluster, uint8_t value); attribute_t *create_physical_closed_limit_lift(cluster_t *cluster, uint16_t value); attribute_t *create_physical_closed_limit_tilt(cluster_t *cluster, uint16_t value); -attribute_t *create_current_position_lift(cluster_t *cluster, uint8_t value); -attribute_t *create_current_position_tilt(cluster_t *cluster, uint8_t value); +attribute_t *create_current_position_lift(cluster_t *cluster, nullable value); +attribute_t *create_current_position_tilt(cluster_t *cluster, nullable value); attribute_t *create_number_of_actuations_lift(cluster_t *cluster, uint16_t value); attribute_t *create_number_of_actuations_tilt(cluster_t *cluster, uint16_t value); attribute_t *create_config_status(cluster_t *cluster, uint8_t value); -attribute_t *create_current_position_lift_percentage(cluster_t *cluster, uint8_t value); -attribute_t *create_current_position_tilt_percentage(cluster_t *cluster, uint8_t value); -attribute_t *create_operational_status(cluster_t *cluster, uint8_t value); -attribute_t *create_target_position_lift_percent_100ths(cluster_t *cluster, uint16_t value); -attribute_t *create_target_position_tilt_percent_100ths(cluster_t *cluster, uint16_t value); +attribute_t *create_current_position_lift_percentage(cluster_t *cluster, nullable value); +attribute_t *create_current_position_tilt_percentage(cluster_t *cluster, nullable value); +attribute_t *create_operational_status(cluster_t *cluster, nullable value); +attribute_t *create_target_position_lift_percent_100ths(cluster_t *cluster, nullable value); +attribute_t *create_target_position_tilt_percent_100ths(cluster_t *cluster, nullable value); attribute_t *create_end_product_type(cluster_t *cluster, uint8_t value); -attribute_t *create_current_position_lift_percent_100ths(cluster_t *cluster, uint16_t value); -attribute_t *create_current_position_tilt_percent_100ths(cluster_t *cluster, uint16_t value); +attribute_t *create_current_position_lift_percent_100ths(cluster_t *cluster, nullable value); +attribute_t *create_current_position_tilt_percent_100ths(cluster_t *cluster, nullable value); attribute_t *create_installed_open_limit_lift(cluster_t *cluster, uint16_t value); attribute_t *create_installed_closed_limit_lift(cluster_t *cluster, uint16_t value); attribute_t *create_installed_open_limit_tilt(cluster_t *cluster, uint16_t value); @@ -374,9 +374,9 @@ attribute_t *create_multi_press_max(cluster_t *cluster, uint8_t value); namespace temperature_measurement { namespace attribute { -attribute_t *create_temperature_measured_value(cluster_t *cluster, int16_t value); -attribute_t *create_temperature_min_measured_value(cluster_t *cluster, int16_t value); -attribute_t *create_temperature_max_measured_value(cluster_t *cluster, int16_t value); +attribute_t *create_temperature_measured_value(cluster_t *cluster, nullable value); +attribute_t *create_temperature_min_measured_value(cluster_t *cluster, nullable value); +attribute_t *create_temperature_max_measured_value(cluster_t *cluster, nullable value); } /* attribute */ } /* temperature_measurement */ diff --git a/components/esp_matter/esp_matter_attribute_utils.cpp b/components/esp_matter/esp_matter_attribute_utils.cpp index 53a4ac8f9..e51b31bcc 100644 --- a/components/esp_matter/esp_matter_attribute_utils.cpp +++ b/components/esp_matter/esp_matter_attribute_utils.cpp @@ -64,6 +64,19 @@ esp_matter_attr_val_t esp_matter_int(int val) return attr_val; } +esp_matter_attr_val_t esp_matter_nullable_int(nullable val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_NULLABLE_INTEGER, + }; + if (val.is_null()) { + chip::app::NumericAttributeTraits::SetNull(attr_val.val.i); + } else { + attr_val.val.i = val.value(); + } + return attr_val; +} + esp_matter_attr_val_t esp_matter_float(float val) { esp_matter_attr_val_t attr_val = { @@ -75,6 +88,19 @@ esp_matter_attr_val_t esp_matter_float(float val) return attr_val; } +esp_matter_attr_val_t esp_matter_nullable_float(nullable val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_NULLABLE_FLOAT, + }; + if (val.is_null()) { + chip::app::NumericAttributeTraits::SetNull(attr_val.val.f); + } else { + attr_val.val.i = val.value(); + } + return attr_val; +} + esp_matter_attr_val_t esp_matter_int8(int8_t val) { esp_matter_attr_val_t attr_val = { @@ -86,6 +112,19 @@ esp_matter_attr_val_t esp_matter_int8(int8_t val) return attr_val; } +esp_matter_attr_val_t esp_matter_nullable_int8(nullable val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_NULLABLE_INT8, + }; + if (val.is_null()) { + chip::app::NumericAttributeTraits::SetNull(attr_val.val.i8); + } else { + attr_val.val.i8 = val.value(); + } + return attr_val; +} + esp_matter_attr_val_t esp_matter_uint8(uint8_t val) { esp_matter_attr_val_t attr_val = { @@ -97,6 +136,19 @@ esp_matter_attr_val_t esp_matter_uint8(uint8_t val) return attr_val; } +esp_matter_attr_val_t esp_matter_nullable_uint8(nullable val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_NULLABLE_UINT8, + }; + if (val.is_null()) { + chip::app::NumericAttributeTraits::SetNull(attr_val.val.u8); + } else { + attr_val.val.u8 = val.value(); + } + return attr_val; +} + esp_matter_attr_val_t esp_matter_int16(int16_t val) { esp_matter_attr_val_t attr_val = { @@ -108,6 +160,19 @@ esp_matter_attr_val_t esp_matter_int16(int16_t val) return attr_val; } +esp_matter_attr_val_t esp_matter_nullable_int16(nullable val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_NULLABLE_INT16, + }; + if (val.is_null()) { + chip::app::NumericAttributeTraits::SetNull(attr_val.val.i16); + } else { + attr_val.val.i16 = val.value(); + } + return attr_val; +} + esp_matter_attr_val_t esp_matter_uint16(uint16_t val) { esp_matter_attr_val_t attr_val = { @@ -119,6 +184,19 @@ esp_matter_attr_val_t esp_matter_uint16(uint16_t val) return attr_val; } +esp_matter_attr_val_t esp_matter_nullable_uint16(nullable val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_NULLABLE_UINT16, + }; + if (val.is_null()) { + chip::app::NumericAttributeTraits::SetNull(attr_val.val.u16); + } else { + attr_val.val.u16 = val.value(); + } + return attr_val; +} + esp_matter_attr_val_t esp_matter_int32(int32_t val) { esp_matter_attr_val_t attr_val = { @@ -130,6 +208,19 @@ esp_matter_attr_val_t esp_matter_int32(int32_t val) return attr_val; } +esp_matter_attr_val_t esp_matter_nullable_int32(nullable val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_NULLABLE_INT32, + }; + if (val.is_null()) { + chip::app::NumericAttributeTraits::SetNull(attr_val.val.i32); + } else { + attr_val.val.i32 = val.value(); + } + return attr_val; +} + esp_matter_attr_val_t esp_matter_uint32(uint32_t val) { esp_matter_attr_val_t attr_val = { @@ -141,6 +232,19 @@ esp_matter_attr_val_t esp_matter_uint32(uint32_t val) return attr_val; } +esp_matter_attr_val_t esp_matter_nullable_uint32(nullable val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_NULLABLE_UINT32, + }; + if (val.is_null()) { + chip::app::NumericAttributeTraits::SetNull(attr_val.val.u32); + } else { + attr_val.val.u32 = val.value(); + } + return attr_val; +} + esp_matter_attr_val_t esp_matter_int64(int64_t val) { esp_matter_attr_val_t attr_val = { @@ -152,6 +256,19 @@ esp_matter_attr_val_t esp_matter_int64(int64_t val) return attr_val; } +esp_matter_attr_val_t esp_matter_nullable_int64(nullable val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_NULLABLE_INT64, + }; + if (val.is_null()) { + chip::app::NumericAttributeTraits::SetNull(attr_val.val.i64); + } else { + attr_val.val.i64 = val.value(); + } + return attr_val; +} + esp_matter_attr_val_t esp_matter_uint64(uint64_t val) { esp_matter_attr_val_t attr_val = { @@ -163,6 +280,19 @@ esp_matter_attr_val_t esp_matter_uint64(uint64_t val) return attr_val; } +esp_matter_attr_val_t esp_matter_nullable_uint64(nullable val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_NULLABLE_UINT64, + }; + if (val.is_null()) { + chip::app::NumericAttributeTraits::SetNull(attr_val.val.u64); + } else { + attr_val.val.u64 = val.value(); + } + return attr_val; +} + esp_matter_attr_val_t esp_matter_enum8(uint8_t val) { esp_matter_attr_val_t attr_val = { @@ -174,6 +304,19 @@ esp_matter_attr_val_t esp_matter_enum8(uint8_t val) return attr_val; } +esp_matter_attr_val_t esp_matter_nullable_enum8(nullable val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_NULLABLE_ENUM8, + }; + if (val.is_null()) { + chip::app::NumericAttributeTraits::SetNull(attr_val.val.u8); + } else { + attr_val.val.u8 = val.value(); + } + return attr_val; +} + esp_matter_attr_val_t esp_matter_bitmap8(uint8_t val) { esp_matter_attr_val_t attr_val = { @@ -185,6 +328,19 @@ esp_matter_attr_val_t esp_matter_bitmap8(uint8_t val) return attr_val; } +esp_matter_attr_val_t esp_matter_nullable_bitmap8(nullable val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP8, + }; + if (val.is_null()) { + chip::app::NumericAttributeTraits::SetNull(attr_val.val.u8); + } else { + attr_val.val.u8 = val.value(); + } + return attr_val; +} + esp_matter_attr_val_t esp_matter_bitmap16(uint16_t val) { esp_matter_attr_val_t attr_val = { @@ -196,6 +352,19 @@ esp_matter_attr_val_t esp_matter_bitmap16(uint16_t val) return attr_val; } +esp_matter_attr_val_t esp_matter_nullable_bitmap16(nullable val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP16, + }; + if (val.is_null()) { + chip::app::NumericAttributeTraits::SetNull(attr_val.val.u16); + } else { + attr_val.val.u16 = val.value(); + } + return attr_val; +} + esp_matter_attr_val_t esp_matter_bitmap32(uint32_t val) { esp_matter_attr_val_t attr_val = { @@ -207,6 +376,19 @@ esp_matter_attr_val_t esp_matter_bitmap32(uint32_t val) return attr_val; } +esp_matter_attr_val_t esp_matter_nullable_bitmap32(nullable val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP32, + }; + if (val.is_null()) { + chip::app::NumericAttributeTraits::SetNull(attr_val.val.u32); + } else { + attr_val.val.u32 = val.value(); + } + return attr_val; +} + esp_matter_attr_val_t esp_matter_char_str(char *val, uint16_t data_size) { uint16_t data_size_len = 1; /* Number of bytes used to store the length */ @@ -268,6 +450,11 @@ static esp_matter::console::engine attribute_console; static esp_err_t console_set_handler(int argc, char **argv) { + if (argc < 4) { + ESP_LOGE(TAG, "The arguments for this command is invalid"); + return ESP_ERR_INVALID_ARG; + } + uint16_t endpoint_id = strtol((const char *)&argv[0][2], NULL, 16); uint32_t cluster_id = strtol((const char *)&argv[1][2], NULL, 16); uint32_t attribute_id = strtol((const char *)&argv[2][2], NULL, 16); @@ -287,44 +474,152 @@ static esp_err_t console_set_handler(int argc, char **argv) bool value = atoi(argv[3]); val = esp_matter_bool(value); } else if (type == ESP_MATTER_VAL_TYPE_INT8) { - int8_t value = atoi(argv[3]); - val = esp_matter_int8(value); + if (matter_attribute->IsNullable()) { + if (strncmp(argv[3], "null", sizeof("null")) == 0) { + val = esp_matter_nullable_int8(nullable()); + } else { + int8_t value = atoi(argv[3]); + val = esp_matter_nullable_int8(value); + } + } else { + int8_t value = atoi(argv[3]); + val = esp_matter_int8(value); + } } else if (type == ESP_MATTER_VAL_TYPE_UINT8) { - uint8_t value = atoi(argv[3]); - val = esp_matter_uint8(value); + if (matter_attribute->IsNullable()) { + if (strncmp(argv[3], "null", sizeof("null")) == 0) { + val = esp_matter_nullable_uint8(nullable()); + } else { + uint8_t value = atoi(argv[3]); + val = esp_matter_nullable_uint8(value); + } + } else { + uint8_t value = atoi(argv[3]); + val = esp_matter_uint8(value); + } } else if (type == ESP_MATTER_VAL_TYPE_INT16) { - int16_t value = atoi(argv[3]); - val = esp_matter_int16(value); + if (matter_attribute->IsNullable()) { + if (strncmp(argv[3], "null", sizeof("null")) == 0) { + val = esp_matter_nullable_int16(nullable()); + } else { + int16_t value = atoi(argv[3]); + val = esp_matter_nullable_int16(value); + } + } else { + int16_t value = atoi(argv[3]); + val = esp_matter_int16(value); + } } else if (type == ESP_MATTER_VAL_TYPE_UINT16) { - uint16_t value = atoi(argv[3]); - val = esp_matter_uint16(value); + if (matter_attribute->IsNullable()) { + if (strncmp(argv[3], "null", sizeof("null")) == 0) { + val = esp_matter_nullable_uint16(nullable()); + } else { + uint16_t value = atoi(argv[3]); + val = esp_matter_nullable_uint16(value); + } + } else { + uint16_t value = atoi(argv[3]); + val = esp_matter_uint16(value); + } } else if (type == ESP_MATTER_VAL_TYPE_INT32) { - int32_t value = atoi(argv[3]); - val = esp_matter_int32(value); + if (matter_attribute->IsNullable()) { + if (strncmp(argv[3], "null", sizeof("null")) == 0) { + val = esp_matter_nullable_int32(nullable()); + } else { + int32_t value = atoi(argv[3]); + val = esp_matter_nullable_int32(value); + } + } else { + int32_t value = atoi(argv[3]); + val = esp_matter_int32(value); + } } else if (type == ESP_MATTER_VAL_TYPE_UINT32) { - uint32_t value = atoi(argv[3]); - val = esp_matter_uint32(value); + if (matter_attribute->IsNullable()) { + if (strncmp(argv[3], "null", sizeof("null")) == 0) { + val = esp_matter_nullable_uint32(nullable()); + } else { + uint32_t value = atoi(argv[3]); + val = esp_matter_nullable_uint32(value); + } + } else { + uint32_t value = atoi(argv[3]); + val = esp_matter_uint32(value); + } } else if (type == ESP_MATTER_VAL_TYPE_INT64) { - int64_t value = atoi(argv[3]); - val = esp_matter_int64(value); + if (matter_attribute->IsNullable()) { + if (strncmp(argv[3], "null", sizeof("null")) == 0) { + val = esp_matter_nullable_int64(nullable()); + } else { + int64_t value = atoi(argv[3]); + val = esp_matter_nullable_int64(value); + } + } else { + int64_t value = atoi(argv[3]); + val = esp_matter_int64(value); + } } else if (type == ESP_MATTER_VAL_TYPE_UINT64) { - uint64_t value = atoi(argv[3]); - val = esp_matter_uint64(value); + if (matter_attribute->IsNullable()) { + if (strncmp(argv[3], "null", sizeof("null")) == 0) { + val = esp_matter_nullable_uint64(nullable()); + } else { + uint64_t value = atoi(argv[3]); + val = esp_matter_nullable_uint64(value); + } + } else { + uint64_t value = atoi(argv[3]); + val = esp_matter_uint64(value); + } } else if (type == ESP_MATTER_VAL_TYPE_CHAR_STRING) { char *value = argv[3]; val = esp_matter_char_str(value, strlen(value)); } else if (type == ESP_MATTER_VAL_TYPE_BITMAP8) { - uint8_t value = atoi(argv[3]); - val = esp_matter_bitmap8(value); + if (matter_attribute->IsNullable()) { + if (strncmp(argv[3], "null", sizeof("null")) == 0) { + val = esp_matter_nullable_bitmap8(nullable()); + } else { + uint8_t value = atoi(argv[3]); + val = esp_matter_nullable_bitmap8(value); + } + } else { + uint8_t value = atoi(argv[3]); + val = esp_matter_bitmap8(value); + } } else if (type == ESP_MATTER_VAL_TYPE_BITMAP16) { - uint16_t value = atoi(argv[3]); - val = esp_matter_bitmap16(value); + if (matter_attribute->IsNullable()) { + if (strncmp(argv[3], "null", sizeof("null")) == 0) { + val = esp_matter_nullable_bitmap16(nullable()); + } else { + uint16_t value = atoi(argv[3]); + val = esp_matter_nullable_bitmap16(value); + } + } else { + uint16_t value = atoi(argv[3]); + val = esp_matter_bitmap16(value); + } } else if (type == ESP_MATTER_VAL_TYPE_BITMAP32) { - uint32_t value = atoi(argv[3]); - val = esp_matter_bitmap32(value); + if (matter_attribute->IsNullable()) { + if (strncmp(argv[3], "null", sizeof("null")) == 0) { + val = esp_matter_nullable_bitmap32(nullable()); + } else { + uint32_t value = atoi(argv[3]); + val = esp_matter_nullable_bitmap32(value); + } + } else { + uint32_t value = atoi(argv[3]); + val = esp_matter_bitmap32(value); + } } else if (type == ESP_MATTER_VAL_TYPE_ENUM8) { - uint8_t value = atoi(argv[3]); - val = esp_matter_enum8(value); + if (matter_attribute->IsNullable()) { + if (strncmp(argv[3], "null", sizeof("null")) == 0) { + val = esp_matter_nullable_enum8(nullable()); + } else { + uint8_t value = atoi(argv[3]); + val = esp_matter_nullable_enum8(value); + } + } else { + uint8_t value = atoi(argv[3]); + val = esp_matter_enum8(value); + } } else { ESP_LOGE(TAG, "Type not handled: %d", type); return ESP_ERR_INVALID_ARG; @@ -334,6 +629,10 @@ static esp_err_t console_set_handler(int argc, char **argv) static esp_err_t console_get_handler(int argc, char **argv) { + if (argc < 3) { + ESP_LOGE(TAG, "The arguments for this command is invalid"); + return ESP_ERR_INVALID_ARG; + } uint16_t endpoint_id = strtol((const char *)&argv[0][2], NULL, 16); uint32_t cluster_id = strtol((const char *)&argv[1][2], NULL, 16); uint32_t attribute_id = strtol((const char *)&argv[2][2], NULL, 16); @@ -350,41 +649,123 @@ static esp_err_t console_get_handler(int argc, char **argv) esp_matter_val_type_t type = get_val_type_from_attribute_type(matter_attribute->attributeType); esp_matter_attr_val_t val = esp_matter_invalid(NULL); if (type == ESP_MATTER_VAL_TYPE_BOOLEAN) { - bool value = false; - get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_bool(value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType value; + uint8_t *read_able = Traits::ToAttributeStoreRepresentation(value); + get_val_raw(endpoint_id, cluster_id, attribute_id, read_able, sizeof(value)); + val = esp_matter_bool(Traits::StorageToWorking(value)); } else if (type == ESP_MATTER_VAL_TYPE_INT8) { - int8_t value = 0; - get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_int8(value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType value; + uint8_t *read_able = Traits::ToAttributeStoreRepresentation(value); + get_val_raw(endpoint_id, cluster_id, attribute_id, read_able, sizeof(value)); + if (matter_attribute->IsNullable()) { + if (Traits::IsNullValue(value)) { + val = esp_matter_nullable_int8(nullable()); + } else { + val = esp_matter_nullable_int8(Traits::StorageToWorking(value)); + } + } else { + val = esp_matter_int8(Traits::StorageToWorking(value)); + } } else if (type == ESP_MATTER_VAL_TYPE_UINT8) { - uint8_t value = 0; - get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_uint8(value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType value; + uint8_t *read_able = Traits::ToAttributeStoreRepresentation(value); + get_val_raw(endpoint_id, cluster_id, attribute_id, read_able, sizeof(value)); + if (matter_attribute->IsNullable()) { + if (Traits::IsNullValue(value)) { + val = esp_matter_nullable_uint8(nullable()); + } else { + val = esp_matter_nullable_uint8(Traits::StorageToWorking(value)); + } + } else { + val = esp_matter_uint8(Traits::StorageToWorking(value)); + } } else if (type == ESP_MATTER_VAL_TYPE_INT16) { - int16_t value = 0; - get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_int16(value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType value; + uint8_t *read_able = Traits::ToAttributeStoreRepresentation(value); + get_val_raw(endpoint_id, cluster_id, attribute_id, read_able, sizeof(value)); + if (matter_attribute->IsNullable()) { + if (Traits::IsNullValue(value)) { + val = esp_matter_nullable_int16(nullable()); + } else { + val = esp_matter_nullable_int16(Traits::StorageToWorking(value)); + } + } else { + val = esp_matter_int16(Traits::StorageToWorking(value)); + } } else if (type == ESP_MATTER_VAL_TYPE_UINT16) { - uint16_t value = 0; - get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_uint16(value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType value; + uint8_t *read_able = Traits::ToAttributeStoreRepresentation(value); + get_val_raw(endpoint_id, cluster_id, attribute_id, read_able, sizeof(value)); + if (matter_attribute->IsNullable()) { + if (Traits::IsNullValue(value)) { + val = esp_matter_nullable_uint16(nullable()); + } else { + val = esp_matter_nullable_uint16(Traits::StorageToWorking(value)); + } + } else { + val = esp_matter_uint16(Traits::StorageToWorking(value)); + } } else if (type == ESP_MATTER_VAL_TYPE_INT32) { - int32_t value = 0; - get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_int32(value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType value; + uint8_t *read_able = Traits::ToAttributeStoreRepresentation(value); + get_val_raw(endpoint_id, cluster_id, attribute_id, read_able, sizeof(value)); + if (matter_attribute->IsNullable()) { + if (Traits::IsNullValue(value)) { + val = esp_matter_nullable_int32(nullable()); + } else { + val = esp_matter_nullable_int32(Traits::StorageToWorking(value)); + } + } else { + val = esp_matter_int32(Traits::StorageToWorking(value)); + } } else if (type == ESP_MATTER_VAL_TYPE_UINT32) { - uint32_t value = 0; - get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_uint32(value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType value; + uint8_t *read_able = Traits::ToAttributeStoreRepresentation(value); + get_val_raw(endpoint_id, cluster_id, attribute_id, read_able, sizeof(value)); + if (matter_attribute->IsNullable()) { + if (Traits::IsNullValue(value)) { + val = esp_matter_nullable_uint32(nullable()); + } else { + val = esp_matter_nullable_uint32(Traits::StorageToWorking(value)); + } + } else { + val = esp_matter_uint32(Traits::StorageToWorking(value)); + } } else if (type == ESP_MATTER_VAL_TYPE_INT64) { - int64_t value = 0; - get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_int64(value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType value; + uint8_t *read_able = Traits::ToAttributeStoreRepresentation(value); + get_val_raw(endpoint_id, cluster_id, attribute_id, read_able, sizeof(value)); + if (matter_attribute->IsNullable()) { + if (Traits::IsNullValue(value)) { + val = esp_matter_nullable_int64(nullable()); + } else { + val = esp_matter_nullable_int64(Traits::StorageToWorking(value)); + } + } else { + val = esp_matter_int64(Traits::StorageToWorking(value)); + } } else if (type == ESP_MATTER_VAL_TYPE_UINT64) { - uint64_t value = 0; - get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_uint64(value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType value; + uint8_t *read_able = Traits::ToAttributeStoreRepresentation(value); + get_val_raw(endpoint_id, cluster_id, attribute_id, read_able, sizeof(value)); + if (matter_attribute->IsNullable()) { + if (Traits::IsNullValue(value)) { + val = esp_matter_nullable_uint64(nullable()); + } else { + val = esp_matter_nullable_uint64(Traits::StorageToWorking(value)); + } + } else { + val = esp_matter_uint64(Traits::StorageToWorking(value)); + } } else if (type == ESP_MATTER_VAL_TYPE_CHAR_STRING) { /* Get raw value */ char value[256] = {0}; /* It can go upto 256 since only 1 byte (first) is used for size */ @@ -396,21 +777,61 @@ static esp_err_t console_get_handler(int argc, char **argv) memcpy(&data_count, &value[0], data_size_len); val = esp_matter_char_str((char *)(value + data_size_len), data_count); } else if (type == ESP_MATTER_VAL_TYPE_BITMAP8) { - uint8_t value = 0; - get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_bitmap8(value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType value; + uint8_t *read_able = Traits::ToAttributeStoreRepresentation(value); + get_val_raw(endpoint_id, cluster_id, attribute_id, read_able, sizeof(value)); + if (matter_attribute->IsNullable()) { + if (Traits::IsNullValue(value)) { + val = esp_matter_nullable_bitmap8(nullable()); + } else { + val = esp_matter_nullable_bitmap8(Traits::StorageToWorking(value)); + } + } else { + val = esp_matter_bitmap8(Traits::StorageToWorking(value)); + } } else if (type == ESP_MATTER_VAL_TYPE_BITMAP16) { - uint16_t value = 0; - get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_bitmap16(value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType value; + uint8_t *read_able = Traits::ToAttributeStoreRepresentation(value); + get_val_raw(endpoint_id, cluster_id, attribute_id, read_able, sizeof(value)); + if (matter_attribute->IsNullable()) { + if (Traits::IsNullValue(value)) { + val = esp_matter_nullable_bitmap16(nullable()); + } else { + val = esp_matter_nullable_bitmap16(Traits::StorageToWorking(value)); + } + } else { + val = esp_matter_bitmap16(Traits::StorageToWorking(value)); + } } else if (type == ESP_MATTER_VAL_TYPE_BITMAP32) { - uint32_t value = 0; - get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_bitmap32(value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType value; + uint8_t *read_able = Traits::ToAttributeStoreRepresentation(value); + get_val_raw(endpoint_id, cluster_id, attribute_id, read_able, sizeof(value)); + if (matter_attribute->IsNullable()) { + if (Traits::IsNullValue(value)) { + val = esp_matter_nullable_bitmap32(nullable()); + } else { + val = esp_matter_nullable_bitmap32(Traits::StorageToWorking(value)); + } + } else { + val = esp_matter_bitmap32(Traits::StorageToWorking(value)); + } } else if (type == ESP_MATTER_VAL_TYPE_ENUM8) { - uint8_t value = 0; - get_val_raw(endpoint_id, cluster_id, attribute_id, (uint8_t *)&value, sizeof(value)); - val = esp_matter_enum8(value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType value; + uint8_t *read_able = Traits::ToAttributeStoreRepresentation(value); + get_val_raw(endpoint_id, cluster_id, attribute_id, read_able, sizeof(value)); + if (matter_attribute->IsNullable()) { + if (Traits::IsNullValue(value)) { + val = esp_matter_nullable_enum8(nullable()); + } else { + val = esp_matter_nullable_enum8(Traits::StorageToWorking(value)); + } + } else { + val = esp_matter_enum8(Traits::StorageToWorking(value)); + } } else { ESP_LOGE(TAG, "Type not handled: %d", type); return ESP_ERR_INVALID_ARG; @@ -574,6 +995,50 @@ static esp_matter_val_type_t get_val_type_from_attribute_type(int attribute_type return ESP_MATTER_VAL_TYPE_INVALID; } +bool val_is_null(esp_matter_attr_val_t *val) +{ + switch (val->type) { + case ESP_MATTER_VAL_TYPE_NULLABLE_INTEGER: + return chip::app::NumericAttributeTraits::IsNullValue(val->val.i); + break; + case ESP_MATTER_VAL_TYPE_NULLABLE_UINT8: + case ESP_MATTER_VAL_TYPE_NULLABLE_ENUM8: + case ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP8: + return chip::app::NumericAttributeTraits::IsNullValue(val->val.u8); + break; + case ESP_MATTER_VAL_TYPE_NULLABLE_UINT16: + case ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP16: + return chip::app::NumericAttributeTraits::IsNullValue(val->val.u16); + break; + case ESP_MATTER_VAL_TYPE_NULLABLE_UINT32: + case ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP32: + return chip::app::NumericAttributeTraits::IsNullValue(val->val.u32); + break; + case ESP_MATTER_VAL_TYPE_NULLABLE_UINT64: + return chip::app::NumericAttributeTraits::IsNullValue(val->val.u64); + break; + case ESP_MATTER_VAL_TYPE_NULLABLE_INT8: + return chip::app::NumericAttributeTraits::IsNullValue(val->val.i8); + break; + case ESP_MATTER_VAL_TYPE_NULLABLE_INT16: + return chip::app::NumericAttributeTraits::IsNullValue(val->val.i16); + break; + case ESP_MATTER_VAL_TYPE_NULLABLE_INT32: + return chip::app::NumericAttributeTraits::IsNullValue(val->val.i32); + break; + case ESP_MATTER_VAL_TYPE_NULLABLE_INT64: + return chip::app::NumericAttributeTraits::IsNullValue(val->val.i64); + break; + case ESP_MATTER_VAL_TYPE_NULLABLE_FLOAT: + return chip::app::NumericAttributeTraits::IsNullValue(val->val.f); + break; + default: + return false; + break; + } + return false; +} + esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeType *attribute_type, uint16_t *attribute_size, uint8_t *value) { @@ -586,23 +1051,31 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp *attribute_size = sizeof(bool); } if (value) { - memcpy(value, (uint8_t *)&val->val.b, *attribute_size); + using Traits = chip::app::NumericAttributeTraits; + Traits::WorkingToStorage(val->val.b, *value); } break; case ESP_MATTER_VAL_TYPE_INTEGER: + case ESP_MATTER_VAL_TYPE_NULLABLE_INTEGER: if (attribute_type) { *attribute_type = ZCL_INT16U_ATTRIBUTE_TYPE; } if (attribute_size) { - *attribute_size = sizeof(uint16_t); + *attribute_size = sizeof(int); } if (value) { - memcpy(value, (uint8_t *)&val->val.i, *attribute_size); + using Traits = chip::app::NumericAttributeTraits; + if ((val->type & ESP_MATTER_VAL_NULLANLE_BASE) && Traits::IsNullValue(val->val.i)) { + Traits::SetNull(*(int *)value); + } else { + Traits::WorkingToStorage(val->val.i, *(int *)value); + } } break; case ESP_MATTER_VAL_TYPE_FLOAT: + case ESP_MATTER_VAL_TYPE_NULLABLE_FLOAT: if (attribute_type) { *attribute_type = ZCL_SINGLE_ATTRIBUTE_TYPE; } @@ -610,7 +1083,12 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp *attribute_size = sizeof(float); } if (value) { - memcpy(value, (uint8_t *)&val->val.f, *attribute_size); + using Traits = chip::app::NumericAttributeTraits; + if ((val->type & ESP_MATTER_VAL_NULLANLE_BASE) && Traits::IsNullValue(val->val.f)) { + Traits::SetNull(*(float *)value); + } else { + Traits::WorkingToStorage(val->val.f, *(float *)value); + } } break; @@ -657,6 +1135,7 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp break; case ESP_MATTER_VAL_TYPE_INT8: + case ESP_MATTER_VAL_TYPE_NULLABLE_INT8: if (attribute_type) { *attribute_type = ZCL_INT8S_ATTRIBUTE_TYPE; } @@ -664,11 +1143,17 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp *attribute_size = sizeof(int8_t); } if (value) { - memcpy(value, (uint8_t *)&val->val.i8, *attribute_size); + using Traits = chip::app::NumericAttributeTraits; + if ((val->type & ESP_MATTER_VAL_NULLANLE_BASE) && Traits::IsNullValue(val->val.i8)) { + Traits::SetNull(*(int8_t *)value); + } else { + Traits::WorkingToStorage(val->val.i8, *(int8_t *)value); + } } break; case ESP_MATTER_VAL_TYPE_UINT8: + case ESP_MATTER_VAL_TYPE_NULLABLE_UINT8: if (attribute_type) { *attribute_type = ZCL_INT8U_ATTRIBUTE_TYPE; } @@ -676,11 +1161,17 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp *attribute_size = sizeof(uint8_t); } if (value) { - memcpy(value, (uint8_t *)&val->val.u8, *attribute_size); + using Traits = chip::app::NumericAttributeTraits; + if ((val->type & ESP_MATTER_VAL_NULLANLE_BASE) && Traits::IsNullValue(val->val.u8)) { + Traits::SetNull(*(uint8_t *)value); + } else { + Traits::WorkingToStorage(val->val.u8, *(uint8_t *)value); + } } break; case ESP_MATTER_VAL_TYPE_INT16: + case ESP_MATTER_VAL_TYPE_NULLABLE_INT16: if (attribute_type) { *attribute_type = ZCL_INT16S_ATTRIBUTE_TYPE; } @@ -688,11 +1179,17 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp *attribute_size = sizeof(int16_t); } if (value) { - memcpy(value, (uint8_t *)&val->val.i16, *attribute_size); + using Traits = chip::app::NumericAttributeTraits; + if ((val->type & ESP_MATTER_VAL_NULLANLE_BASE) && Traits::IsNullValue(val->val.i16)) { + Traits::SetNull(*(int16_t *)value); + } else { + Traits::WorkingToStorage(val->val.i16, *(int16_t *)value); + } } break; case ESP_MATTER_VAL_TYPE_UINT16: + case ESP_MATTER_VAL_TYPE_NULLABLE_UINT16: if (attribute_type) { *attribute_type = ZCL_INT16U_ATTRIBUTE_TYPE; } @@ -700,11 +1197,17 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp *attribute_size = sizeof(uint16_t); } if (value) { - memcpy(value, (uint8_t *)&val->val.u16, *attribute_size); + using Traits = chip::app::NumericAttributeTraits; + if ((val->type & ESP_MATTER_VAL_NULLANLE_BASE) && Traits::IsNullValue(val->val.u16)) { + Traits::SetNull(*(uint16_t *)value); + } else { + Traits::WorkingToStorage(val->val.u16, *(uint16_t *)value); + } } break; case ESP_MATTER_VAL_TYPE_INT32: + case ESP_MATTER_VAL_TYPE_NULLABLE_INT32: if (attribute_type) { *attribute_type = ZCL_INT32S_ATTRIBUTE_TYPE; } @@ -712,11 +1215,17 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp *attribute_size = sizeof(int32_t); } if (value) { - memcpy(value, (uint8_t *)&val->val.i32, *attribute_size); + using Traits = chip::app::NumericAttributeTraits; + if ((val->type & ESP_MATTER_VAL_NULLANLE_BASE) && Traits::IsNullValue(val->val.i32)) { + Traits::SetNull(*(int32_t *)value); + } else { + Traits::WorkingToStorage(val->val.i32, *(int32_t *)value); + } } break; case ESP_MATTER_VAL_TYPE_UINT32: + case ESP_MATTER_VAL_TYPE_NULLABLE_UINT32: if (attribute_type) { *attribute_type = ZCL_INT32U_ATTRIBUTE_TYPE; } @@ -724,11 +1233,17 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp *attribute_size = sizeof(uint32_t); } if (value) { - memcpy(value, (uint8_t *)&val->val.u32, *attribute_size); + using Traits = chip::app::NumericAttributeTraits; + if ((val->type & ESP_MATTER_VAL_NULLANLE_BASE) && Traits::IsNullValue(val->val.u32)) { + Traits::SetNull(*(uint32_t *)value); + } else { + Traits::WorkingToStorage(val->val.u32, *(uint32_t *)value); + } } break; case ESP_MATTER_VAL_TYPE_INT64: + case ESP_MATTER_VAL_TYPE_NULLABLE_INT64: if (attribute_type) { *attribute_type = ZCL_INT64S_ATTRIBUTE_TYPE; } @@ -736,11 +1251,17 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp *attribute_size = sizeof(int64_t); } if (value) { - memcpy(value, (uint8_t *)&val->val.i64, *attribute_size); + using Traits = chip::app::NumericAttributeTraits; + if ((val->type & ESP_MATTER_VAL_NULLANLE_BASE) && Traits::IsNullValue(val->val.i64)) { + Traits::SetNull(*(int64_t *)value); + } else { + Traits::WorkingToStorage(val->val.i64, *(int64_t *)value); + } } break; case ESP_MATTER_VAL_TYPE_UINT64: + case ESP_MATTER_VAL_TYPE_NULLABLE_UINT64: if (attribute_type) { *attribute_type = ZCL_INT64U_ATTRIBUTE_TYPE; } @@ -748,11 +1269,17 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp *attribute_size = sizeof(uint64_t); } if (value) { - memcpy(value, (uint8_t *)&val->val.u64, *attribute_size); + using Traits = chip::app::NumericAttributeTraits; + if ((val->type & ESP_MATTER_VAL_NULLANLE_BASE) && Traits::IsNullValue(val->val.u64)) { + Traits::SetNull(*(uint64_t *)value); + } else { + Traits::WorkingToStorage(val->val.i8, *(uint64_t *)value); + } } break; case ESP_MATTER_VAL_TYPE_ENUM8: + case ESP_MATTER_VAL_TYPE_NULLABLE_ENUM8: if (attribute_type) { *attribute_type = ZCL_ENUM8_ATTRIBUTE_TYPE; } @@ -760,11 +1287,17 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp *attribute_size = sizeof(uint8_t); } if (value) { - memcpy(value, (uint8_t *)&val->val.u8, *attribute_size); + using Traits = chip::app::NumericAttributeTraits; + if ((val->type & ESP_MATTER_VAL_NULLANLE_BASE) && Traits::IsNullValue(val->val.u8)) { + Traits::SetNull(*(uint8_t *)value); + } else { + Traits::WorkingToStorage(val->val.u8, *(uint8_t *)value); + } } break; case ESP_MATTER_VAL_TYPE_BITMAP8: + case ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP8: if (attribute_type) { *attribute_type = ZCL_BITMAP8_ATTRIBUTE_TYPE; } @@ -772,11 +1305,17 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp *attribute_size = sizeof(uint8_t); } if (value) { - memcpy(value, (uint8_t *)&val->val.u8, *attribute_size); + using Traits = chip::app::NumericAttributeTraits; + if ((val->type & ESP_MATTER_VAL_NULLANLE_BASE) && Traits::IsNullValue(val->val.u8)) { + Traits::SetNull(*(uint8_t *)value); + } else { + Traits::WorkingToStorage(val->val.u8, *(uint8_t *)value); + } } break; case ESP_MATTER_VAL_TYPE_BITMAP16: + case ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP16: if (attribute_type) { *attribute_type = ZCL_BITMAP16_ATTRIBUTE_TYPE; } @@ -784,11 +1323,17 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp *attribute_size = sizeof(uint16_t); } if (value) { - memcpy(value, (uint8_t *)&val->val.u16, *attribute_size); + using Traits = chip::app::NumericAttributeTraits; + if ((val->type & ESP_MATTER_VAL_NULLANLE_BASE) && Traits::IsNullValue(val->val.u16)) { + Traits::SetNull(*(uint16_t *)value); + } else { + Traits::WorkingToStorage(val->val.u16, *(uint16_t *)value); + } } break; case ESP_MATTER_VAL_TYPE_BITMAP32: + case ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP32: if (attribute_type) { *attribute_type = ZCL_BITMAP32_ATTRIBUTE_TYPE; } @@ -796,7 +1341,12 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp *attribute_size = sizeof(uint32_t); } if (value) { - memcpy(value, (uint8_t *)&val->val.u32, *attribute_size); + using Traits = chip::app::NumericAttributeTraits; + if ((val->type & ESP_MATTER_VAL_NULLANLE_BASE) && Traits::IsNullValue(val->val.u32)) { + Traits::SetNull(*(uint32_t *)value); + } else { + Traits::WorkingToStorage(val->val.i8, *(uint32_t *)value); + } } break; @@ -809,12 +1359,14 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp } static esp_err_t get_attr_val_from_data(esp_matter_attr_val_t *val, EmberAfAttributeType attribute_type, - uint16_t attribute_size, uint8_t *value) + uint16_t attribute_size, uint8_t *value, + const EmberAfAttributeMetadata * attribute_metadata) { switch (attribute_type) { case ZCL_BOOLEAN_ATTRIBUTE_TYPE: { - bool attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(bool)); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType attribute_value; + memcpy((uint8_t *)&attribute_value, value, sizeof(Traits::StorageType)); *val = esp_matter_bool(attribute_value); break; } @@ -847,79 +1399,178 @@ static esp_err_t get_attr_val_from_data(esp_matter_attr_val_t *val, EmberAfAttri } case ZCL_INT8S_ATTRIBUTE_TYPE: { - int8_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(int8_t)); - *val = esp_matter_int8(attribute_value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType attribute_value; + memcpy((uint8_t *)&attribute_value, value, sizeof(Traits::StorageType)); + if (attribute_metadata->IsNullable()) { + if (Traits::IsNullValue(attribute_value)) { + *val = esp_matter_nullable_int8(nullable()); + } else { + *val = esp_matter_nullable_int8(attribute_value); + } + } else { + *val = esp_matter_int8(attribute_value); + } break; } case ZCL_INT8U_ATTRIBUTE_TYPE: { - uint8_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(uint8_t)); - *val = esp_matter_uint8(attribute_value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType attribute_value; + memcpy((uint8_t *)&attribute_value, value, sizeof(Traits::StorageType)); + if (attribute_metadata->IsNullable()) { + if (Traits::IsNullValue(attribute_value)) { + *val = esp_matter_nullable_uint8(nullable()); + } else { + *val = esp_matter_nullable_uint8(attribute_value); + } + } else { + *val = esp_matter_uint8(attribute_value); + } break; } case ZCL_INT16S_ATTRIBUTE_TYPE: { - int16_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(int16_t)); - *val = esp_matter_int16(attribute_value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType attribute_value; + memcpy((uint8_t *)&attribute_value, value, sizeof(Traits::StorageType)); + if (attribute_metadata->IsNullable()) { + if (Traits::IsNullValue(attribute_value)) { + *val = esp_matter_nullable_int16(nullable()); + } else { + *val = esp_matter_nullable_int16(attribute_value); + } + } else { + *val = esp_matter_int16(attribute_value); + } break; } case ZCL_INT16U_ATTRIBUTE_TYPE: { - uint16_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(uint16_t)); - *val = esp_matter_uint16(attribute_value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType attribute_value; + memcpy((uint8_t *)&attribute_value, value, sizeof(Traits::StorageType)); + if (attribute_metadata->IsNullable()) { + if (Traits::IsNullValue(attribute_value)) { + *val = esp_matter_nullable_uint16(nullable()); + } else { + *val = esp_matter_nullable_uint16(attribute_value); + } + } else { + *val = esp_matter_uint16(attribute_value); + } break; } case ZCL_INT32S_ATTRIBUTE_TYPE: { - int32_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(int32_t)); - *val = esp_matter_int32(attribute_value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType attribute_value; + memcpy((uint8_t *)&attribute_value, value, sizeof(Traits::StorageType)); + if (attribute_metadata->IsNullable()) { + if (Traits::IsNullValue(attribute_value)) { + *val = esp_matter_nullable_int32(nullable()); + } else { + *val = esp_matter_nullable_int32(attribute_value); + } + } else { + *val = esp_matter_int32(attribute_value); + } break; } case ZCL_INT32U_ATTRIBUTE_TYPE: { - uint32_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(uint32_t)); - *val = esp_matter_uint32(attribute_value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType attribute_value; + memcpy((uint8_t *)&attribute_value, value, sizeof(Traits::StorageType)); + if (attribute_metadata->IsNullable()) { + if (Traits::IsNullValue(attribute_value)) { + *val = esp_matter_nullable_uint32(nullable()); + } else { + *val = esp_matter_nullable_uint32(attribute_value); + } + } else { + *val = esp_matter_uint32(attribute_value); + } break; } case ZCL_INT64S_ATTRIBUTE_TYPE: { - int64_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(int64_t)); - *val = esp_matter_int64(attribute_value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType attribute_value; + memcpy((uint8_t *)&attribute_value, value, sizeof(Traits::StorageType)); + if (attribute_metadata->IsNullable()) { + if (Traits::IsNullValue(attribute_value)) { + *val = esp_matter_nullable_int64(nullable()); + } else { + *val = esp_matter_nullable_int64(attribute_value); + } + } else { + *val = esp_matter_int64(attribute_value); + } break; } case ZCL_INT64U_ATTRIBUTE_TYPE: { - uint64_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(uint64_t)); - *val = esp_matter_uint64(attribute_value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType attribute_value; + memcpy((uint8_t *)&attribute_value, value, sizeof(Traits::StorageType)); + if (attribute_metadata->IsNullable()) { + if (Traits::IsNullValue(attribute_value)) { + *val = esp_matter_nullable_uint64(nullable()); + } else { + *val = esp_matter_nullable_uint64(attribute_value); + } + } else { + *val = esp_matter_uint64(attribute_value); + } break; } case ZCL_ENUM8_ATTRIBUTE_TYPE: { - uint8_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(uint8_t)); - *val = esp_matter_enum8(attribute_value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType attribute_value; + memcpy((uint8_t *)&attribute_value, value, sizeof(Traits::StorageType)); + if (attribute_metadata->IsNullable()) { + if (Traits::IsNullValue(attribute_value)) { + *val = esp_matter_nullable_enum8(nullable()); + } else { + *val = esp_matter_nullable_enum8(attribute_value); + } + } else { + *val = esp_matter_enum8(attribute_value); + } break; } case ZCL_BITMAP8_ATTRIBUTE_TYPE: { - uint8_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(uint8_t)); - *val = esp_matter_bitmap8(attribute_value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType attribute_value; + memcpy((uint8_t *)&attribute_value, value, sizeof(Traits::StorageType)); + if (attribute_metadata->IsNullable()) { + if (Traits::IsNullValue(attribute_value)) { + *val = esp_matter_nullable_bitmap8(nullable()); + } else { + *val = esp_matter_nullable_bitmap8(attribute_value); + } + } else { + *val = esp_matter_bitmap8(attribute_value); + } break; } case ZCL_BITMAP16_ATTRIBUTE_TYPE: { - uint16_t attribute_value = 0; - memcpy((uint8_t *)&attribute_value, value, sizeof(uint16_t)); - *val = esp_matter_bitmap16(attribute_value); + using Traits = chip::app::NumericAttributeTraits; + Traits::StorageType attribute_value; + memcpy((uint8_t *)&attribute_value, value, sizeof(Traits::StorageType)); + if (attribute_metadata->IsNullable()) { + if (Traits::IsNullValue(attribute_value)) { + *val = esp_matter_nullable_bitmap16(nullable()); + } else { + *val = esp_matter_nullable_bitmap16(attribute_value); + } + } else { + *val = esp_matter_bitmap16(attribute_value); + } break; } @@ -933,35 +1584,44 @@ static esp_err_t get_attr_val_from_data(esp_matter_attr_val_t *val, EmberAfAttri void val_print(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id, esp_matter_attr_val_t *val) { + if (val_is_null(val)) { + ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is null **********", endpoint_id, + cluster_id, attribute_id); + return; + } + if (val->type == ESP_MATTER_VAL_TYPE_BOOLEAN) { ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %d **********", endpoint_id, cluster_id, attribute_id, val->val.b); - } else if (val->type == ESP_MATTER_VAL_TYPE_INTEGER) { + } else if (val->type == ESP_MATTER_VAL_TYPE_INTEGER || val->type == ESP_MATTER_VAL_TYPE_NULLABLE_INTEGER) { ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %d **********", endpoint_id, cluster_id, attribute_id, val->val.i); - } else if (val->type == ESP_MATTER_VAL_TYPE_FLOAT) { + } else if (val->type == ESP_MATTER_VAL_TYPE_FLOAT || val->type == ESP_MATTER_VAL_TYPE_NULLABLE_FLOAT) { ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %f **********", endpoint_id, cluster_id, attribute_id, val->val.f); } else if (val->type == ESP_MATTER_VAL_TYPE_UINT8 || val->type == ESP_MATTER_VAL_TYPE_BITMAP8 - || val->type == ESP_MATTER_VAL_TYPE_ENUM8) { + || val->type == ESP_MATTER_VAL_TYPE_ENUM8 || val->type == ESP_MATTER_VAL_TYPE_NULLABLE_UINT8 + || val->type == ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP8 || val->type == ESP_MATTER_VAL_TYPE_NULLABLE_ENUM8) { ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %d **********", endpoint_id, cluster_id, attribute_id, val->val.u8); - } else if (val->type == ESP_MATTER_VAL_TYPE_INT16) { + } else if (val->type == ESP_MATTER_VAL_TYPE_INT16 || val->type == ESP_MATTER_VAL_TYPE_NULLABLE_INT16) { ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %d **********", endpoint_id, cluster_id, attribute_id, val->val.i16); - } else if (val->type == ESP_MATTER_VAL_TYPE_UINT16 || val->type == ESP_MATTER_VAL_TYPE_BITMAP16) { + } else if (val->type == ESP_MATTER_VAL_TYPE_UINT16 || val->type == ESP_MATTER_VAL_TYPE_BITMAP16 + || val->type == ESP_MATTER_VAL_TYPE_NULLABLE_UINT16 || val->type == ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP16) { ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %d **********", endpoint_id, cluster_id, attribute_id, val->val.u16); - } else if (val->type == ESP_MATTER_VAL_TYPE_INT32) { + } else if (val->type == ESP_MATTER_VAL_TYPE_INT32|| val->type == ESP_MATTER_VAL_TYPE_NULLABLE_INT32) { ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %d **********", endpoint_id, cluster_id, attribute_id, val->val.i32); - } else if (val->type == ESP_MATTER_VAL_TYPE_UINT32 || val->type == ESP_MATTER_VAL_TYPE_BITMAP32) { + } else if (val->type == ESP_MATTER_VAL_TYPE_UINT32 || val->type == ESP_MATTER_VAL_TYPE_BITMAP32 + || val->type == ESP_MATTER_VAL_TYPE_NULLABLE_UINT32 || val->type == ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP32) { ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %d **********", endpoint_id, cluster_id, attribute_id, val->val.u32); - } else if (val->type == ESP_MATTER_VAL_TYPE_INT64) { + } else if (val->type == ESP_MATTER_VAL_TYPE_INT64 || val->type == ESP_MATTER_VAL_TYPE_NULLABLE_INT64) { ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %lld **********", endpoint_id, cluster_id, attribute_id, val->val.i64); - } else if (val->type == ESP_MATTER_VAL_TYPE_UINT64) { + } else if (val->type == ESP_MATTER_VAL_TYPE_UINT64 || val->type == ESP_MATTER_VAL_TYPE_NULLABLE_UINT64) { ESP_LOGI(TAG, "********** Endpoint 0x%04X's Cluster 0x%04X's Attribute 0x%04X is %lld **********", endpoint_id, cluster_id, attribute_id, val->val.u64); } else if (val->type == ESP_MATTER_VAL_TYPE_CHAR_STRING) { @@ -1051,8 +1711,10 @@ Status MatterPreAttributeChangeCallback(const chip::app::ConcreteAttributePath & uint16_t endpoint_id = path.mEndpointId; uint32_t cluster_id = path.mClusterId; uint32_t attribute_id = path.mAttributeId; + const EmberAfAttributeMetadata *attribute_metadata = emberAfLocateAttributeMetadata(endpoint_id, cluster_id, + attribute_id); esp_matter_attr_val_t val = esp_matter_invalid(NULL); - attribute::get_attr_val_from_data(&val, type, size, value); + attribute::get_attr_val_from_data(&val, type, size, value, attribute_metadata); /* Print */ attribute::val_print(endpoint_id, cluster_id, attribute_id, &val); @@ -1071,8 +1733,10 @@ void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath &p uint16_t endpoint_id = path.mEndpointId; uint32_t cluster_id = path.mClusterId; uint32_t attribute_id = path.mAttributeId; + const EmberAfAttributeMetadata *attribute_metadata = emberAfLocateAttributeMetadata(endpoint_id, cluster_id, + attribute_id); esp_matter_attr_val_t val = esp_matter_invalid(NULL); - attribute::get_attr_val_from_data(&val, type, size, value); + attribute::get_attr_val_from_data(&val, type, size, value, attribute_metadata); /* Callback to application */ execute_callback(attribute::POST_UPDATE, endpoint_id, cluster_id, attribute_id, &val); @@ -1138,7 +1802,7 @@ EmberAfStatus emberAfExternalAttributeWriteCallback(EndpointId endpoint_id, Clus /* This creates a new variable val, and stores the new attribute value in the new variable. The value in esp-matter data model is updated only when attribute::set_val() is called */ esp_matter_attr_val_t val = esp_matter_invalid(NULL); - attribute::get_attr_val_from_data(&val, matter_attribute->attributeType, matter_attribute->size, buffer); + attribute::get_attr_val_from_data(&val, matter_attribute->attributeType, matter_attribute->size, buffer, matter_attribute); int flags = attribute::get_flags(attribute); if (flags & ATTRIBUTE_FLAG_OVERRIDE) { diff --git a/components/esp_matter/esp_matter_attribute_utils.h b/components/esp_matter/esp_matter_attribute_utils.h index 14d00e99d..49d15dfb5 100644 --- a/components/esp_matter/esp_matter_attribute_utils.h +++ b/components/esp_matter/esp_matter_attribute_utils.h @@ -18,6 +18,8 @@ #include #include +#include + /** Remap attribute values * * This can be used to remap attribute values to different ranges. @@ -33,46 +35,64 @@ */ #define REMAP_TO_RANGE_INVERSE(value, factor) (factor / value) +/* Nullable base for nullable attribute */ +#define ESP_MATTER_VAL_NULLANLE_BASE 0x80 + /** ESP Matter Attribute Value type */ typedef enum { /** Invalid */ ESP_MATTER_VAL_TYPE_INVALID = 0, /** Boolean */ - ESP_MATTER_VAL_TYPE_BOOLEAN, + ESP_MATTER_VAL_TYPE_BOOLEAN = 1, /** Integer. Mapped to a 32 bit signed integer */ - ESP_MATTER_VAL_TYPE_INTEGER, + ESP_MATTER_VAL_TYPE_INTEGER = 2, /** Floating point number */ - ESP_MATTER_VAL_TYPE_FLOAT, + ESP_MATTER_VAL_TYPE_FLOAT = 3, /** Array Eg. [1,2,3] */ - ESP_MATTER_VAL_TYPE_ARRAY, + ESP_MATTER_VAL_TYPE_ARRAY = 4, /** Char String Eg. "123" */ - ESP_MATTER_VAL_TYPE_CHAR_STRING, + ESP_MATTER_VAL_TYPE_CHAR_STRING = 5, /** Octet String Eg. [0x01, 0x20] */ - ESP_MATTER_VAL_TYPE_OCTET_STRING, + ESP_MATTER_VAL_TYPE_OCTET_STRING = 6, /** 8 bit signed integer */ - ESP_MATTER_VAL_TYPE_INT8, + ESP_MATTER_VAL_TYPE_INT8 = 7, /** 8 bit unsigned integer */ - ESP_MATTER_VAL_TYPE_UINT8, + ESP_MATTER_VAL_TYPE_UINT8 = 8, /** 16 bit signed integer */ - ESP_MATTER_VAL_TYPE_INT16, + ESP_MATTER_VAL_TYPE_INT16 = 9, /** 16 bit unsigned integer */ - ESP_MATTER_VAL_TYPE_UINT16, + ESP_MATTER_VAL_TYPE_UINT16 = 10, /** 32 bit signed integer */ - ESP_MATTER_VAL_TYPE_INT32, + ESP_MATTER_VAL_TYPE_INT32 = 11, /** 32 bit unsigned integer */ - ESP_MATTER_VAL_TYPE_UINT32, + ESP_MATTER_VAL_TYPE_UINT32 = 12, /** 64 bit signed integer */ - ESP_MATTER_VAL_TYPE_INT64, + ESP_MATTER_VAL_TYPE_INT64 = 13, /** 64 bit unsigned integer */ - ESP_MATTER_VAL_TYPE_UINT64, + ESP_MATTER_VAL_TYPE_UINT64 = 14, /** 8 bit enum */ - ESP_MATTER_VAL_TYPE_ENUM8, + ESP_MATTER_VAL_TYPE_ENUM8 = 15, /** 8 bit bitmap */ - ESP_MATTER_VAL_TYPE_BITMAP8, + ESP_MATTER_VAL_TYPE_BITMAP8 = 16, /** 16 bit bitmap */ - ESP_MATTER_VAL_TYPE_BITMAP16, + ESP_MATTER_VAL_TYPE_BITMAP16 = 17, /** 32 bit bitmap */ - ESP_MATTER_VAL_TYPE_BITMAP32, + ESP_MATTER_VAL_TYPE_BITMAP32 = 18, + /** nullable types **/ + ESP_MATTER_VAL_TYPE_NULLABLE_INTEGER = ESP_MATTER_VAL_TYPE_INTEGER + ESP_MATTER_VAL_NULLANLE_BASE, + ESP_MATTER_VAL_TYPE_NULLABLE_FLOAT = ESP_MATTER_VAL_TYPE_FLOAT + ESP_MATTER_VAL_NULLANLE_BASE, + ESP_MATTER_VAL_TYPE_NULLABLE_INT8 = ESP_MATTER_VAL_TYPE_INT8 + ESP_MATTER_VAL_NULLANLE_BASE, + ESP_MATTER_VAL_TYPE_NULLABLE_UINT8 = ESP_MATTER_VAL_TYPE_UINT8 + ESP_MATTER_VAL_NULLANLE_BASE, + ESP_MATTER_VAL_TYPE_NULLABLE_INT16 = ESP_MATTER_VAL_TYPE_INT16 + ESP_MATTER_VAL_NULLANLE_BASE, + ESP_MATTER_VAL_TYPE_NULLABLE_UINT16 = ESP_MATTER_VAL_TYPE_UINT16 + ESP_MATTER_VAL_NULLANLE_BASE, + ESP_MATTER_VAL_TYPE_NULLABLE_INT32 = ESP_MATTER_VAL_TYPE_INT32 + ESP_MATTER_VAL_NULLANLE_BASE, + ESP_MATTER_VAL_TYPE_NULLABLE_UINT32 = ESP_MATTER_VAL_TYPE_UINT32 + ESP_MATTER_VAL_NULLANLE_BASE, + ESP_MATTER_VAL_TYPE_NULLABLE_INT64 = ESP_MATTER_VAL_TYPE_INT64 + ESP_MATTER_VAL_NULLANLE_BASE, + ESP_MATTER_VAL_TYPE_NULLABLE_UINT64 = ESP_MATTER_VAL_TYPE_UINT64 + ESP_MATTER_VAL_NULLANLE_BASE, + ESP_MATTER_VAL_TYPE_NULLABLE_ENUM8 = ESP_MATTER_VAL_TYPE_ENUM8 + ESP_MATTER_VAL_NULLANLE_BASE, + ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP8 = ESP_MATTER_VAL_TYPE_BITMAP8 + ESP_MATTER_VAL_NULLANLE_BASE, + ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP16 = ESP_MATTER_VAL_TYPE_BITMAP16 + ESP_MATTER_VAL_NULLANLE_BASE, + ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP32= ESP_MATTER_VAL_TYPE_BITMAP32 + ESP_MATTER_VAL_NULLANLE_BASE, } esp_matter_val_type_t; /** ESP Matter Value */ @@ -131,54 +151,110 @@ typedef struct esp_matter_attr_bounds { /** TODO: Step Value might be needed here later */ } esp_matter_attr_bounds_t; +template +class nullable { +public: + nullable(T value) + { + assert(!chip::app::NumericAttributeTraits::IsNullValue(value)); + val = value; + } + nullable() + { + chip::app::NumericAttributeTraits::SetNull(val); + } + + T value() + { + assert(!is_null()); + return val; + } + + T value_or(T ret) + { + return is_null() ? ret : val; + } + + bool is_null() + { + return chip::app::NumericAttributeTraits::IsNullValue(val); + } + + void operator=(T value) + { + assert(!chip::app::NumericAttributeTraits::IsNullValue(value)); + this->val = value; + } + + void operator=(std::nullptr_t) + { + chip::app::NumericAttributeTraits::SetNull(this->val); + } +private: + T val; +}; + /*** Attribute val APIs ***/ /** Invalid */ esp_matter_attr_val_t esp_matter_invalid(void *val); - /** Boolean */ esp_matter_attr_val_t esp_matter_bool(bool val); /** Integer */ esp_matter_attr_val_t esp_matter_int(int val); +esp_matter_attr_val_t esp_matter_nullable_int(nullable val); /** Float */ esp_matter_attr_val_t esp_matter_float(float val); +esp_matter_attr_val_t esp_matter_nullable_float(nullable val); /** 8 bit integer */ esp_matter_attr_val_t esp_matter_int8(int8_t val); +esp_matter_attr_val_t esp_matter_nullable_int8(nullable val); /** 8 bit unsigned integer */ esp_matter_attr_val_t esp_matter_uint8(uint8_t val); +esp_matter_attr_val_t esp_matter_nullable_uint8(nullable val); /** 16 bit signed integer */ esp_matter_attr_val_t esp_matter_int16(int16_t val); +esp_matter_attr_val_t esp_matter_nullable_int16(nullable val); /** 16 bit unsigned integer */ esp_matter_attr_val_t esp_matter_uint16(uint16_t val); +esp_matter_attr_val_t esp_matter_nullable_uint16(nullable val); /** 32 bit signed integer */ esp_matter_attr_val_t esp_matter_int32(int32_t val); +esp_matter_attr_val_t esp_matter_nullable_int32(nullable val); /** 32 bit unsigned integer */ esp_matter_attr_val_t esp_matter_uint32(uint32_t val); +esp_matter_attr_val_t esp_matter_nullable_uint32(nullable val); /** 64 bit signed integer */ esp_matter_attr_val_t esp_matter_int64(int64_t val); +esp_matter_attr_val_t esp_matter_nullable_int64(nullable val); /** 64 bit unsigned integer */ esp_matter_attr_val_t esp_matter_uint64(uint64_t val); +esp_matter_attr_val_t esp_matter_nullable_uint64(nullable val); /** 8 bit enum */ esp_matter_attr_val_t esp_matter_enum8(uint8_t val); +esp_matter_attr_val_t esp_matter_nullable_enum8(nullable val); /** 8 bit bitmap */ esp_matter_attr_val_t esp_matter_bitmap8(uint8_t val); +esp_matter_attr_val_t esp_matter_nullable_bitmap8(nullable val); /** 16 bit bitmap */ esp_matter_attr_val_t esp_matter_bitmap16(uint16_t val); +esp_matter_attr_val_t esp_matter_nullable_bitmap16(nullable val); /** 32 bit bitmap */ esp_matter_attr_val_t esp_matter_bitmap32(uint32_t val); +esp_matter_attr_val_t esp_matter_nullable_bitmap32(nullable val); /** Character string */ esp_matter_attr_val_t esp_matter_char_str(char *val, uint16_t data_size); @@ -190,6 +266,7 @@ esp_matter_attr_val_t esp_matter_octet_str(uint8_t *val, uint16_t data_size); esp_matter_attr_val_t esp_matter_array(uint8_t *val, uint16_t data_size, uint16_t count); namespace esp_matter { + namespace attribute { /** Attribute update callback type */ diff --git a/components/esp_matter/esp_matter_cluster.cpp b/components/esp_matter/esp_matter_cluster.cpp index 55aa9bf5d..3fc567a63 100644 --- a/components/esp_matter/esp_matter_cluster.cpp +++ b/components/esp_matter/esp_matter_cluster.cpp @@ -428,9 +428,9 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) attribute::create_scan_max_time_seconds(cluster, 0); attribute::create_connect_max_time_seconds(cluster, 0); attribute::create_interface_enabled(cluster, 0); - attribute::create_last_networking_status(cluster, 0); + attribute::create_last_networking_status(cluster, nullable()); attribute::create_last_network_id(cluster, NULL, 0); - attribute::create_last_connect_error_value(cluster, 0); + attribute::create_last_connect_error_value(cluster, nullable()); global::attribute::create_feature_map(cluster, 0); /* Attributes not managed internally */ @@ -668,10 +668,10 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) /* Attributes managed internally */ global::attribute::create_feature_map(cluster, 0); attribute::create_bssid(cluster, NULL, 0); - attribute::create_security_type(cluster, 0); - attribute::create_wifi_version(cluster, 0); - attribute::create_channel_number(cluster, 0); - attribute::create_rssi(cluster, 0); + attribute::create_security_type(cluster, nullable()); + attribute::create_wifi_version(cluster, nullable()); + attribute::create_channel_number(cluster, nullable()); + attribute::create_rssi(cluster, nullable()); /* Attributes not managed internally */ if (config) { @@ -709,19 +709,19 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) if (flags & CLUSTER_FLAG_SERVER) { /* Attributes managed internally */ global::attribute::create_feature_map(cluster, 0); - attribute::create_channel(cluster, 0); - attribute::create_routing_role(cluster, 0); + attribute::create_channel(cluster, nullable(0)); + attribute::create_routing_role(cluster, nullable(0)); attribute::create_network_name(cluster, NULL, 0); - attribute::create_pan_id(cluster, 0); - attribute::create_extended_pan_id(cluster, 0); + attribute::create_pan_id(cluster, nullable(0)); + attribute::create_extended_pan_id(cluster, nullable(0)); attribute::create_mesh_local_prefix(cluster, NULL, 0); attribute::create_neighbor_table(cluster, NULL, 0, 0); attribute::create_route_table(cluster, NULL, 0, 0); - attribute::create_partition_id(cluster, 0); - attribute::create_weighting(cluster, 0); - attribute::create_data_version(cluster, 0); - attribute::create_stable_data_version(cluster, 0); - attribute::create_leader_router_id(cluster, 0); + attribute::create_partition_id(cluster, nullable(0)); + attribute::create_weighting(cluster, nullable(0)); + attribute::create_data_version(cluster, nullable(0)); + attribute::create_stable_data_version(cluster, nullable(0)); + attribute::create_leader_router_id(cluster, nullable(0)); attribute::create_security_policy(cluster, NULL, 0, 0); attribute::create_channel_page0_mask(cluster, NULL, 0); attribute::create_operational_dataset_components(cluster, NULL, 0, 0); @@ -1201,10 +1201,10 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_ /* Attributes managed internally */ attribute::create_remaining_time(cluster, 0); - for (uint8_t idx = 1; idx <= config->number_of_primaries; ++idx) { + for (uint8_t idx = 1; idx <= config->number_of_primaries.value_or(0); ++idx) { attribute::create_primary_n_x(cluster, 0, idx); attribute::create_primary_n_y(cluster, 0, idx); - attribute::create_primary_n_intensity(cluster, 0, idx); + attribute::create_primary_n_intensity(cluster, nullable(), idx); } } diff --git a/components/esp_matter/esp_matter_cluster.h b/components/esp_matter/esp_matter_cluster.h index 94b4c297d..29ca709ef 100644 --- a/components/esp_matter/esp_matter_cluster.h +++ b/components/esp_matter/esp_matter_cluster.h @@ -85,7 +85,7 @@ typedef struct config { uint16_t cluster_revision; bool update_possible; uint8_t update_state; - uint8_t update_state_progress; + nullable update_state_progress; config() : cluster_revision(1), update_possible(1), update_state(0), update_state_progress(0) {} } config_t; @@ -247,11 +247,11 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_ namespace level_control { typedef struct config { uint16_t cluster_revision; - uint8_t current_level; - uint8_t on_level; + nullable current_level; + nullable on_level; uint8_t options; feature::lighting::config_t lighting; - config() : cluster_revision(5), current_level(0xFF), on_level(0xFF), options(0) {} + config() : cluster_revision(5), current_level(0xFE), on_level(0xFE), options(0) {} } config_t; cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features); @@ -264,7 +264,7 @@ typedef struct config { uint8_t color_control_options; uint8_t enhanced_color_mode; uint16_t color_capabilities; - uint8_t number_of_primaries; + nullable number_of_primaries; feature::hue_saturation::config_t hue_saturation; feature::color_temperature::config_t color_temperature; feature::xy::config_t xy; @@ -282,7 +282,7 @@ typedef struct config { uint16_t cluster_revision; uint8_t fan_mode; uint8_t fan_mode_sequence; - uint8_t percent_setting; + nullable percent_setting; uint8_t percent_current; config() : cluster_revision(2), fan_mode(0), fan_mode_sequence(2), percent_setting(0), percent_current(0) {} } config_t; @@ -293,10 +293,10 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); namespace thermostat { typedef struct config { uint16_t cluster_revision; - int16_t local_temperature; + nullable local_temperature; uint8_t control_sequence_of_operation; uint8_t system_mode; - config() : cluster_revision(5), local_temperature(0xFFFF), control_sequence_of_operation(4), system_mode(1) {} + config() : cluster_revision(5), local_temperature(), control_sequence_of_operation(4), system_mode(1) {} } config_t; cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); @@ -305,7 +305,7 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); namespace door_lock { typedef struct config { uint16_t cluster_revision; - uint8_t lock_state; + nullable lock_state; uint8_t lock_type; bool actuator_enabled; uint8_t operating_mode; @@ -322,19 +322,19 @@ typedef struct config { uint8_t type; uint16_t physical_closed_limit_lift; uint16_t physical_closed_limit_tilt; - uint8_t current_position_lift; - uint8_t current_position_tilt; + nullable current_position_lift; + nullable current_position_tilt; uint16_t number_of_actuations_lift; uint16_t number_of_actuations_tilt; uint8_t config_status; - uint8_t current_position_lift_percentage; - uint8_t current_position_tilt_percentage; - uint8_t operational_status; - uint16_t target_position_lift_percent_100ths; - uint16_t target_position_tilt_percent_100ths; + nullable current_position_lift_percentage; + nullable current_position_tilt_percentage; + nullable operational_status; + nullable target_position_lift_percent_100ths; + nullable target_position_tilt_percent_100ths; uint8_t end_product_type; - uint16_t current_position_lift_percent_100ths; - uint16_t current_position_tilt_percent_100ths; + nullable current_position_lift_percent_100ths; + nullable current_position_tilt_percent_100ths; uint16_t installed_open_limit_lift; uint16_t installed_closed_limit_lift; uint16_t installed_open_limit_tilt; @@ -361,10 +361,10 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); namespace temperature_measurement { typedef struct config { uint16_t cluster_revision; - int16_t measured_value; - int16_t min_measured_value; - int16_t max_measured_value; - config() : cluster_revision(4), measured_value(-32768), min_measured_value(-32768), max_measured_value(-32768) {} + nullable measured_value; + nullable min_measured_value; + nullable max_measured_value; + config() : cluster_revision(4), measured_value(), min_measured_value(), max_measured_value() {} } config_t; cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); diff --git a/components/esp_matter/esp_matter_feature.h b/components/esp_matter/esp_matter_feature.h index de7ac4ae4..6f58a0910 100644 --- a/components/esp_matter/esp_matter_feature.h +++ b/components/esp_matter/esp_matter_feature.h @@ -37,9 +37,9 @@ namespace lighting { typedef struct config { bool global_scene_control; - uint16_t on_time; - uint16_t off_wait_time; - uint8_t start_up_on_off; + nullable on_time; + nullable off_wait_time; + nullable start_up_on_off; config() : global_scene_control(1), on_time(0), off_wait_time(0), start_up_on_off(0) {} } config_t; @@ -65,7 +65,7 @@ typedef struct config { uint16_t remaining_time; uint8_t min_level; uint8_t max_level; - uint8_t start_up_current_level; + nullable start_up_current_level; config() : remaining_time(0), min_level(1), max_level(254), start_up_current_level(0) {} } config_t; @@ -111,7 +111,7 @@ typedef struct config { uint16_t color_temp_physical_min_mireds; uint16_t color_temp_physical_max_mireds; uint16_t couple_color_temp_to_level_min_mireds; - uint16_t startup_color_temperature_mireds; + nullable startup_color_temperature_mireds; config() : color_temperature_mireds(0x00fa), color_temp_physical_min_mireds(0), color_temp_physical_max_mireds(0xfeff), couple_color_temp_to_level_min_mireds(0), startup_color_temperature_mireds(0x00fa) {} diff --git a/examples/light/main/app_main.cpp b/examples/light/main/app_main.cpp index 65d4913d1..2182092d7 100644 --- a/examples/light/main/app_main.cpp +++ b/examples/light/main/app_main.cpp @@ -100,10 +100,11 @@ extern "C" void app_main() color_temperature_light::config_t light_config; light_config.on_off.on_off = DEFAULT_POWER; - light_config.on_off.lighting.start_up_on_off = DEFAULT_POWER; + light_config.on_off.lighting.start_up_on_off = nullptr; light_config.level_control.current_level = DEFAULT_BRIGHTNESS; light_config.level_control.lighting.start_up_current_level = DEFAULT_BRIGHTNESS; light_config.color_control.color_mode = EMBER_ZCL_COLOR_MODE_COLOR_TEMPERATURE; + light_config.color_control.color_temperature.startup_color_temperature_mireds = nullptr; endpoint_t *endpoint = color_temperature_light::create(node, &light_config, ENDPOINT_FLAG_NONE, light_handle); /* These node and endpoint handles can be used to create/add other endpoints and clusters. */