summaryrefslogtreecommitdiffstats
path: root/src/procedures.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/procedures.c')
-rw-r--r--src/procedures.c503
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);
+};