Просмотр исходного кода

[FL-2456] App notifications update (#1175)

* Notifications update: SubGHz
* Notifications: ibutton, infrared, rfid
Nikolay Minaylov 3 лет назад
Родитель
Сommit
4526503d81
29 измененных файлов с 138 добавлено и 99 удалено
  1. 1 0
      applications/desktop/helpers/pin_lock.c
  2. 6 6
      applications/ibutton/ibutton_app.cpp
  3. 2 2
      applications/ibutton/ibutton_app.h
  4. 1 1
      applications/ibutton/scene/ibutton_scene_emulate.cpp
  5. 1 1
      applications/ibutton/scene/ibutton_scene_read.cpp
  6. 1 1
      applications/ibutton/scene/ibutton_scene_write.cpp
  7. 5 39
      applications/infrared/infrared_app.cpp
  8. 3 7
      applications/infrared/infrared_app.h
  9. 1 1
      applications/infrared/scene/infrared_app_scene_learn.cpp
  10. 0 1
      applications/infrared/scene/infrared_app_scene_learn_success.cpp
  11. 0 3
      applications/infrared/scene/infrared_app_scene_remote.cpp
  12. 2 0
      applications/infrared/scene/infrared_app_scene_universal_common.cpp
  13. 1 1
      applications/lfrfid/scene/lfrfid_app_scene_emulate.cpp
  14. 2 2
      applications/lfrfid/scene/lfrfid_app_scene_read.cpp
  15. 2 2
      applications/lfrfid/scene/lfrfid_app_scene_write.cpp
  16. 7 0
      applications/notification/notification_messages.c
  17. 1 0
      applications/notification/notification_messages.h
  18. 2 1
      applications/subghz/helpers/subghz_custom_event.h
  19. 12 2
      applications/subghz/scenes/subghz_scene_frequency_analyzer.c
  20. 18 11
      applications/subghz/scenes/subghz_scene_read_raw.c
  21. 22 3
      applications/subghz/scenes/subghz_scene_receiver.c
  22. 10 6
      applications/subghz/scenes/subghz_scene_receiver_info.c
  23. 10 0
      applications/subghz/scenes/subghz_scene_show_error.c
  24. 4 0
      applications/subghz/scenes/subghz_scene_show_error_sub.c
  25. 3 3
      applications/subghz/scenes/subghz_scene_transmitter.c
  26. 3 2
      applications/subghz/subghz_i.h
  27. 12 0
      applications/subghz/views/subghz_frequency_analyzer.c
  28. 0 2
      applications/subghz/views/subghz_read_raw.c
  29. 6 2
      applications/u2f/scenes/u2f_scene_main.c

+ 1 - 0
applications/desktop/helpers/pin_lock.c

@@ -77,6 +77,7 @@ void desktop_pin_lock_init(DesktopSettings* settings) {
         furi_hal_rtc_set_flag(FuriHalRtcFlagLock);
         furi_hal_rtc_set_flag(FuriHalRtcFlagLock);
         furi_hal_usb_disable();
         furi_hal_usb_disable();
     } else {
     } else {
+        furi_hal_rtc_set_pin_fails(0);
         furi_hal_rtc_reset_flag(FuriHalRtcFlagLock);
         furi_hal_rtc_reset_flag(FuriHalRtcFlagLock);
         furi_hal_usb_enable();
         furi_hal_usb_enable();
     }
     }

+ 6 - 6
applications/ibutton/ibutton_app.cpp

@@ -133,16 +133,16 @@ uint8_t iButtonApp::get_file_name_size() {
     return file_name_size;
     return file_name_size;
 }
 }
 
 
-void iButtonApp::notify_green_blink() {
-    notification_message(notification, &sequence_blink_green_10);
+void iButtonApp::notify_read() {
+    notification_message(notification, &sequence_blink_cyan_10);
 }
 }
 
 
-void iButtonApp::notify_yellow_blink() {
-    notification_message(notification, &sequence_blink_yellow_10);
+void iButtonApp::notify_emulate() {
+    notification_message(notification, &sequence_blink_magenta_10);
 }
 }
 
 
-void iButtonApp::notify_red_blink() {
-    notification_message(notification, &sequence_blink_red_10);
+void iButtonApp::notify_yellow_blink() {
+    notification_message(notification, &sequence_blink_yellow_10);
 }
 }
 
 
 void iButtonApp::notify_error() {
 void iButtonApp::notify_error() {

+ 2 - 2
applications/ibutton/ibutton_app.h

@@ -75,9 +75,9 @@ public:
     iButtonWorker* get_key_worker();
     iButtonWorker* get_key_worker();
     iButtonKey* get_key();
     iButtonKey* get_key();
 
 
-    void notify_green_blink();
+    void notify_read();
     void notify_yellow_blink();
     void notify_yellow_blink();
-    void notify_red_blink();
+    void notify_emulate();
 
 
     void notify_error();
     void notify_error();
     void notify_success();
     void notify_success();

+ 1 - 1
applications/ibutton/scene/ibutton_scene_emulate.cpp

@@ -83,7 +83,7 @@ bool iButtonSceneEmulate::on_event(iButtonApp* app, iButtonEvent* event) {
         app->notify_yellow_blink();
         app->notify_yellow_blink();
         consumed = true;
         consumed = true;
     } else if(event->type == iButtonEvent::Type::EventTypeTick) {
     } else if(event->type == iButtonEvent::Type::EventTypeTick) {
-        app->notify_red_blink();
+        app->notify_emulate();
         consumed = true;
         consumed = true;
     }
     }
 
 

+ 1 - 1
applications/ibutton/scene/ibutton_scene_read.cpp

@@ -54,7 +54,7 @@ bool iButtonSceneRead::on_event(iButtonApp* app, iButtonEvent* event) {
         }
         }
     } else if(event->type == iButtonEvent::Type::EventTypeTick) {
     } else if(event->type == iButtonEvent::Type::EventTypeTick) {
         consumed = true;
         consumed = true;
-        app->notify_red_blink();
+        app->notify_read();
     }
     }
 
 
     return consumed;
     return consumed;

+ 1 - 1
applications/ibutton/scene/ibutton_scene_write.cpp

@@ -95,7 +95,7 @@ bool iButtonSceneWrite::on_event(iButtonApp* app, iButtonEvent* event) {
         if(blink_yellow) {
         if(blink_yellow) {
             app->notify_yellow_blink();
             app->notify_yellow_blink();
         } else {
         } else {
-            app->notify_red_blink();
+            app->notify_emulate();
         }
         }
     }
     }
 
 

+ 5 - 39
applications/infrared/infrared_app.cpp

@@ -211,46 +211,12 @@ void InfraredApp::notify_success() {
     notification_message(notification, &sequence_success);
     notification_message(notification, &sequence_success);
 }
 }
 
 
-void InfraredApp::notify_red_blink() {
-    notification_message(notification, &sequence_blink_red_10);
+void InfraredApp::notify_blink_read() {
+    notification_message(notification, &sequence_blink_cyan_10);
 }
 }
 
 
-void InfraredApp::notify_click() {
-    static const NotificationSequence sequence = {
-        &message_click,
-        &message_delay_1,
-        &message_sound_off,
-        NULL,
-    };
-
-    notification_message_block(notification, &sequence);
-}
-
-void InfraredApp::notify_click_and_green_blink() {
-    static const NotificationSequence sequence = {
-        &message_click,
-        &message_delay_1,
-        &message_sound_off,
-        &message_green_255,
-        &message_delay_10,
-        &message_green_0,
-        &message_do_not_reset,
-        NULL,
-    };
-
-    notification_message_block(notification, &sequence);
-}
-
-void InfraredApp::notify_blink_green() {
-    static const NotificationSequence sequence = {
-        &message_green_255,
-        &message_delay_10,
-        &message_green_0,
-        &message_do_not_reset,
-        NULL,
-    };
-
-    notification_message(notification, &sequence);
+void InfraredApp::notify_blink_send() {
+    notification_message(notification, &sequence_blink_magenta_10);
 }
 }
 
 
 DialogsApp* InfraredApp::get_dialogs() {
 DialogsApp* InfraredApp::get_dialogs() {
@@ -279,5 +245,5 @@ void InfraredApp::set_received_signal(const InfraredAppSignal& signal) {
 
 
 void InfraredApp::signal_sent_callback(void* context) {
 void InfraredApp::signal_sent_callback(void* context) {
     InfraredApp* app = static_cast<InfraredApp*>(context);
     InfraredApp* app = static_cast<InfraredApp*>(context);
-    app->notify_blink_green();
+    app->notify_blink_send();
 }
 }

+ 3 - 7
applications/infrared/infrared_app.h

@@ -217,17 +217,13 @@ public:
     /** Play success notification */
     /** Play success notification */
     void notify_success();
     void notify_success();
     /** Play red blink notification */
     /** Play red blink notification */
-    void notify_red_blink();
+    void notify_blink_read();
     /** Light green */
     /** Light green */
     void notify_green_on();
     void notify_green_on();
     /** Disable green light */
     /** Disable green light */
     void notify_green_off();
     void notify_green_off();
-    /** Play click sound */
-    void notify_click();
-    /** Play click and green notification */
-    void notify_click_and_green_blink();
-    /** Blink green light */
-    void notify_blink_green();
+    /** Blink on send */
+    void notify_blink_send();
 
 
     /** Get Dialogs instance */
     /** Get Dialogs instance */
     DialogsApp* get_dialogs();
     DialogsApp* get_dialogs();

+ 1 - 1
applications/infrared/scene/infrared_app_scene_learn.cpp

@@ -51,7 +51,7 @@ bool InfraredAppSceneLearn::on_event(InfraredApp* app, InfraredAppEvent* event)
     switch(event->type) {
     switch(event->type) {
     case InfraredAppEvent::Type::Tick:
     case InfraredAppEvent::Type::Tick:
         consumed = true;
         consumed = true;
-        app->notify_red_blink();
+        app->notify_blink_read();
         break;
         break;
     case InfraredAppEvent::Type::InfraredMessageReceived:
     case InfraredAppEvent::Type::InfraredMessageReceived:
         app->notify_success();
         app->notify_success();

+ 0 - 1
applications/infrared/scene/infrared_app_scene_learn_success.cpp

@@ -95,7 +95,6 @@ bool InfraredAppSceneLearnSuccess::on_event(InfraredApp* app, InfraredAppEvent*
         case DialogExPressCenter:
         case DialogExPressCenter:
             if(!button_pressed) {
             if(!button_pressed) {
                 button_pressed = true;
                 button_pressed = true;
-                app->notify_click_and_green_blink();
 
 
                 auto signal = app->get_received_signal();
                 auto signal = app->get_received_signal();
                 if(signal.is_raw()) {
                 if(signal.is_raw()) {

+ 0 - 3
applications/infrared/scene/infrared_app_scene_remote.cpp

@@ -72,14 +72,12 @@ bool InfraredAppSceneRemote::on_event(InfraredApp* app, InfraredAppEvent* event)
         switch(event->payload.menu_index) {
         switch(event->payload.menu_index) {
         case ButtonIndexPlus:
         case ButtonIndexPlus:
             furi_assert(event->type == InfraredAppEvent::Type::MenuSelected);
             furi_assert(event->type == InfraredAppEvent::Type::MenuSelected);
-            app->notify_click();
             buttonmenu_item_selected = event->payload.menu_index;
             buttonmenu_item_selected = event->payload.menu_index;
             app->set_learn_new_remote(false);
             app->set_learn_new_remote(false);
             app->switch_to_next_scene(InfraredApp::Scene::Learn);
             app->switch_to_next_scene(InfraredApp::Scene::Learn);
             break;
             break;
         case ButtonIndexEdit:
         case ButtonIndexEdit:
             furi_assert(event->type == InfraredAppEvent::Type::MenuSelected);
             furi_assert(event->type == InfraredAppEvent::Type::MenuSelected);
-            app->notify_click();
             buttonmenu_item_selected = event->payload.menu_index;
             buttonmenu_item_selected = event->payload.menu_index;
             app->switch_to_next_scene(InfraredApp::Scene::Edit);
             app->switch_to_next_scene(InfraredApp::Scene::Edit);
             break;
             break;
@@ -89,7 +87,6 @@ bool InfraredAppSceneRemote::on_event(InfraredApp* app, InfraredAppEvent* event)
 
 
             if(pressed && !button_pressed) {
             if(pressed && !button_pressed) {
                 button_pressed = true;
                 button_pressed = true;
-                app->notify_click_and_green_blink();
 
 
                 auto button_signal =
                 auto button_signal =
                     app->get_remote_manager()->get_button_data(event->payload.menu_index);
                     app->get_remote_manager()->get_button_data(event->payload.menu_index);

+ 2 - 0
applications/infrared/scene/infrared_app_scene_universal_common.cpp

@@ -56,6 +56,7 @@ bool InfraredAppSceneUniversalCommon::on_event(InfraredApp* app, InfraredAppEven
     if(brute_force_started) {
     if(brute_force_started) {
         if(event->type == InfraredAppEvent::Type::Tick) {
         if(event->type == InfraredAppEvent::Type::Tick) {
             auto view_manager = app->get_view_manager();
             auto view_manager = app->get_view_manager();
+            app->notify_blink_send();
             InfraredAppEvent tick_event = {.type = InfraredAppEvent::Type::Tick};
             InfraredAppEvent tick_event = {.type = InfraredAppEvent::Type::Tick};
             view_manager->send_event(&tick_event);
             view_manager->send_event(&tick_event);
             bool result = brute_force.send_next_bruteforce();
             bool result = brute_force.send_next_bruteforce();
@@ -81,6 +82,7 @@ bool InfraredAppSceneUniversalCommon::on_event(InfraredApp* app, InfraredAppEven
                 DOLPHIN_DEED(DolphinDeedIrBruteForce);
                 DOLPHIN_DEED(DolphinDeedIrBruteForce);
                 brute_force_started = true;
                 brute_force_started = true;
                 show_popup(app, record_amount);
                 show_popup(app, record_amount);
+                app->notify_blink_send();
             } else {
             } else {
                 app->switch_to_previous_scene();
                 app->switch_to_previous_scene();
             }
             }

+ 1 - 1
applications/lfrfid/scene/lfrfid_app_scene_emulate.cpp

@@ -29,7 +29,7 @@ bool LfRfidAppSceneEmulate::on_event(LfRfidApp* app, LfRfidApp::Event* event) {
     bool consumed = false;
     bool consumed = false;
 
 
     if(event->type == LfRfidApp::EventType::Tick) {
     if(event->type == LfRfidApp::EventType::Tick) {
-        notification_message(app->notification, &sequence_blink_cyan_10);
+        notification_message(app->notification, &sequence_blink_magenta_10);
     }
     }
 
 
     return consumed;
     return consumed;

+ 2 - 2
applications/lfrfid/scene/lfrfid_app_scene_read.cpp

@@ -24,9 +24,9 @@ bool LfRfidAppSceneRead::on_event(LfRfidApp* app, LfRfidApp::Event* event) {
             if(app->worker.any_read()) {
             if(app->worker.any_read()) {
                 notification_message(app->notification, &sequence_blink_green_10);
                 notification_message(app->notification, &sequence_blink_green_10);
             } else if(app->worker.detect()) {
             } else if(app->worker.detect()) {
-                notification_message(app->notification, &sequence_blink_blue_10);
+                notification_message(app->notification, &sequence_blink_cyan_10);
             } else {
             } else {
-                notification_message(app->notification, &sequence_blink_red_10);
+                notification_message(app->notification, &sequence_blink_cyan_10);
             }
             }
         }
         }
     }
     }

+ 2 - 2
applications/lfrfid/scene/lfrfid_app_scene_write.cpp

@@ -32,7 +32,7 @@ bool LfRfidAppSceneWrite::on_event(LfRfidApp* app, LfRfidApp::Event* event) {
 
 
         switch(result) {
         switch(result) {
         case RfidWorker::WriteResult::Nothing:
         case RfidWorker::WriteResult::Nothing:
-            notification_message(app->notification, &sequence_blink_yellow_10);
+            notification_message(app->notification, &sequence_blink_magenta_10);
             break;
             break;
         case RfidWorker::WriteResult::Ok:
         case RfidWorker::WriteResult::Ok:
             notification_message(app->notification, &sequence_success);
             notification_message(app->notification, &sequence_success);
@@ -51,7 +51,7 @@ bool LfRfidAppSceneWrite::on_event(LfRfidApp* app, LfRfidApp::Event* event) {
                     AlignTop);
                     AlignTop);
                 card_not_supported = true;
                 card_not_supported = true;
             }
             }
-            notification_message(app->notification, &sequence_blink_red_10);
+            notification_message(app->notification, &sequence_blink_yellow_10);
             break;
             break;
         }
         }
     }
     }

+ 7 - 0
applications/notification/notification_messages.c

@@ -309,6 +309,13 @@ const NotificationSequence sequence_blink_cyan_10 = {
     NULL,
     NULL,
 };
 };
 
 
+const NotificationSequence sequence_blink_magenta_10 = {
+    &message_red_255,
+    &message_blue_255,
+    &message_delay_10,
+    NULL,
+};
+
 const NotificationSequence sequence_blink_red_100 = {
 const NotificationSequence sequence_blink_red_100 = {
     &message_red_255,
     &message_red_255,
     &message_delay_100,
     &message_delay_100,

+ 1 - 0
applications/notification/notification_messages.h

@@ -100,6 +100,7 @@ extern const NotificationSequence sequence_blink_red_10;
 extern const NotificationSequence sequence_blink_green_10;
 extern const NotificationSequence sequence_blink_green_10;
 extern const NotificationSequence sequence_blink_yellow_10;
 extern const NotificationSequence sequence_blink_yellow_10;
 extern const NotificationSequence sequence_blink_cyan_10;
 extern const NotificationSequence sequence_blink_cyan_10;
+extern const NotificationSequence sequence_blink_magenta_10;
 
 
 extern const NotificationSequence sequence_blink_red_100;
 extern const NotificationSequence sequence_blink_red_100;
 extern const NotificationSequence sequence_blink_green_100;
 extern const NotificationSequence sequence_blink_green_100;

+ 2 - 1
applications/subghz/helpers/subghz_custom_event.h

@@ -19,6 +19,8 @@ typedef enum {
     SubGhzCustomEventSceneShowErrorOk,
     SubGhzCustomEventSceneShowErrorOk,
     SubGhzCustomEventSceneShowErrorSub,
     SubGhzCustomEventSceneShowErrorSub,
     SubGhzCustomEventSceneShowOnlyRX,
     SubGhzCustomEventSceneShowOnlyRX,
+    SubGhzCustomEventSceneAnalyzerLock,
+    SubGhzCustomEventSceneAnalyzerUnlock,
 
 
     SubGhzCustomEventSceneExit,
     SubGhzCustomEventSceneExit,
     SubGhzCustomEventSceneStay,
     SubGhzCustomEventSceneStay,
@@ -35,7 +37,6 @@ typedef enum {
     SubGhzCustomEventViewReadRAWSendStart,
     SubGhzCustomEventViewReadRAWSendStart,
     SubGhzCustomEventViewReadRAWSendStop,
     SubGhzCustomEventViewReadRAWSendStop,
     SubGhzCustomEventViewReadRAWSave,
     SubGhzCustomEventViewReadRAWSave,
-    SubGhzCustomEventViewReadRAWVibro,
     SubGhzCustomEventViewReadRAWTXRXStop,
     SubGhzCustomEventViewReadRAWTXRXStop,
     SubGhzCustomEventViewReadRAWMore,
     SubGhzCustomEventViewReadRAWMore,
 
 

+ 12 - 2
applications/subghz/scenes/subghz_scene_frequency_analyzer.c

@@ -17,10 +17,20 @@ void subghz_scene_frequency_analyzer_on_enter(void* context) {
 }
 }
 
 
 bool subghz_scene_frequency_analyzer_on_event(void* context, SceneManagerEvent event) {
 bool subghz_scene_frequency_analyzer_on_event(void* context, SceneManagerEvent event) {
-    //SubGhz* subghz = context;
+    SubGhz* subghz = context;
+    if(event.type == SceneManagerEventTypeCustom) {
+        if(event.event == SubGhzCustomEventSceneAnalyzerLock) {
+            notification_message(subghz->notifications, &sequence_set_green_255);
+            return true;
+        } else if(event.event == SubGhzCustomEventSceneAnalyzerUnlock) {
+            notification_message(subghz->notifications, &sequence_reset_rgb);
+            return true;
+        }
+    }
     return false;
     return false;
 }
 }
 
 
 void subghz_scene_frequency_analyzer_on_exit(void* context) {
 void subghz_scene_frequency_analyzer_on_exit(void* context) {
-    // SubGhz* subghz = context;
+    SubGhz* subghz = context;
+    notification_message(subghz->notifications, &sequence_reset_rgb);
 }
 }

+ 18 - 11
applications/subghz/scenes/subghz_scene_read_raw.c

@@ -168,11 +168,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
 
 
         case SubGhzCustomEventViewReadRAWErase:
         case SubGhzCustomEventViewReadRAWErase:
             subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
             subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
-            return true;
-            break;
-
-        case SubGhzCustomEventViewReadRAWVibro:
-            notification_message(subghz->notifications, &sequence_single_vibro);
+            notification_message(subghz->notifications, &sequence_reset_rgb);
             return true;
             return true;
             break;
             break;
 
 
@@ -209,7 +205,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
                             (SubGhzProtocolEncoderRAW*)subghz->txrx->transmitter->protocol_instance,
                             (SubGhzProtocolEncoderRAW*)subghz->txrx->transmitter->protocol_instance,
                             subghz_scene_read_raw_callback_end_tx,
                             subghz_scene_read_raw_callback_end_tx,
                             subghz);
                             subghz);
-                        subghz->state_notifications = SubGhzNotificationStateTX;
+                        subghz->state_notifications = SubGhzNotificationStateTx;
                     }
                     }
                 }
                 }
             }
             }
@@ -231,6 +227,10 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
                 subghz_rx_end(subghz);
                 subghz_rx_end(subghz);
                 subghz_sleep(subghz);
                 subghz_sleep(subghz);
             };
             };
+
+            size_t spl_count = subghz_protocol_raw_get_sample_write(
+                (SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result);
+
             subghz_protocol_raw_save_to_file_stop(
             subghz_protocol_raw_save_to_file_stop(
                 (SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result);
                 (SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result);
 
 
@@ -241,6 +241,12 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
             subghz_protocol_raw_gen_fff_data(subghz->txrx->fff_data, string_get_cstr(temp_str));
             subghz_protocol_raw_gen_fff_data(subghz->txrx->fff_data, string_get_cstr(temp_str));
             string_clear(temp_str);
             string_clear(temp_str);
 
 
+            if(spl_count > 0) {
+                notification_message(subghz->notifications, &sequence_set_green_255);
+            } else {
+                notification_message(subghz->notifications, &sequence_reset_rgb);
+            }
+
             subghz->state_notifications = SubGhzNotificationStateIDLE;
             subghz->state_notifications = SubGhzNotificationStateIDLE;
             subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey;
             subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey;
 
 
@@ -263,7 +269,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
                         subghz_begin(subghz, subghz->txrx->preset);
                         subghz_begin(subghz, subghz->txrx->preset);
                         subghz_rx(subghz, subghz->txrx->frequency);
                         subghz_rx(subghz, subghz->txrx->frequency);
                     }
                     }
-                    subghz->state_notifications = SubGhzNotificationStateRX;
+                    subghz->state_notifications = SubGhzNotificationStateRx;
                     subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey;
                     subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey;
                 } else {
                 } else {
                     string_set(subghz->error_str, "Function requires\nan SD card.");
                     string_set(subghz->error_str, "Function requires\nan SD card.");
@@ -288,16 +294,16 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
         }
         }
     } else if(event.type == SceneManagerEventTypeTick) {
     } else if(event.type == SceneManagerEventTypeTick) {
         switch(subghz->state_notifications) {
         switch(subghz->state_notifications) {
-        case SubGhzNotificationStateRX:
-            notification_message(subghz->notifications, &sequence_blink_blue_10);
+        case SubGhzNotificationStateRx:
+            notification_message(subghz->notifications, &sequence_blink_cyan_10);
             subghz_read_raw_update_sample_write(
             subghz_read_raw_update_sample_write(
                 subghz->subghz_read_raw,
                 subghz->subghz_read_raw,
                 subghz_protocol_raw_get_sample_write(
                 subghz_protocol_raw_get_sample_write(
                     (SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result));
                     (SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result));
             subghz_read_raw_add_data_rssi(subghz->subghz_read_raw, furi_hal_subghz_get_rssi());
             subghz_read_raw_add_data_rssi(subghz->subghz_read_raw, furi_hal_subghz_get_rssi());
             break;
             break;
-        case SubGhzNotificationStateTX:
-            notification_message(subghz->notifications, &sequence_blink_green_10);
+        case SubGhzNotificationStateTx:
+            notification_message(subghz->notifications, &sequence_blink_magenta_10);
             subghz_read_raw_update_sin(subghz->subghz_read_raw);
             subghz_read_raw_update_sin(subghz->subghz_read_raw);
             break;
             break;
         default:
         default:
@@ -316,6 +322,7 @@ void subghz_scene_read_raw_on_exit(void* context) {
         subghz_sleep(subghz);
         subghz_sleep(subghz);
     };
     };
     subghz->state_notifications = SubGhzNotificationStateIDLE;
     subghz->state_notifications = SubGhzNotificationStateIDLE;
+    notification_message(subghz->notifications, &sequence_reset_rgb);
 
 
     //filter restoration
     //filter restoration
     subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable);
     subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable);

+ 22 - 3
applications/subghz/scenes/subghz_scene_receiver.c

@@ -1,6 +1,19 @@
 #include "../subghz_i.h"
 #include "../subghz_i.h"
 #include "../views/receiver.h"
 #include "../views/receiver.h"
 
 
+static const NotificationSequence subghs_sequence_rx = {
+    &message_green_255,
+
+    &message_vibro_on,
+    &message_note_c6,
+    &message_delay_50,
+    &message_sound_off,
+    &message_vibro_off,
+
+    &message_delay_50,
+    NULL,
+};
+
 static void subghz_scene_receiver_update_statusbar(void* context) {
 static void subghz_scene_receiver_update_statusbar(void* context) {
     SubGhz* subghz = context;
     SubGhz* subghz = context;
     string_t history_stat_str;
     string_t history_stat_str;
@@ -50,6 +63,8 @@ static void subghz_scene_add_to_history_callback(
         subghz_receiver_reset(receiver);
         subghz_receiver_reset(receiver);
         string_reset(str_buff);
         string_reset(str_buff);
 
 
+        subghz->state_notifications = SubGhzNotificationStateRxDone;
+
         subghz_history_get_text_item_menu(
         subghz_history_get_text_item_menu(
             subghz->txrx->history, str_buff, subghz_history_get_item(subghz->txrx->history) - 1);
             subghz->txrx->history, str_buff, subghz_history_get_item(subghz->txrx->history) - 1);
         subghz_view_receiver_add_item_to_menu(
         subghz_view_receiver_add_item_to_menu(
@@ -95,7 +110,7 @@ void subghz_scene_receiver_on_enter(void* context) {
     subghz_receiver_set_rx_callback(
     subghz_receiver_set_rx_callback(
         subghz->txrx->receiver, subghz_scene_add_to_history_callback, subghz);
         subghz->txrx->receiver, subghz_scene_add_to_history_callback, subghz);
 
 
-    subghz->state_notifications = SubGhzNotificationStateRX;
+    subghz->state_notifications = SubGhzNotificationStateRx;
     if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) {
     if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) {
         subghz_rx_end(subghz);
         subghz_rx_end(subghz);
     };
     };
@@ -161,8 +176,12 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) {
         }
         }
 
 
         switch(subghz->state_notifications) {
         switch(subghz->state_notifications) {
-        case SubGhzNotificationStateRX:
-            notification_message(subghz->notifications, &sequence_blink_blue_10);
+        case SubGhzNotificationStateRx:
+            notification_message(subghz->notifications, &sequence_blink_cyan_10);
+            break;
+        case SubGhzNotificationStateRxDone:
+            notification_message(subghz->notifications, &subghs_sequence_rx);
+            subghz->state_notifications = SubGhzNotificationStateRx;
             break;
             break;
         default:
         default:
             break;
             break;

+ 10 - 6
applications/subghz/scenes/subghz_scene_receiver_info.c

@@ -126,7 +126,7 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event)
                            subghz->txrx->history, subghz->txrx->idx_menu_chosen))) {
                            subghz->txrx->history, subghz->txrx->idx_menu_chosen))) {
                     scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx);
                     scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx);
                 } else {
                 } else {
-                    subghz->state_notifications = SubGhzNotificationStateTX;
+                    subghz->state_notifications = SubGhzNotificationStateTx;
                 }
                 }
             }
             }
             return true;
             return true;
@@ -143,7 +143,7 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event)
             if(subghz->txrx->hopper_state == SubGhzHopperStatePause) {
             if(subghz->txrx->hopper_state == SubGhzHopperStatePause) {
                 subghz->txrx->hopper_state = SubGhzHopperStateRunnig;
                 subghz->txrx->hopper_state = SubGhzHopperStateRunnig;
             }
             }
-            subghz->state_notifications = SubGhzNotificationStateRX;
+            subghz->state_notifications = SubGhzNotificationStateRx;
             return true;
             return true;
         } else if(event.event == SubGhzCustomEventSceneReceiverInfoSave) {
         } else if(event.event == SubGhzCustomEventSceneReceiverInfoSave) {
             //CC1101 Stop RX -> Save
             //CC1101 Stop RX -> Save
@@ -171,11 +171,15 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event)
             subghz_hopper_update(subghz);
             subghz_hopper_update(subghz);
         }
         }
         switch(subghz->state_notifications) {
         switch(subghz->state_notifications) {
-        case SubGhzNotificationStateTX:
-            notification_message(subghz->notifications, &sequence_blink_red_10);
+        case SubGhzNotificationStateTx:
+            notification_message(subghz->notifications, &sequence_blink_magenta_10);
             break;
             break;
-        case SubGhzNotificationStateRX:
-            notification_message(subghz->notifications, &sequence_blink_blue_10);
+        case SubGhzNotificationStateRx:
+            notification_message(subghz->notifications, &sequence_blink_cyan_10);
+            break;
+        case SubGhzNotificationStateRxDone:
+            notification_message(subghz->notifications, &sequence_blink_green_100);
+            subghz->state_notifications = SubGhzNotificationStateRx;
             break;
             break;
         default:
         default:
             break;
             break;

+ 10 - 0
applications/subghz/scenes/subghz_scene_show_error.c

@@ -1,6 +1,13 @@
 #include "../subghz_i.h"
 #include "../subghz_i.h"
 #include "../helpers/subghz_custom_event.h"
 #include "../helpers/subghz_custom_event.h"
 
 
+static const NotificationSequence subghs_sequence_sd_error = {
+    &message_red_255,
+    &message_green_255,
+    &message_do_not_reset,
+    NULL,
+};
+
 void subghz_scene_show_error_callback(GuiButtonType result, InputType type, void* context) {
 void subghz_scene_show_error_callback(GuiButtonType result, InputType type, void* context) {
     furi_assert(context);
     furi_assert(context);
     SubGhz* subghz = context;
     SubGhz* subghz = context;
@@ -31,6 +38,8 @@ void subghz_scene_show_error_on_enter(void* context) {
        SubGhzCustomEventManagerSet) {
        SubGhzCustomEventManagerSet) {
         widget_add_button_element(
         widget_add_button_element(
             subghz->widget, GuiButtonTypeRight, "Ok", subghz_scene_show_error_callback, subghz);
             subghz->widget, GuiButtonTypeRight, "Ok", subghz_scene_show_error_callback, subghz);
+    } else {
+        notification_message(subghz->notifications, &subghs_sequence_sd_error);
     }
     }
 
 
     widget_add_button_element(
     widget_add_button_element(
@@ -81,4 +90,5 @@ void subghz_scene_show_error_on_exit(void* context) {
         subghz->scene_manager, SubGhzSceneShowError, SubGhzCustomEventManagerNoSet);
         subghz->scene_manager, SubGhzSceneShowError, SubGhzCustomEventManagerNoSet);
     widget_reset(subghz->widget);
     widget_reset(subghz->widget);
     string_reset(subghz->error_str);
     string_reset(subghz->error_str);
+    notification_message(subghz->notifications, &sequence_reset_rgb);
 }
 }

+ 4 - 0
applications/subghz/scenes/subghz_scene_show_error_sub.c

@@ -18,6 +18,8 @@ void subghz_scene_show_error_sub_on_enter(void* context) {
     popup_set_callback(popup, subghz_scene_show_error_sub_popup_callback);
     popup_set_callback(popup, subghz_scene_show_error_sub_popup_callback);
     popup_enable_timeout(popup);
     popup_enable_timeout(popup);
     view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdPopup);
     view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdPopup);
+
+    notification_message(subghz->notifications, &sequence_set_red_255);
 }
 }
 
 
 bool subghz_scene_show_error_sub_on_event(void* context, SceneManagerEvent event) {
 bool subghz_scene_show_error_sub_on_event(void* context, SceneManagerEvent event) {
@@ -45,4 +47,6 @@ void subghz_scene_show_error_sub_on_exit(void* context) {
     popup_set_timeout(popup, 0);
     popup_set_timeout(popup, 0);
     popup_disable_timeout(popup);
     popup_disable_timeout(popup);
     string_reset(subghz->error_str);
     string_reset(subghz->error_str);
+
+    notification_message(subghz->notifications, &sequence_reset_rgb);
 }
 }

+ 3 - 3
applications/subghz/scenes/subghz_scene_transmitter.c

@@ -76,7 +76,7 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) {
                 if(!subghz_tx_start(subghz, subghz->txrx->fff_data)) {
                 if(!subghz_tx_start(subghz, subghz->txrx->fff_data)) {
                     scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx);
                     scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx);
                 } else {
                 } else {
-                    subghz->state_notifications = SubGhzNotificationStateTX;
+                    subghz->state_notifications = SubGhzNotificationStateTx;
                     subghz_scene_transmitter_update_data_show(subghz);
                     subghz_scene_transmitter_update_data_show(subghz);
                 }
                 }
             }
             }
@@ -98,8 +98,8 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) {
             scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub);
             scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub);
         }
         }
     } else if(event.type == SceneManagerEventTypeTick) {
     } else if(event.type == SceneManagerEventTypeTick) {
-        if(subghz->state_notifications == SubGhzNotificationStateTX) {
-            notification_message(subghz->notifications, &sequence_blink_red_10);
+        if(subghz->state_notifications == SubGhzNotificationStateTx) {
+            notification_message(subghz->notifications, &sequence_blink_magenta_10);
         }
         }
         return true;
         return true;
     }
     }

+ 3 - 2
applications/subghz/subghz_i.h

@@ -41,8 +41,9 @@
 typedef enum {
 typedef enum {
     SubGhzNotificationStateStarting,
     SubGhzNotificationStateStarting,
     SubGhzNotificationStateIDLE,
     SubGhzNotificationStateIDLE,
-    SubGhzNotificationStateTX,
-    SubGhzNotificationStateRX,
+    SubGhzNotificationStateTx,
+    SubGhzNotificationStateRx,
+    SubGhzNotificationStateRxDone,
 } SubGhzNotificationState;
 } SubGhzNotificationState;
 
 
 /** SubGhzTxRx state */
 /** SubGhzTxRx state */

+ 12 - 0
applications/subghz/views/subghz_frequency_analyzer.c

@@ -19,6 +19,7 @@ struct SubGhzFrequencyAnalyzer {
     SubGhzFrequencyAnalyzerWorker* worker;
     SubGhzFrequencyAnalyzerWorker* worker;
     SubGhzFrequencyAnalyzerCallback callback;
     SubGhzFrequencyAnalyzerCallback callback;
     void* context;
     void* context;
+    bool locked;
 };
 };
 
 
 typedef struct {
 typedef struct {
@@ -86,6 +87,17 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) {
 
 
 void subghz_frequency_analyzer_pair_callback(void* context, uint32_t frequency, float rssi) {
 void subghz_frequency_analyzer_pair_callback(void* context, uint32_t frequency, float rssi) {
     SubGhzFrequencyAnalyzer* instance = context;
     SubGhzFrequencyAnalyzer* instance = context;
+    if((rssi == 0.f) && (instance->locked)) {
+        if(instance->callback) {
+            instance->callback(SubGhzCustomEventSceneAnalyzerUnlock, instance->context);
+        }
+    } else if((rssi != 0.f) && (!instance->locked)) {
+        if(instance->callback) {
+            instance->callback(SubGhzCustomEventSceneAnalyzerLock, instance->context);
+        }
+    }
+
+    instance->locked = (rssi != 0.f);
     with_view_model(
     with_view_model(
         instance->view, (SubGhzFrequencyAnalyzerModel * model) {
         instance->view, (SubGhzFrequencyAnalyzerModel * model) {
             model->rssi = rssi;
             model->rssi = rssi;

+ 0 - 2
applications/subghz/views/subghz_read_raw.c

@@ -293,7 +293,6 @@ bool subghz_read_raw_input(InputEvent* event, void* context) {
                 case SubGhzReadRAWStatusIDLE:
                 case SubGhzReadRAWStatusIDLE:
                     // Start TX
                     // Start TX
                     instance->callback(SubGhzCustomEventViewReadRAWSendStart, instance->context);
                     instance->callback(SubGhzCustomEventViewReadRAWSendStart, instance->context);
-                    instance->callback(SubGhzCustomEventViewReadRAWVibro, instance->context);
                     model->satus = SubGhzReadRAWStatusTXRepeat;
                     model->satus = SubGhzReadRAWStatusTXRepeat;
                     ret = true;
                     ret = true;
                     break;
                     break;
@@ -304,7 +303,6 @@ bool subghz_read_raw_input(InputEvent* event, void* context) {
                 case SubGhzReadRAWStatusLoadKeyIDLE:
                 case SubGhzReadRAWStatusLoadKeyIDLE:
                     // Start Load Key TX
                     // Start Load Key TX
                     instance->callback(SubGhzCustomEventViewReadRAWSendStart, instance->context);
                     instance->callback(SubGhzCustomEventViewReadRAWSendStart, instance->context);
-                    instance->callback(SubGhzCustomEventViewReadRAWVibro, instance->context);
                     model->satus = SubGhzReadRAWStatusLoadKeyTXRepeat;
                     model->satus = SubGhzReadRAWStatusLoadKeyTXRepeat;
                     ret = true;
                     ret = true;
                     break;
                     break;

+ 6 - 2
applications/u2f/scenes/u2f_scene_main.c

@@ -62,15 +62,17 @@ bool u2f_scene_main_on_event(void* context, SceneManagerEvent event) {
                 notification_message(app->notifications, &sequence_display_on);
                 notification_message(app->notifications, &sequence_display_on);
                 notification_message(app->notifications, &sequence_single_vibro);
                 notification_message(app->notifications, &sequence_single_vibro);
             }
             }
-            notification_message(app->notifications, &sequence_blink_blue_10);
+            notification_message(app->notifications, &sequence_blink_magenta_10);
         } else if(event.event == U2fCustomEventWink) {
         } else if(event.event == U2fCustomEventWink) {
-            notification_message(app->notifications, &sequence_blink_green_10);
+            notification_message(app->notifications, &sequence_blink_magenta_10);
         } else if(event.event == U2fCustomEventAuthSuccess) {
         } else if(event.event == U2fCustomEventAuthSuccess) {
+            notification_message_block(app->notifications, &sequence_set_green_255);
             DOLPHIN_DEED(DolphinDeedU2fAuthorized);
             DOLPHIN_DEED(DolphinDeedU2fAuthorized);
             osTimerStart(app->timer, U2F_SUCCESS_TIMEOUT);
             osTimerStart(app->timer, U2F_SUCCESS_TIMEOUT);
             app->event_cur = U2fCustomEventNone;
             app->event_cur = U2fCustomEventNone;
             u2f_view_set_state(app->u2f_view, U2fMsgSuccess);
             u2f_view_set_state(app->u2f_view, U2fMsgSuccess);
         } else if(event.event == U2fCustomEventTimeout) {
         } else if(event.event == U2fCustomEventTimeout) {
+            notification_message_block(app->notifications, &sequence_reset_rgb);
             app->event_cur = U2fCustomEventNone;
             app->event_cur = U2fCustomEventNone;
             u2f_view_set_state(app->u2f_view, U2fMsgIdle);
             u2f_view_set_state(app->u2f_view, U2fMsgIdle);
         } else if(event.event == U2fCustomEventConfirm) {
         } else if(event.event == U2fCustomEventConfirm) {
@@ -78,6 +80,7 @@ bool u2f_scene_main_on_event(void* context, SceneManagerEvent event) {
                 u2f_confirm_user_present(app->u2f_instance);
                 u2f_confirm_user_present(app->u2f_instance);
             }
             }
         } else if(event.event == U2fCustomEventDataError) {
         } else if(event.event == U2fCustomEventDataError) {
+            notification_message(app->notifications, &sequence_set_red_255);
             osTimerStop(app->timer);
             osTimerStop(app->timer);
             u2f_view_set_state(app->u2f_view, U2fMsgError);
             u2f_view_set_state(app->u2f_view, U2fMsgError);
         }
         }
@@ -108,6 +111,7 @@ void u2f_scene_main_on_enter(void* context) {
 
 
 void u2f_scene_main_on_exit(void* context) {
 void u2f_scene_main_on_exit(void* context) {
     U2fApp* app = context;
     U2fApp* app = context;
+    notification_message_block(app->notifications, &sequence_reset_rgb);
     osTimerStop(app->timer);
     osTimerStop(app->timer);
     osTimerDelete(app->timer);
     osTimerDelete(app->timer);
     if(app->u2f_ready == true) {
     if(app->u2f_ready == true) {