@ -28,12 +28,54 @@ static void draw_common_overlay();
//stratch string buffer
char sbuf [ 100 ] ;
void gui_read_moisture ( ) {
void gui_read_moisture ( )
{
s_app . moisture_pt = moisture_convert ( s_app . moisture_raw = moisture_read ( ) ) ;
}
static void read_time_and_moisture ( ) {
/**
* Get days remaining to next watering day
*
* @ return
*/
uint8_t days_to_next_watering ( )
{
if ( app_config . scheduler_dry_days = = 0 ) {
return 0 ;
}
uint8_t wd = s_app . rtc_time . weekday ;
uint8_t last_wd = s_app . last_watering_day_wd ;
uint8_t normalized_next = ( last_wd + 1 + app_config . scheduler_dry_days ) % 7 ;
if ( wd > normalized_next ) {
normalized_next + = 7 ;
}
return normalized_next - wd ;
}
static void read_time_and_moisture ( )
{
uint8_t prev_wd = s_app . rtc_time . weekday ;
rtc_get_time ( & s_app . rtc_time ) ; // now is a good time to update timestamp - we could just increment it though
// decide if today is a watering day
if ( app_config . scheduler_dry_days = = 0 ) {
s_app . today_is_watering_day = true ;
s_app . last_watering_day_wd = s_app . rtc_time . weekday ;
} else {
uint8_t cur_wd = s_app . rtc_time . weekday ;
if ( cur_wd ! = prev_wd ) {
// Weekday change, decide now
s_app . today_is_watering_day = false ;
uint8_t now_normalized = cur_wd + ( cur_wd < s_app . last_watering_day_wd ? 7 : 0 ) ;
uint8_t elapsed_days = now_normalized - s_app . last_watering_day_wd ;
if ( elapsed_days > = app_config . scheduler_dry_days ) {
s_app . today_is_watering_day = true ;
s_app . last_watering_day_wd = cur_wd ;
}
}
}
gui_read_moisture ( ) ;
}
@ -44,11 +86,19 @@ void gui_init()
read_time_and_moisture ( ) ;
s_app . today_is_watering_day = true ;
s_app . last_watering_day_wd = s_app . rtc_time . weekday ;
LcdBuffer_Init ( & lcd , CGROM_A00 , CGRAM_CZ ) ;
}
static bool blink_state = 0 ;
bool is_valve_control_screen ( )
{
return s_app . screen = = screen_cyklus | | s_app . screen = = screen_manual_control ;
}
void gui_loop_iter ( GuiEvent message )
{
uint32_t tickNow = timestamp_ms ( ) ;
@ -56,7 +106,7 @@ void gui_loop_iter(GuiEvent message)
// Time program logic - since this runs very often, we are guaranteed not to miss a cycle - unless there is a power outage
// exactly in the scheduled watering time
if ( s_app . screen ! = screen_cyklus & & app_config . scheduler_enable ) {
if ( ! is_valve_control_screen ( ) & & app_config . scheduler_enable & & ( s_app . today_is_watering_day | | app_config . scheduler_dry_days = = 0 ) ) { // if dry days=0, is_wd should always be true, but making sure here
if ( s_app . cycle_time_checking ) {
if ( s_app . rtc_time . hour ! = s_app . last_cycle_time . hour
| | s_app . rtc_time . minute ! = s_app . last_cycle_time . minute ) {
@ -88,12 +138,19 @@ void gui_loop_iter(GuiEvent message)
}
// screen auto-close
if ( s_app . screen ! = screen_home & & s_app . screen ! = screen_cyklus ) {
if ( s_app . screen ! = screen_home & & ! is_valve_control_screen ( ) ) {
if ( ( tickNow - s_app . screen_open_time ) > = ( MENU_AUTOEXIT_TIME_S * 1000 ) ) {
switch_screen ( screen_home , true ) ;
}
}
// exit manual mode after long time
if ( s_app . screen = = screen_manual_control ) {
if ( ( tickNow - s_app . screen_open_time ) > = ( 3600 * 1000 ) ) {
switch_screen ( screen_home , true ) ;
}
}
// Read RTC every second
if ( tickNow - s_app . last_1s_time > = 1000 ) {
s_app . screen ( GUI_EVENT_SCREEN_TICK_1S ) ;
@ -154,13 +211,17 @@ void gui_loop_iter(GuiEvent message)
/** Switch to a different screen handler.
* If " init " is true , immediately call it with the init event . */
void switch_screen ( screen_t pScreen , bool init )
static void switch_screen_ex ( screen_t pScreen , bool init , bool deinit_curren t )
{
if ( s_app . screen = = pScreen ) {
// already, no op
return ;
}
if ( s_app . screen & & deinit_current ) {
s_app . screen ( GUI_EVENT_SCREEN_DEINIT ) ;
}
s_app . screen_open_time = timestamp_ms ( ) ;
s_app . screen = pScreen ;
@ -178,6 +239,21 @@ void switch_screen(screen_t pScreen, bool init)
}
}
void switch_screen ( screen_t pScreen , bool init )
{
switch_screen_ex ( pScreen , init , true ) ;
}
void switch_to_subscreen ( screen_t pScreen )
{
switch_screen_ex ( pScreen , true , false ) ;
}
void switch_to_parent_screen ( screen_t pScreen )
{
switch_screen_ex ( pScreen , false , true ) ;
}
/** Draw GUI common to all screens */
static void draw_common_overlay ( )
{