static void static_setpoint_button_clicked(button_event_t* event) { if (event->id != EVT_BUTTON_CLICK) return; controller_settings_screen_t* s = widget_get_user_data(event->widget); unit_t temp_units = app_cfg_get_temp_unit(); float min; float max; char* title; if (s->controller == CONTROLLER_1) title = "Controller 1 Setpoint"; else title = "Controller 2 Setpoint"; float velocity_steps[] = { 0.1f, 0.5f, 1.0f }; if (temp_units == UNIT_TEMP_DEG_F) { min = MIN_TEMP_F; max = MAX_TEMP_F; } else{ min = MIN_TEMP_C; max = MAX_TEMP_C; } widget_t* static_setpoint_screen = quantity_select_screen_create( title, s->settings.static_setpoint, min, max, velocity_steps, 3, update_static_setpoint, s); gui_push_screen(static_setpoint_screen); }
static void rebuild_offset_screen(offset_screen_t* s) { uint32_t num_buttons = 0; button_spec_t buttons[3]; char* text; char* units_subtext; char* probe1_subtext = NULL; char* probe2_subtext = NULL; bool sensor1_connected = get_sensor_conn_status(SENSOR_1); bool sensor2_connected = get_sensor_conn_status(SENSOR_2); sensor_config_t* sensor1_cfg = get_sensor_cfg(SENSOR_1); sensor_config_t* sensor2_cfg = get_sensor_cfg(SENSOR_2); quantity_t probe1_offset = app_cfg_get_probe_offset(sensor1_cfg->sensor_serial); quantity_t probe2_offset = app_cfg_get_probe_offset(sensor2_cfg->sensor_serial); if (app_cfg_get_temp_unit() == UNIT_TEMP_DEG_F) { units_subtext = "F"; } else { probe1_offset.value *= (5.0f / 9.0f); probe2_offset.value *= (5.0f / 9.0f); units_subtext = "C"; } if (sensor1_connected == true) { text = "Probe 1 Offset"; probe1_subtext = malloc(128); snprintf(probe1_subtext, 128, "Probe 1 Offset: %d.%d %s", (int)(probe1_offset.value), ((int)(fabs(probe1_offset.value) * 10.0f)) % 10, units_subtext); add_button_spec(buttons, &num_buttons, probe1_offset_button_clicked, img_temp_med, AMBER, text, probe1_subtext, s); } if (sensor2_connected == true) { text = "Probe 2 Offset"; probe2_subtext = malloc(128); snprintf(probe2_subtext, 128, "Probe 2 Offset: %d.%d %s", (int)(probe2_offset.value), ((int)(fabs(probe2_offset.value) * 10.0f)) % 10, units_subtext); add_button_spec(buttons, &num_buttons, probe2_offset_button_clicked, img_temp_med, MAGENTA, text, probe2_subtext, s); } button_list_set_buttons(s->button_list, buttons, num_buttons); if (probe1_subtext != NULL) free(probe1_subtext); if (probe2_subtext != NULL) free(probe2_subtext); }
static void build_offset_screen(offset_screen_t* s, char* title) { float velocity_steps[] = { 0.1f }; sensor_config_t* sensor_cfg = get_sensor_cfg(s->sensor_id); quantity_t probe_offset = app_cfg_get_probe_offset(sensor_cfg->sensor_serial); if (app_cfg_get_temp_unit() == UNIT_TEMP_DEG_C) { probe_offset.value *= (5.0f / 9.0f); probe_offset.unit = UNIT_TEMP_DEG_C; } widget_t* probe_offset_screen = quantity_select_screen_create( title, probe_offset, MIN_PROBE_OFFSET, MAX_PROBE_OFFSET, velocity_steps, 1, update_probe_offset, s); gui_push_screen(probe_offset_screen); }
static void set_controller_settings(controller_settings_screen_t* s) { uint32_t num_buttons = 0; button_spec_t buttons[16]; char* subtext; char* setpoint_subtext; switch (s->settings.setpoint_type) { case SP_STATIC: subtext = "Static Setpoint - Temp is held at fixed value"; break; case SP_TEMP_PROFILE: subtext = "Temp Profile - Temp follows customized profile"; break; default: subtext = "Invalid setpoint type!"; break; } add_button_spec(buttons, &num_buttons, setpoint_type_button_clicked, img_snowflake, CYAN, "Setpoint Type", subtext, s); setpoint_subtext = malloc(128); switch (s->settings.setpoint_type) { case SP_STATIC: { quantity_t setpoint = quantity_convert(s->settings.static_setpoint, app_cfg_get_temp_unit()); if (setpoint.unit == UNIT_TEMP_DEG_F) subtext = "F"; else subtext = "C"; snprintf(setpoint_subtext, 128, "Setpoint value: %d.%d %s", (int)(setpoint.value), ((int)(fabs(setpoint.value) * 10.0f)) % 10, subtext); add_button_spec(buttons, &num_buttons, static_setpoint_button_clicked, img_snowflake, CYAN, "Static Setpoint", setpoint_subtext, s); break; } case SP_TEMP_PROFILE: { const temp_profile_t* tp = app_cfg_get_temp_profile(s->settings.temp_profile_id); if (tp != NULL) snprintf(setpoint_subtext, 128, "Selected profile: '%s'", tp->name); else snprintf(setpoint_subtext, 128, "Selected profile: id=%u", (unsigned int)s->settings.temp_profile_id); add_button_spec(buttons, &num_buttons, temp_profile_button_clicked, img_snowflake, CYAN, "Temp Profile", setpoint_subtext, s); break; } default: break; } switch (s->output_selection) { case SELECT_1: subtext = "Use Output #1"; break; case SELECT_2: subtext = "Use Output #2"; break; case SELECT_1_2: subtext = "Use Output #1 & #2"; break; default: case SELECT_NONE: subtext = "No output"; break; } add_button_spec(buttons, &num_buttons, output_selection_button_clicked, img_plug, CYAN, "Output Selection", subtext, s); if (s->settings.output_settings[OUTPUT_1].enabled) add_button_spec(buttons, &num_buttons, output_settings_button_clicked, img_plug, CYAN, "Output 1 Settings", "Set settings for output 1", &s->settings.output_settings[OUTPUT_1]); if (s->settings.output_settings[OUTPUT_2].enabled) add_button_spec(buttons, &num_buttons, output_settings_button_clicked, img_plug, CYAN, "Output 2 Settings", "Set settings for output 2", &s->settings.output_settings[OUTPUT_2]); button_list_set_buttons(s->button_list, buttons, num_buttons); free(setpoint_subtext); }
widget_t* home_screen_create() { home_screen_t* s = calloc(1, sizeof(home_screen_t)); s->sample_timestamp = chTimeNow(); s->screen = widget_create(NULL, &home_widget_class, s, display_rect); widget_set_background(s->screen, BLACK); rect_t rect = { .x = TILE_X(0), .y = TILE_Y(0), .width = TILE_SPAN(3), .height = TILE_SPAN(2), }; s->stage_widget = widget_create(s->screen, NULL, NULL, rect); widget_set_background(s->stage_widget, GREEN); rect.x = TILE_X(3); rect.width = TILE_SPAN(1); rect.height = TILE_SPAN(1); s->sensors[SENSOR_1].button = button_create(s->screen, rect, img_temp_med, WHITE, STEEL, click_sensor_button); rect.y = TILE_Y(1); s->sensors[SENSOR_2].button = button_create(s->screen, rect, img_temp_med, WHITE, STEEL, click_sensor_button); rect.x = TILE_X(0); rect.y = TILE_Y(2); s->outputs[OUTPUT_1].button = button_create(s->screen, rect, img_plug, WHITE, STEEL, click_output_button); rect.x = TILE_X(1); s->outputs[OUTPUT_2].button = button_create(s->screen, rect, img_plug, WHITE, STEEL, click_output_button); rect.x = TILE_X(2); s->conn_button = button_create(s->screen, rect, img_signal, RED, STEEL, click_conn_button); rect.x = TILE_X(3); s->settings_button = button_create(s->screen, rect, img_settings, WHITE, COBALT, click_settings_button); rect.x = 0; rect.width = TILE_SPAN(3); s->sensors[SENSOR_1].quantity_widget = quantity_widget_create(s->stage_widget, rect, app_cfg_get_temp_unit()); widget_disable(s->sensors[SENSOR_1].quantity_widget); s->sensors[SENSOR_2].quantity_widget = quantity_widget_create(s->stage_widget, rect, app_cfg_get_temp_unit()); widget_disable(s->sensors[SENSOR_2].quantity_widget); place_quantity_widgets(s); set_output_settings(s, OUTPUT_1, temp_control_get_output_function(OUTPUT_1)); set_output_settings(s, OUTPUT_2, temp_control_get_output_function(OUTPUT_2)); gui_msg_subscribe(MSG_SENSOR_SAMPLE, s->screen); gui_msg_subscribe(MSG_SENSOR_TIMEOUT, s->screen); gui_msg_subscribe(MSG_OUTPUT_STATUS, s->screen); gui_msg_subscribe(MSG_TEMP_UNIT, s->screen); gui_msg_subscribe(MSG_NET_STATUS, s->screen); gui_msg_subscribe(MSG_API_STATUS, s->screen); gui_msg_subscribe(MSG_CONTROLLER_SETTINGS, s->screen); gui_msg_subscribe(MSG_API_CONTROLLER_SETTINGS, s->screen); return s->screen; } void home_screen_destroy(widget_t* w) { home_screen_t* s = widget_get_instance_data(w); gui_msg_unsubscribe(MSG_SENSOR_SAMPLE, s->screen); gui_msg_unsubscribe(MSG_SENSOR_TIMEOUT, s->screen); gui_msg_unsubscribe(MSG_OUTPUT_STATUS, s->screen); gui_msg_unsubscribe(MSG_TEMP_UNIT, s->screen); gui_msg_unsubscribe(MSG_NET_STATUS, s->screen); gui_msg_unsubscribe(MSG_API_STATUS, s->screen); gui_msg_unsubscribe(MSG_CONTROLLER_SETTINGS, s->screen); gui_msg_unsubscribe(MSG_API_CONTROLLER_SETTINGS, s->screen); free(s); }