diff --git a/applications/main/subghz/scenes/subghz_scene_decode_raw.c b/applications/main/subghz/scenes/subghz_scene_decode_raw.c index 8df85de48..2ff1f4b52 100644 --- a/applications/main/subghz/scenes/subghz_scene_decode_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_decode_raw.c @@ -67,7 +67,8 @@ static void subghz_scene_add_to_history_callback( subghz->subghz_receiver, furi_string_get_cstr(item_name), furi_string_get_cstr(item_time), - subghz_history_get_type_protocol(subghz->history, idx)); + subghz_history_get_type_protocol(subghz->history, idx), + subghz_history_get_repeats(subghz->history, idx)); subghz_scene_receiver_update_statusbar(subghz); } @@ -185,7 +186,8 @@ void subghz_scene_decode_raw_on_enter(void* context) { subghz->subghz_receiver, furi_string_get_cstr(item_name), furi_string_get_cstr(item_time), - subghz_history_get_type_protocol(subghz->history, i)); + subghz_history_get_type_protocol(subghz->history, i), + subghz_history_get_repeats(subghz->history, i)); } subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, subghz->idx_menu_chosen); } diff --git a/applications/main/subghz/scenes/subghz_scene_receiver.c b/applications/main/subghz/scenes/subghz_scene_receiver.c index 8bf31334c..29809147b 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver.c @@ -122,43 +122,48 @@ static void subghz_scene_add_to_history_callback( subghz->state_notifications = SubGhzNotificationStateRxDone; + if(subghz->ignore_duplicates) { + // Look in history for signal hash + uint8_t hash_data = subghz_protocol_decoder_base_get_hash_data(decoder_base); + uint16_t menu_idx = subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); + subghz_view_receiver_disable_draw_callback(subghz->subghz_receiver); + for(uint16_t i = idx; i > 0; i--) { + i--; // Iterating in reverse with off by one + if(subghz_history_get_hash_data(subghz->history, i) == hash_data) { + // Remove previous instance and update menu index + subghz_history_delete_item(subghz->history, i); + subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, i); + subghz_view_receiver_delete_element_callback(subghz->subghz_receiver); + if(menu_idx > i) { + menu_idx--; + idx--; + } + } + i++; + } + // Restore ui state + subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, menu_idx); + subghz->idx_menu_chosen = + subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); + subghz_view_receiver_enable_draw_callback(subghz->subghz_receiver); + if(subghz_history_get_last_index(subghz->history) == 0) { + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateStart); + } + } + subghz_history_get_text_item_menu(history, item_name, idx); subghz_history_get_time_item_menu(history, item_time, idx); subghz_view_receiver_add_item_to_menu( subghz->subghz_receiver, furi_string_get_cstr(item_name), furi_string_get_cstr(item_time), - subghz_history_get_type_protocol(history, idx)); + subghz_history_get_type_protocol(history, idx), + subghz_history_get_repeats(history, idx)); subghz_scene_receiver_update_statusbar(subghz); if(subghz_history_get_text_space_left(subghz->history, NULL, 0)) { notification_message(subghz->notifications, &sequence_error); } - - if(subghz->ignore_duplicates) { - uint16_t history_count = subghz_history_get_last_index(subghz->history) - 1; - uint8_t hash_data = subghz_protocol_decoder_base_get_hash_data(decoder_base); - uint16_t menu_idx = subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); - subghz_view_receiver_disable_draw_callback(subghz->subghz_receiver); - - for(uint16_t idx = history_count; idx > 0; idx--) { - if(subghz_history_get_hash_data(subghz->history, idx - 1) == hash_data) { - subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, idx - 1); - subghz_history_delete_item(subghz->history, idx - 1); - subghz_view_receiver_delete_element_callback(subghz->subghz_receiver); - if(menu_idx > idx - 1) menu_idx--; - } - } - - subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, menu_idx); - subghz->idx_menu_chosen = - subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); - subghz_view_receiver_enable_draw_callback(subghz->subghz_receiver); - subghz_scene_receiver_update_statusbar(subghz); - if(subghz_history_get_last_index(subghz->history) == 0) { - subghz_rx_key_state_set(subghz, SubGhzRxKeyStateStart); - } - } } subghz_receiver_reset(receiver); furi_string_free(item_name); @@ -206,7 +211,8 @@ void subghz_scene_receiver_on_enter(void* context) { subghz->subghz_receiver, furi_string_get_cstr(item_name), furi_string_get_cstr(item_time), - subghz_history_get_type_protocol(history, i)); + subghz_history_get_type_protocol(history, i), + subghz_history_get_repeats(history, i)); subghz_rx_key_state_set(subghz, SubGhzRxKeyStateAddKey); } furi_string_free(item_name); diff --git a/applications/main/subghz/subghz_history.c b/applications/main/subghz/subghz_history.c index 0812808c2..9940b64a0 100644 --- a/applications/main/subghz/subghz_history.c +++ b/applications/main/subghz/subghz_history.c @@ -14,6 +14,7 @@ typedef struct { SubGhzRadioPreset* preset; FuriHalRtcDateTime datetime; uint8_t hash_data; + uint16_t repeats; float latitude; float longitude; } SubGhzHistoryItem; @@ -64,6 +65,12 @@ uint8_t subghz_history_get_hash_data(SubGhzHistory* instance, uint16_t idx) { return item->hash_data; } +uint16_t subghz_history_get_repeats(SubGhzHistory* instance, uint16_t idx) { + furi_assert(instance); + SubGhzHistoryItem* item = SubGhzHistoryItemArray_get(instance->history->data, idx); + return item->repeats; +} + uint32_t subghz_history_get_frequency(SubGhzHistory* instance, uint16_t idx) { furi_assert(instance); SubGhzHistoryItem* item = SubGhzHistoryItemArray_get(instance->history->data, idx); @@ -230,6 +237,18 @@ bool subghz_history_add_to_history( return false; } + uint16_t repeats = 0; + SubGhzHistoryItemArray_it_t it; + SubGhzHistoryItemArray_it_last(it, instance->history->data); + while(!SubGhzHistoryItemArray_end_p(it)) { + SubGhzHistoryItem* search = SubGhzHistoryItemArray_ref(it); + if(search->hash_data == hash_data) { + repeats = search->repeats + 1; + break; + } + SubGhzHistoryItemArray_previous(it); + } + instance->code_last_hash_data = hash_data; instance->last_update_timestamp = furi_get_tick(); @@ -244,6 +263,7 @@ bool subghz_history_add_to_history( item->preset->data_size = preset->data_size; furi_hal_rtc_get_datetime(&item->datetime); item->hash_data = hash_data; + item->repeats = repeats; item->latitude = preset->latitude; item->longitude = preset->longitude; diff --git a/applications/main/subghz/subghz_history.h b/applications/main/subghz/subghz_history.h index f2c93e127..41fc8e829 100644 --- a/applications/main/subghz/subghz_history.h +++ b/applications/main/subghz/subghz_history.h @@ -37,6 +37,14 @@ void subghz_history_delete_item(SubGhzHistory* instance, uint16_t item_id); */ uint8_t subghz_history_get_hash_data(SubGhzHistory* instance, uint16_t idx); +/** Get repeat count to history[idx] + * + * @param instance - SubGhzHistory instance + * @param idx - Record index + * @return repeats - uint16_t repeat count +*/ +uint16_t subghz_history_get_repeats(SubGhzHistory* instance, uint16_t idx); + /** Get frequency to history[idx] * * @param instance - SubGhzHistory instance diff --git a/applications/main/subghz/views/receiver.c b/applications/main/subghz/views/receiver.c index 44ffb1827..b0a340281 100644 --- a/applications/main/subghz/views/receiver.c +++ b/applications/main/subghz/views/receiver.c @@ -20,6 +20,7 @@ typedef struct { FuriString* item_str; FuriString* time; uint8_t type; + uint16_t repeats; } SubGhzReceiverMenuItem; ARRAY_DEF(SubGhzReceiverMenuItemArray, SubGhzReceiverMenuItem, M_POD_OPLIST) @@ -175,7 +176,8 @@ void subghz_view_receiver_add_item_to_menu( SubGhzViewReceiver* subghz_receiver, const char* name, const char* time, - uint8_t type) { + uint8_t type, + uint16_t repeats) { furi_assert(subghz_receiver); with_view_model( subghz_receiver->view, @@ -186,6 +188,7 @@ void subghz_view_receiver_add_item_to_menu( item_menu->time = furi_string_alloc_set(time); item_menu->item_str = furi_string_alloc_set(name); item_menu->type = type; + item_menu->repeats = repeats; if((model->idx == model->history_item - 1)) { model->history_item++; model->idx++; @@ -293,7 +296,15 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { if(item_menu->type == 0) { break; } - furi_string_set(str_buff, item_menu->item_str); + if(item_menu->repeats) { + furi_string_printf( + str_buff, + "x%u: %s", + item_menu->repeats + 1, + furi_string_get_cstr(item_menu->item_str)); + } else { + furi_string_set(str_buff, item_menu->item_str); + } if(model->idx == idx) { subghz_view_receiver_draw_frame(canvas, i, scrollbar); if(model->show_time) { diff --git a/applications/main/subghz/views/receiver.h b/applications/main/subghz/views/receiver.h index c280e1de6..6f8a5863f 100644 --- a/applications/main/subghz/views/receiver.h +++ b/applications/main/subghz/views/receiver.h @@ -47,7 +47,8 @@ void subghz_view_receiver_add_item_to_menu( SubGhzViewReceiver* subghz_receiver, const char* name, const char* time, - uint8_t type); + uint8_t type, + uint16_t repeats); uint16_t subghz_view_receiver_get_idx_menu(SubGhzViewReceiver* subghz_receiver);