timed-remote

Flipper Zero app for sending delayed IR commands
git clone git://src.adamsgaard.dk/timed-remote # fast
git clone https://src.adamsgaard.dk/timed-remote.git # slow
Log | Files | Refs | README | LICENSE Back to index

scene_timer_running.c (3424B)


      1 #include <stdio.h>
      2 
      3 #include "../helpers/ir_helper.h"
      4 #include "../helpers/time_helper.h"
      5 #include "../timed_remote.h"
      6 #include "timed_remote_scene.h"
      7 
      8 static uint32_t	countdown_seconds(const TimedRemoteApp *);
      9 static void	render_timer(TimedRemoteApp *);
     10 
     11 #define REPEAT_UNLIMITED 255U
     12 
     13 static void
     14 on_timer_tick(void *context)
     15 {
     16 	TimedRemoteApp *app;
     17 
     18 	app = context;
     19 	view_dispatcher_send_custom_event(app->vd, EVENT_TIMER_TICK);
     20 }
     21 
     22 static uint32_t
     23 countdown_seconds(const TimedRemoteApp *app)
     24 {
     25 	return time_hms_sec(app->h, app->m, app->s);
     26 }
     27 
     28 static void
     29 render_timer(TimedRemoteApp *app)
     30 {
     31 	char timer[16];
     32 	uint8_t h;
     33 	uint8_t m;
     34 	uint8_t s;
     35 
     36 	time_sec_hms(app->left, &h, &m, &s);
     37 	snprintf(timer, sizeof(timer), "%02d:%02d:%02d", h, m, s);
     38 
     39 	widget_reset(app->widget);
     40 	widget_add_string_element(
     41 	    app->widget,
     42 	    64,
     43 	    5,
     44 	    AlignCenter,
     45 	    AlignTop,
     46 	    FontSecondary,
     47 	    app->sig);
     48 	widget_add_string_element(
     49 	    app->widget,
     50 	    64,
     51 	    25,
     52 	    AlignCenter,
     53 	    AlignTop,
     54 	    FontBigNumbers,
     55 	    timer);
     56 
     57 	if (app->repeat > 0 && app->repeat < REPEAT_UNLIMITED) {
     58 		char repeat[24];
     59 
     60 		snprintf(
     61 		    repeat,
     62 		    sizeof(repeat),
     63 		    "Repeat: %d/%d",
     64 		    app->repeat - app->repeat_left + 1,
     65 		    app->repeat);
     66 		widget_add_string_element(
     67 		    app->widget,
     68 		    64,
     69 		    52,
     70 		    AlignCenter,
     71 		    AlignTop,
     72 		    FontSecondary,
     73 		    repeat);
     74 	} else if (app->repeat == REPEAT_UNLIMITED) {
     75 		widget_add_string_element(
     76 		    app->widget,
     77 		    64,
     78 		    52,
     79 		    AlignCenter,
     80 		    AlignTop,
     81 		    FontSecondary,
     82 		    "Repeat: Unlimited");
     83 	}
     84 }
     85 
     86 void
     87 scene_run_enter(void *context)
     88 {
     89 	TimedRemoteApp *app;
     90 
     91 	app = context;
     92 	if (app->mode == MODE_COUNTDOWN) {
     93 		app->left = countdown_seconds(app);
     94 	} else {
     95 		app->left = time_until(app->h, app->m, app->s);
     96 		if (app->left == 0) {
     97 			view_dispatcher_send_custom_event(app->vd, EVENT_FIRE_SIGNAL);
     98 			return;
     99 		}
    100 	}
    101 
    102 	if (app->repeat == 0)
    103 		app->repeat_left = 1;
    104 
    105 	render_timer(app);
    106 	view_dispatcher_switch_to_view(app->vd, VIEW_RUN);
    107 
    108 	app->timer = furi_timer_alloc(on_timer_tick, FuriTimerTypePeriodic, app);
    109 	if (app->timer == NULL)
    110 		return;
    111 
    112 	furi_timer_start(app->timer, furi_kernel_get_tick_frequency());
    113 }
    114 
    115 bool
    116 scene_run_event(void *context, SceneManagerEvent event)
    117 {
    118 	TimedRemoteApp *app;
    119 
    120 	app = context;
    121 	if (event.type == SceneManagerEventTypeBack) {
    122 		scene_manager_search_and_switch_to_previous_scene(
    123 		    app->sm,
    124 		    SCENE_BROWSE);
    125 		return true;
    126 	}
    127 	if (event.type != SceneManagerEventTypeCustom)
    128 		return false;
    129 
    130 	if (event.event == EVENT_TIMER_TICK) {
    131 		if (app->left > 0) {
    132 			app->left--;
    133 			render_timer(app);
    134 		}
    135 		if (app->left == 0)
    136 			view_dispatcher_send_custom_event(app->vd, EVENT_FIRE_SIGNAL);
    137 		return true;
    138 	}
    139 	if (event.event != EVENT_FIRE_SIGNAL)
    140 		return false;
    141 
    142 	if (app->ir != NULL)
    143 		ir_tx(app->ir);
    144 
    145 	if (app->repeat == REPEAT_UNLIMITED) {
    146 		app->left = countdown_seconds(app);
    147 		render_timer(app);
    148 		return true;
    149 	}
    150 
    151 	if (app->repeat_left > 0)
    152 		app->repeat_left--;
    153 
    154 	if (app->repeat != 0 && app->repeat_left > 0) {
    155 		app->left = countdown_seconds(app);
    156 		render_timer(app);
    157 		return true;
    158 	}
    159 
    160 	scene_manager_next_scene(app->sm, SCENE_DONE);
    161 	return true;
    162 }
    163 
    164 void
    165 scene_run_exit(void *context)
    166 {
    167 	TimedRemoteApp *app;
    168 
    169 	app = context;
    170 	if (app->timer != NULL) {
    171 		furi_timer_stop(app->timer);
    172 		furi_timer_free(app->timer);
    173 		app->timer = NULL;
    174 	}
    175 	widget_reset(app->widget);
    176 }