use super::ffi;
use huesmith_core::hue::device::HueDeviceType;
fn reportable_change(attr_type: u8) -> ffi::esp_zb_zcl_attr_var_u {
match attr_type {
ffi::ZCL_ATTR_TYPE_BOOL | ffi::ZCL_ATTR_TYPE_U8 | ffi::ZCL_ATTR_TYPE_ENUM8 => {
ffi::esp_zb_zcl_attr_var_u::from_u8(1)
}
ffi::ZCL_ATTR_TYPE_U16 => ffi::esp_zb_zcl_attr_var_u::from_u16(1),
_ => ffi::esp_zb_zcl_attr_var_u::zero(),
}
}
pub fn configure_reporting(
endpoint: u8,
cluster_id: u16,
attr_id: u16,
attr_type: u8,
min_interval: u16,
max_interval: u16,
) {
let attr_location = ffi::esp_zb_zcl_attr_location_info_t {
endpoint_id: endpoint,
cluster_id,
cluster_role: ffi::ZB_ZCL_CLUSTER_SERVER_ROLE,
manuf_code: ffi::ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC,
attr_id,
};
let mut info = ffi::esp_zb_zcl_reporting_info_t {
direction: ffi::ZB_ZCL_REPORT_DIRECTION_SEND,
ep: endpoint,
cluster_id,
cluster_role: ffi::ZB_ZCL_CLUSTER_SERVER_ROLE,
attr_id,
flags: 0,
run_time: 0,
u: ffi::esp_zb_zcl_reporting_info_u {
send_info: ffi::esp_zb_zcl_reporting_send_info_t {
min_interval,
max_interval,
delta: reportable_change(attr_type),
reported_value: ffi::esp_zb_zcl_attr_var_u::zero(),
def_min_interval: min_interval,
def_max_interval: max_interval,
},
},
dst: ffi::esp_zb_zcl_reporting_dst_t {
short_addr: 0,
endpoint: 0,
profile_id: ffi::PROFILE_HA,
},
manuf_code: ffi::ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC,
};
let ret = unsafe { ffi::esp_zb_zcl_update_reporting_info(&mut info) };
if ret != 0 {
log::warn!(
"Failed to configure reporting for cluster 0x{:04X} attr 0x{:04X}: {}",
cluster_id,
attr_id,
ret,
);
return;
}
let ret = unsafe { ffi::esp_zb_zcl_start_attr_reporting(attr_location) };
if ret != 0 {
log::warn!(
"Failed to start reporting for cluster 0x{:04X} attr 0x{:04X}: {}",
cluster_id,
attr_id,
ret,
);
}
}
pub fn setup_default_reporting(endpoint: u8, device_type: HueDeviceType) {
let has_level_control = device_type.has_level_control();
let has_color_control = device_type.has_color_control();
configure_reporting(
endpoint,
ffi::CLUSTER_ON_OFF,
ffi::ATTR_ON_OFF,
ffi::ZCL_ATTR_TYPE_BOOL,
1, 300, );
if has_level_control {
configure_reporting(
endpoint,
ffi::CLUSTER_LEVEL_CONTROL,
ffi::ATTR_LEVEL_CURRENT_LEVEL,
ffi::ZCL_ATTR_TYPE_U8,
1,
300,
);
}
if !has_color_control {
return;
}
configure_reporting(
endpoint,
ffi::CLUSTER_COLOR_CONTROL,
ffi::ATTR_COLOR_CURRENT_X,
ffi::ZCL_ATTR_TYPE_U16,
1,
300,
);
configure_reporting(
endpoint,
ffi::CLUSTER_COLOR_CONTROL,
ffi::ATTR_COLOR_CURRENT_Y,
ffi::ZCL_ATTR_TYPE_U16,
1,
300,
);
configure_reporting(
endpoint,
ffi::CLUSTER_COLOR_CONTROL,
ffi::ATTR_COLOR_TEMPERATURE_MIREDS,
ffi::ZCL_ATTR_TYPE_U16,
1,
300,
);
}