diff options
Diffstat (limited to 'src/procedures.c')
-rw-r--r-- | src/procedures.c | 503 |
1 files changed, 458 insertions, 45 deletions
diff --git a/src/procedures.c b/src/procedures.c index be3ab5e..13ca6f3 100644 --- a/src/procedures.c +++ b/src/procedures.c @@ -1,4 +1,5 @@ /* + * TODO: rename this to dbus_procedures.c * eulogium_procedures, available procedures * * Copyright (c) 2015 Ultimaker B.V. @@ -11,57 +12,174 @@ #include <Eldbus.h> #include <stdint.h> -#include "procedures.h" - #include "dbus_common.h" +#include "eulogium.h" #include "print_data.h" +#include "procedures.h" +#include "settings_data.h" +#include "ui_widgets.h" #define _PROC_PRINT "PRINT" -#define _PROC_HEATUP_HOTEND "HEATUP_HOTEND" +#define _META_PRINT_JOBNAME "jobname" +#define _META_PRINT_JOBNAME_TYPE VALUE_STR +#define _META_PRINT_TIME "time" +#define _META_PRINT_TIME_TYPE VALUE_DOUBLE +#define _META_PRINT_TIME_TOTAL "time_total" +#define _META_PRINT_TIME_TOTAL_TYPE VALUE_DOUBLE +#define _META_PRINT_PROGRESS "progress" +#define _META_PRINT_PROGRESS_TYPE VALUE_DOUBLE + #define _PROC_POST_PRINT "POST_PRINT" #define _PROC_PRE_PRINT_SETUP "PRE_PRINT_SETUP" +#define _PROC_RUN_PRE_PRINT_SETUP "RUN_PRE_PRINT_SETUP" +#define _PROC_WAIT_FOR_CLEANUP "WAIT_FOR_CLEANUP" + +#define _PROC_BED_HEATUP "HEATUP_BED" +#define _PROC_HOTEND_HEATUP_0 "HEATUP_HOTEND_0" +#define _PROC_HOTEND_HEATUP_1 "HEATUP_HOTEND_1" +#define _PROC_PRINT_SPEED "PRINT_SPEED" +#define _PROC_FAN_SPEED "FAN_SPEED" +#define _PROC_FLOW_RATE "MATERIAL_FLOW" +#define _META_CURRENT "current" +#define _META_TARGET "target" + +#define _STEP_PRINTING "PRINTING" +#define _STEP_PRINT_SPEEDING "PRINT_SPEEDING" +#define _STEP_HOTEND_HEATING "HOTEND_HEATING" +#define _STEP_BED_HEATING "BED_HEATING" +#define _STEP_FAN_SPEEDING "FAN_SPEEDING" +#define _STEP_MATERIAL_FLOWING "MATERIAL_FLOWING" +#define _STEP_HOTEND_HOMEING "HOTEND_HOMEING" +#define _STEP_BED_HOMEING "HOTEND_HOMEING" -void _container_basic_variant(Eldbus_Message_Iter *parent, const char type, void *data) +#define _PROC_MSG_PRINTER_CLEANED "PRINTER_CLEANED" + +static Eldbus_Proxy *__proxy = NULL; + +static void _container_basic_variant(Eldbus_Message_Iter *parent, int type, ...) { Eldbus_Message_Iter *child; + va_list value; char sig[2] = { '\0' }; sig[0] = type; child = eldbus_message_iter_container_new(parent, 'v', sig); - eldbus_message_iter_basic_append(child, type, data); + va_start(value, type); + eldbus_message_iter_arguments_vappend(child, sig, value); + va_end(value); eldbus_message_iter_container_close(parent, child); } -static struct procedure_data procedures[] = { - { - .key = _PROC_PRINT, - .keylen = sizeof(_PROC_PRINT), - .executable = EINA_FALSE, - .available = EINA_FALSE, - }, { - .key = _PROC_HEATUP_HOTEND, - .keylen = sizeof(_PROC_HEATUP_HOTEND), - .executable = EINA_FALSE, - .available = EINA_FALSE, - }, { - .key = _PROC_POST_PRINT, - .keylen = sizeof(_PROC_POST_PRINT), - .executable = EINA_FALSE, - .available = EINA_FALSE, - }, { - .key = _PROC_PRE_PRINT_SETUP, - .keylen = sizeof(_PROC_PRE_PRINT_SETUP), - .executable = EINA_FALSE, - .available = EINA_FALSE, - }, { - NULL /* sentinel */ +static void _container_dict_basic_variant_append(Eldbus_Message_Iter *array, int type, const char *key, ...) /* TODO rename something key/value */ +{ + Eldbus_Message_Iter *value, *dict; + va_list ap; + char sig[2] = { '\0' }; + + sig[0] = type; + + dict = eldbus_message_iter_container_new(array, 'e', NULL); /* { */ + eldbus_message_iter_basic_append(dict, 's', key); /* s (key) */ + value = eldbus_message_iter_container_new(dict, 'v', sig); /* start variant */ + va_start(ap, key); + eldbus_message_iter_arguments_vappend(value, sig, ap); /* v (value) */ + va_end(ap); + eldbus_message_iter_container_close(dict, value); /* end variant */ + eldbus_message_iter_container_close(array, dict); /* } */ +} + +/* TODO move to ui_invalidate_navi_items ?? */ +static void _invalidate_navi_items(Evas_Object *navi, const enum navi_page_state page_state) +{ + Eina_List *navi_list, *l; + Elm_Object_Item *navi_item; + enum navi_page_state page; + + navi_list = elm_naviframe_items_get(navi); + EINA_LIST_FOREACH(navi_list, l, navi_item) { + page = (enum navi_page_state)(uintptr_t)elm_object_item_data_get(navi_item); + if (page == page_state) + elm_object_item_data_set(navi_item, (void *)PAGE_INVALID); } -}; + eina_list_free(navi_list); +} -struct procedure_data *procedures_init(void) +static void _get_meta_print(void *data, const void *key, Eldbus_Message_Iter *var) { - return procedures; -}; + struct print_data *print = data; + const char *skey = key; + char *var_sig; + + if (!print) { + EINA_LOG_ERR("dial_data should not be null"); + return; + } + + var_sig = eldbus_message_iter_signature_get(var); + if (!strcmp(skey, _META_PRINT_JOBNAME)) { + char *value = NULL; + + if (!eldbus_message_iter_arguments_get(var, "s", &value)) {/* TODO: check if value is leaking mem here */ + EINA_LOG_ERR("Message signature does not match \"s\", got %s", var_sig); + } else { + uint_fast16_t value_size = strlen(value) + 1; + + print->jobname = realloc(print->jobname, value_size); + strncpy(print->jobname, value, value_size); + } + + } else if (!strcmp(skey, _META_PRINT_TIME)) { + int32_t value = 0; + + if (!eldbus_message_iter_arguments_get(var, "i", &value)) + EINA_LOG_ERR("Message signature does not match \"i\", got %s", var_sig); + else + print->time = value; + } else if (!strcmp(skey, _META_PRINT_TIME_TOTAL)) { + int32_t value = 0; + + if (!eldbus_message_iter_arguments_get(var, "i", &value)) + EINA_LOG_ERR("Message signature does not match \"i\", got %s", var_sig); + else + print->total_time = value; + } + if (!strcmp(skey, _META_PRINT_PROGRESS)) { + double value = 0.0; + + if (!eldbus_message_iter_arguments_get(var, "d", &value)) + EINA_LOG_ERR("Message signature does not match \"d\", got %s", var_sig); + else + print->progress = value; + } + free(var_sig); +} + +static void _get_meta_cur_tar(void *data, const void *key, Eldbus_Message_Iter *var) +{ + struct settings_dial_data *dial_data = data; + const char *skey = key; + char *var_sig; + double value; + + if (!dial_data) { + EINA_LOG_ERR("dial_data should not be null"); + return; + } + + var_sig = eldbus_message_iter_signature_get(var); + if (!strcmp(skey, _META_TARGET)) { + if (!eldbus_message_iter_arguments_get(var, "d", &value)) + EINA_LOG_ERR("Message signature does not match \"d\", got %s", var_sig); + else + dial_data->value = value; + } else if (!strcmp(skey, _META_CURRENT)) { + if (!eldbus_message_iter_arguments_get(var, "d", &value)) + EINA_LOG_ERR("Message signature does not match \"d\", got %s", var_sig); + else + dial_data->value_end = value; + } + free(var_sig); +} static void _on_start_print_ret(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED) { @@ -74,7 +192,7 @@ static void _on_start_print_ret(void *data, const Eldbus_Message *msg, Eldbus_Pe return; } if (!eldbus_message_arguments_get(msg, "b", &print_started)) { - EINA_LOG_ERR("Failed to start print."); + EINA_LOG_ERR("Signature mistmatch, \"b\"."); return; } if (print_started == EINA_TRUE) { @@ -82,32 +200,327 @@ static void _on_start_print_ret(void *data, const Eldbus_Message *msg, Eldbus_Pe print->block = EINA_FALSE; } else { EINA_LOG_ERR("Unable to start print"); + /* TODO, if print start failed, invalidate all PRINTING pages */ + //_invalidate_navi_items(eulogium->navi, PAGE_PRINTING); + } +} + +static void _on_start_dial_ret(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED) +{ + char *label = data; + const char *errname, *errmsg; + Eina_Bool procedure_started = EINA_FALSE; + + if (eldbus_message_error_get(msg, &errname, &errmsg)) { + EINA_LOG_ERR("%s %s", errname, errmsg); + return; + } + if (!eldbus_message_arguments_get(msg, "b", &procedure_started)) { + EINA_LOG_ERR("Signature mistmatch, \"b\"."); + return; + } + if (procedure_started == EINA_TRUE) { + EINA_LOG_INFO("Procedure %s has been successfully started", label); + } else { + EINA_LOG_ERR("Unable to start procedure %s", label); + /* TODO, if tuning failed .. */ + } +} + +Eina_Bool _print_progress_cleanup(void *data, Elm_Object_Item *eoi EINA_UNUSED) +{ + eulogium_print_data_clear(data); + + return EINA_TRUE; +} + +void procedure_process_step(struct eulogium_data *eulogium, struct procedure_data *procedure) +{ + Evas_Object *content = NULL; + Elm_Object_Item *navi_item = NULL; + enum navi_page_state page_state = PAGE_NORMAL; + + if (!procedure) + return; + if (!procedure->step_active) + return; + + /* TODO build 'remember previous screen so we don't redraw the same' */ + EINA_LOG_CRIT("%s", procedure->step_active->key); + if (procedure->step_active->step == STEP_PRINTING) { + content = eulogium_print_progress(eulogium->navi, eulogium, (struct print_data *)procedure->meta); + page_state = PAGE_PRINTING; + } + if (procedure->step_active->step == PROC_WAIT_FOR_CLEANUP) { + _invalidate_navi_items(eulogium->navi, PAGE_PRINTING); + content = eulogium_clean_print_bed(eulogium); + } + + if (!content) + return; + + navi_item = elm_naviframe_item_simple_push(eulogium->navi, content); + elm_object_item_data_set(navi_item, (void *)page_state); + if (page_state == PAGE_PRINTING) + elm_naviframe_item_pop_cb_set(navi_item, _print_progress_cleanup, eulogium); +} + +static struct procedure_msg print_msgs[] = { + { + .key = _PROC_MSG_PRINTER_CLEANED, + .msg = PROC_MSG_PRINTER_CLEANED, + }, { NULL }, /* sentinel */ +}; + +static struct procedure_step steps_print[] = { + { + .key = _PROC_RUN_PRE_PRINT_SETUP, + .step = PROC_RUN_PRE_PRINT_SETUP, + }, { + .key = _STEP_PRINTING, + .step = STEP_PRINTING, + }, { + .key = _PROC_POST_PRINT, + .step = PROC_POST_PRINT, + }, { + .key = _PROC_WAIT_FOR_CLEANUP, + .step = PROC_WAIT_FOR_CLEANUP, + }, { NULL }, /* sentinel */ +}; + +static struct procedure_step steps_bed_temp_set[] = { + { + .key = _STEP_BED_HEATING, + .step = STEP_HEATING, + }, { NULL }, /* sentinel */ +}; + +static struct procedure_step steps_hotend_temp_set[] = { + { + .key = _STEP_HOTEND_HEATING, + .step = STEP_HEATING, + }, { NULL }, /* sentinel */ +}; + +static struct procedure_step steps_fan_speed_set[] = { + { + .key = _STEP_FAN_SPEEDING, + .step = STEP_SPEEDING, + }, { NULL }, /* sentinel */ +}; + +static struct procedure_step steps_flow_rate_set[] = { + { + .key = _STEP_MATERIAL_FLOWING, + .step = STEP_SPEEDING, + }, { NULL }, /* sentinel */ +}; + +static struct procedure_step steps_print_speed_set[] = { + { + .key = _STEP_PRINT_SPEEDING, + .step = STEP_SPEEDING, + }, { NULL }, /* sentinel */ +}; + +static struct procedure_data procedures[] = { + [PROC_PRINT] = { + .key = _PROC_PRINT, + .status = PROC_READY, + .parser = _get_meta_print, + .executable = EINA_FALSE, + .available = EINA_FALSE, + ._steps = steps_print, + .step_active = NULL, + .meta = NULL, /* struct print_data * */ + }, + [PROC_BED_HEATUP] = { + .key = _PROC_BED_HEATUP, + .status = PROC_READY, + .parser = _get_meta_cur_tar, + .executable = EINA_FALSE, + .available = EINA_FALSE, + ._steps = steps_bed_temp_set, + .step_active = NULL, + .meta = NULL, + }, + [PROC_HOTEND_HEATUP_0] = { + .key = _PROC_HOTEND_HEATUP_0, + .status = PROC_READY, + .parser = _get_meta_cur_tar, + .executable = EINA_FALSE, + .available = EINA_FALSE, + ._steps = steps_hotend_temp_set, + .step_active = NULL, + .meta = NULL, + }, + [PROC_HOTEND_HEATUP_1] = { + .key = _PROC_HOTEND_HEATUP_1, + .status = PROC_READY, + .parser = _get_meta_cur_tar, + .executable = EINA_FALSE, + .available = EINA_FALSE, + ._steps = steps_hotend_temp_set, + .step_active = NULL, + .meta = NULL, + }, + [PROC_PRINT_SPEED] = { + .key = _PROC_PRINT_SPEED, + .status = PROC_READY, + .parser = _get_meta_cur_tar, + .executable = EINA_FALSE, + .available = EINA_FALSE, + ._steps = steps_print_speed_set, + .step_active = NULL, + .meta = NULL, + }, + [PROC_FAN_SPEED] = { + .key = _PROC_FAN_SPEED, + .status = PROC_READY, + .parser = _get_meta_cur_tar, + .executable = EINA_FALSE, + .available = EINA_FALSE, + ._steps = steps_fan_speed_set, + .step_active = NULL, + .meta = NULL, + }, + [PROC_FLOW_RATE] = { + .key = _PROC_FLOW_RATE, + .status = PROC_READY, + .parser = _get_meta_cur_tar, + .executable = EINA_FALSE, + .available = EINA_FALSE, + ._steps = steps_flow_rate_set, + .step_active = NULL, + .meta = NULL, + }, { NULL }, /* sentinel */ +}; + +void procedure_meta_set(struct procedure_data *procedure, void *data) +{ + procedure->meta = data; +} + +void *procedure_meta_get(struct procedure_data *procedure) +{ + return procedure->meta; +} + +const struct procedure_step *procedure_step_get(const struct procedure_data *proc, const char *key) +{ + uint_fast16_t i; + + if (!proc) + return NULL; + + for (i = 0; proc->_steps[i].key; i++) { + if (!strcmp(proc->_steps[i].key, key)) + return &proc->_steps[i]; + } + + return NULL; +}; + +const struct procedure_data *procedure_get(const char *key) +{ + enum procedure_key i; + + for (i = PROC_PRINT; procedures[i].key; i++) { + if (!strcmp(procedures[i].key, key)) + return &procedures[i]; } + + return NULL; +}; + +Eldbus_Pending *procedure_message(const struct procedure_data *proc, const struct procedure_msg *msg) +{ + return eldbus_proxy_call(__proxy, "messageProcedure", NULL, NULL, -1, "ss", proc->key, msg->key); } -Eldbus_Pending *procedure_start_print(Eldbus_Proxy *proxy, struct print_data *print) +Eldbus_Pending *procedure_led_brightness_set(const Evas_Object *dial) +{ + //struct settings_dial_data *dial_data; + +// dial_data = evas_object_data_get(dial, "dial_data"); +// eldbus_proxy_call(dial_data->proxy, "SetBrightness", _on_dial_units_update_ret, dial, -1, ""); +} + +Eldbus_Pending *procedure_print_printer_cleaned(void) /* XXX pass procedure step? */ +{ + return eldbus_proxy_call(__proxy, "messageProcedure", on_method_generic_bool_ret, NULL, -1, "ss", _PROC_PRINT, _PROC_MSG_PRINTER_CLEANED); +} + +/* TODO half of the content of this procedure is generic and could be gotten from the procedure if it where a parameter. This can be made much more generic. */ +Eldbus_Pending *procedure_print_start(const struct print_data *print) { Eldbus_Message *msg; - Eldbus_Message_Iter *iter, *dict, *array; + Eldbus_Message_Iter *iter, *array; - msg = eldbus_proxy_method_call_new(proxy, "startProcedure"); + msg = eldbus_proxy_method_call_new(__proxy, "startProcedure"); iter = eldbus_message_iter_get(msg); /* Compose msg sa{sv} */ eldbus_message_iter_basic_append(iter, 's', "PRINT"); array = eldbus_message_iter_container_new(iter, 'a', "{sv}"); - dict = eldbus_message_iter_container_new(array, 'e', NULL); - eldbus_message_iter_basic_append(dict, 's', "name"); - _container_basic_variant(dict, 's', print->name); - eldbus_message_iter_container_close(array, dict); + _container_dict_basic_variant_append(array, 's', "name", print->name); + _container_dict_basic_variant_append(array, 's', "url", print->url); + + eldbus_message_iter_container_close(iter, array); + + return eldbus_proxy_send(__proxy, msg, _on_start_print_ret, print, -1); +} + +/* TODO, add resend/retry if actual value does not match current value */ +Eldbus_Pending *procedure_target_set(const enum procedure_key proc_key) +{ + Eldbus_Message *msg; + Eldbus_Message_Iter *iter, *array; + struct procedure_data *procedure = &procedures[proc_key]; + struct settings_dial_data *dial_data = procedure->meta; + + msg = eldbus_proxy_method_call_new(__proxy, "startProcedure"); + iter = eldbus_message_iter_get(msg); + + /* Compose msg sa{sv} */ + printf("Prockey: %s\n", procedure->key); + eldbus_message_iter_basic_append(iter, 's', procedure->key); + array = eldbus_message_iter_container_new(iter, 'a', "{sv}"); - dict = eldbus_message_iter_container_new(array, 'e', NULL); - eldbus_message_iter_basic_append(dict, 's', "url"); - _container_basic_variant(dict, 's', print->url); - eldbus_message_iter_container_close(array, dict); + _container_dict_basic_variant_append(array, 'd', "target", dial_data->value); eldbus_message_iter_container_close(iter, array); - return eldbus_proxy_send(proxy, msg, &_on_start_print_ret, print, -1); + return eldbus_proxy_send(__proxy, msg, _on_start_dial_ret, dial_data->label, -1); +} + +Eldbus_Pending *procedure_metadata_get(enum procedure_key proc_key) +{ + return eldbus_proxy_call(__proxy, "getProcedureMetaData", on_method_get_procedure_metadata_ret, &procedures[proc_key], -1, "s", procedures[proc_key].key); } + +void procedure_meta_getall(void) +{ + enum procedure_key i; + + for (i = PROC_NONE; i < PROC_LAST; i++) + if (procedures[i].key) + procedure_metadata_get(i); +}; + +struct procedure_data *procedures_init(Eldbus_Proxy *proxy) +{ + __proxy = proxy; + + /* TODO: we probably should do something here to prepare all procedures and their meta data + * so that we can do the getall here and drop the function altogether. + */ + return procedures; +}; + +void procedures_shutdown(void) +{ + free(procedures[PROC_PRINT].meta); + eldbus_proxy_unref(__proxy); +}; |