Browse Source

edit menu to reorder workflows and steps

Thomas Buck 6 months ago
parent
commit
6ad8468dcd

+ 2
- 0
CMakeLists.txt View File

88
     src/crafty.c
88
     src/crafty.c
89
     src/state_crafty.c
89
     src/state_crafty.c
90
     src/mem.c
90
     src/mem.c
91
+    src/state_edit_workflow.c
92
+    src/workflow_default.c
91
 
93
 
92
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ff.c
94
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ff.c
93
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ffunicode.c
95
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ffunicode.c

+ 8
- 3
include/mem.h View File

20
 #define __MEM_H__
20
 #define __MEM_H__
21
 
21
 
22
 #include <stdint.h>
22
 #include <stdint.h>
23
+#include "workflow.h"
23
 
24
 
24
-#define MEM_VERSION 0x01
25
+#define MEM_VERSION 0x02
25
 
26
 
26
 struct mem_data {
27
 struct mem_data {
27
     uint16_t backlight;
28
     uint16_t backlight;
29
+    uint16_t wf_count;
30
+    struct workflow wf[WF_MAX_FLOWS];
28
 } __attribute__((packed));
31
 } __attribute__((packed));
29
 
32
 
30
-#define MEM_DATA_INIT {         \
31
-    .backlight = (0xFF00 >> 1), \
33
+
34
+// wf and wf_count are assigned in mem_init()
35
+#define MEM_DATA_INIT {           \
36
+    .backlight = (0xFF00 >> 1),   \
32
 }
37
 }
33
 
38
 
34
 void mem_init(void);
39
 void mem_init(void);

+ 4
- 1
include/menu.h View File

31
     char *buff;
31
     char *buff;
32
 };
32
 };
33
 
33
 
34
-void menu_init(void (*enter)(int), void (*exit)(void));
34
+void menu_init(void (*enter)(int),
35
+               void (*up)(int),
36
+               void (*down)(int),
37
+               void (*exit)(void));
35
 void menu_deinit(void);
38
 void menu_deinit(void);
36
 
39
 
37
 void menu_run(void (*cb)(struct menu_state *), bool centered);
40
 void menu_run(void (*cb)(struct menu_state *), bool centered);

+ 1
- 0
include/state.h View File

25
     STATE_VOLCANO_WORKFLOW,
25
     STATE_VOLCANO_WORKFLOW,
26
     STATE_VOLCANO_RUN,
26
     STATE_VOLCANO_RUN,
27
     STATE_CRAFTY,
27
     STATE_CRAFTY,
28
+    STATE_EDIT_WORKFLOW,
28
 
29
 
29
     STATE_INVALID,
30
     STATE_INVALID,
30
 };
31
 };

+ 30
- 0
include/state_edit_workflow.h View File

1
+/*
2
+ * state_edit_workflow.h
3
+ *
4
+ * Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * See <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+#ifndef __STATE_EDIT_WORKFLOW_H__
20
+#define __STATE_EDIT_WORKFLOW_H__
21
+
22
+#include <stdint.h>
23
+
24
+void state_edit_wf_index(uint16_t index);
25
+
26
+void state_edit_wf_enter(void);
27
+void state_edit_wf_exit(void);
28
+void state_edit_wf_run(void);
29
+
30
+#endif // __STATE_EDIT_WORKFLOW_H__

+ 4
- 0
include/state_volcano_workflow.h View File

19
 #ifndef __STATE_VOLCANO_WORKFLOW_H__
19
 #ifndef __STATE_VOLCANO_WORKFLOW_H__
20
 #define __STATE_VOLCANO_WORKFLOW_H__
20
 #define __STATE_VOLCANO_WORKFLOW_H__
21
 
21
 
22
+#include <stdbool.h>
23
+
24
+void state_volcano_wf_edit(bool edit);
25
+
22
 void state_volcano_wf_enter(void);
26
 void state_volcano_wf_enter(void);
23
 void state_volcano_wf_exit(void);
27
 void state_volcano_wf_exit(void);
24
 void state_volcano_wf_run(void);
28
 void state_volcano_wf_run(void);

+ 25
- 0
include/workflow.h View File

21
 
21
 
22
 #include <stdint.h>
22
 #include <stdint.h>
23
 
23
 
24
+#define WF_MAX_STEPS 42
25
+#define WF_MAX_FLOWS 6
26
+
24
 enum wf_op {
27
 enum wf_op {
25
     OP_SET_TEMPERATURE = 0,
28
     OP_SET_TEMPERATURE = 0,
26
     OP_WAIT_TEMPERATURE,
29
     OP_WAIT_TEMPERATURE,
33
     uint16_t val;
36
     uint16_t val;
34
 };
37
 };
35
 
38
 
39
+struct workflow {
40
+    const char *name;
41
+    const char *author;
42
+    struct wf_step steps[WF_MAX_STEPS];
43
+    uint16_t count;
44
+};
45
+
36
 enum wf_status {
46
 enum wf_status {
37
     WF_IDLE = 0,
47
     WF_IDLE = 0,
38
     WF_RUNNING,
48
     WF_RUNNING,
48
 };
58
 };
49
 
59
 
50
 uint16_t wf_count(void);
60
 uint16_t wf_count(void);
61
+
62
+void wf_move_down(uint16_t index);
63
+void wf_move_up(uint16_t index);
64
+
51
 const char *wf_name(uint16_t index);
65
 const char *wf_name(uint16_t index);
52
 const char *wf_author(uint16_t index);
66
 const char *wf_author(uint16_t index);
53
 
67
 
68
+uint16_t wf_steps(uint16_t index);
69
+
70
+void wf_move_step_down(uint16_t index, uint16_t step);
71
+void wf_move_step_up(uint16_t index, uint16_t step);
72
+
73
+struct wf_step wf_get_step(uint16_t index, uint16_t step);
74
+const char *wf_step_str(struct wf_step step);
75
+
54
 struct wf_state wf_status(void);
76
 struct wf_state wf_status(void);
55
 void wf_start(uint16_t index);
77
 void wf_start(uint16_t index);
56
 
78
 
57
 void wf_reset(void);
79
 void wf_reset(void);
58
 void wf_run(void);
80
 void wf_run(void);
59
 
81
 
82
+extern const uint16_t wf_default_count;
83
+extern const struct workflow wf_default_data[];
84
+
60
 #endif // __WORKFLOW_H__
85
 #endif // __WORKFLOW_H__

+ 5
- 0
src/mem.c View File

78
 }
78
 }
79
 
79
 
80
 void mem_init(void) {
80
 void mem_init(void) {
81
+    data_ram.data.wf_count = wf_default_count;
82
+    for (uint16_t i = 0; i < wf_default_count; i++) {
83
+        data_ram.data.wf[i] = wf_default_data[i];
84
+    }
85
+
81
     if (!flash_safe_execute_core_init()) {
86
     if (!flash_safe_execute_core_init()) {
82
         debug("error calling flash_safe_execute_core_init");
87
         debug("error calling flash_safe_execute_core_init");
83
     }
88
     }

+ 18
- 1
src/menu.c View File

29
 static char buff[MENU_MAX_LEN] = {0};
29
 static char buff[MENU_MAX_LEN] = {0};
30
 static struct menu_state menu = { .off = 0, .selection = -1, .length = 0, .buff = buff };
30
 static struct menu_state menu = { .off = 0, .selection = -1, .length = 0, .buff = buff };
31
 static void (*enter_callback)(int) = NULL;
31
 static void (*enter_callback)(int) = NULL;
32
+static void (*up_callback)(int) = NULL;
33
+static void (*down_callback)(int) = NULL;
32
 static void (*exit_callback)(void) = NULL;
34
 static void (*exit_callback)(void) = NULL;
33
 
35
 
34
 static void menu_buttons(enum buttons btn, bool state) {
36
 static void menu_buttons(enum buttons btn, bool state) {
53
             enter_callback(menu.selection);
55
             enter_callback(menu.selection);
54
         }
56
         }
55
         return;
57
         return;
58
+    } else if (state && (btn == BTN_B)) {
59
+        if (up_callback) {
60
+            up_callback(menu.selection);
61
+        }
62
+        return;
63
+    } else if (state && (btn == BTN_X)) {
64
+        if (down_callback) {
65
+            down_callback(menu.selection);
66
+        }
67
+        return;
56
     } else if (state && (btn == BTN_Y)) {
68
     } else if (state && (btn == BTN_Y)) {
57
         if (exit_callback) {
69
         if (exit_callback) {
58
             exit_callback();
70
             exit_callback();
91
     }
103
     }
92
 }
104
 }
93
 
105
 
94
-void menu_init(void (*enter)(int), void (*exit)(void)) {
106
+void menu_init(void (*enter)(int),
107
+               void (*up)(int),
108
+               void (*down)(int),
109
+               void (*exit)(void)) {
95
     menu.off = 0;
110
     menu.off = 0;
96
     menu.selection = -1;
111
     menu.selection = -1;
97
     menu.length = 0;
112
     menu.length = 0;
98
 
113
 
99
     enter_callback = enter;
114
     enter_callback = enter;
115
+    up_callback = up;
116
+    down_callback = down;
100
     exit_callback = exit;
117
     exit_callback = exit;
101
     buttons_callback(menu_buttons);
118
     buttons_callback(menu_buttons);
102
 }
119
 }

+ 6
- 0
src/state.c View File

22
 #include "state_volcano_workflow.h"
22
 #include "state_volcano_workflow.h"
23
 #include "state_volcano_run.h"
23
 #include "state_volcano_run.h"
24
 #include "state_crafty.h"
24
 #include "state_crafty.h"
25
+#include "state_edit_workflow.h"
25
 #include "state.h"
26
 #include "state.h"
26
 
27
 
27
 #define stringify(name) # name
28
 #define stringify(name) # name
60
         .exit = state_crafty_exit,
61
         .exit = state_crafty_exit,
61
         .run = state_crafty_run,
62
         .run = state_crafty_run,
62
     }, {
63
     }, {
64
+        .name = stringify(STATE_EDIT_WORKFLOW),
65
+        .enter = state_edit_wf_enter,
66
+        .exit = state_edit_wf_exit,
67
+        .run = state_edit_wf_run,
68
+    }, {
63
         .name = stringify(STATE_INVALID),
69
         .name = stringify(STATE_INVALID),
64
         .enter = NULL,
70
         .enter = NULL,
65
         .exit = NULL,
71
         .exit = NULL,

+ 92
- 0
src/state_edit_workflow.c View File

1
+/*
2
+ * state_edit_workflow.c
3
+ *
4
+ * Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * See <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+#include <stdio.h>
20
+#include <string.h>
21
+
22
+#include "config.h"
23
+#include "menu.h"
24
+#include "workflow.h"
25
+#include "state.h"
26
+#include "state_edit_workflow.h"
27
+
28
+static uint16_t wf_index = 0;
29
+
30
+static void enter_cb(int selection) {
31
+    if ((selection >= 0) && (selection < wf_steps(wf_index))) {
32
+        // TODO edit value
33
+    }
34
+}
35
+
36
+static void lower_cb(int selection) {
37
+    if ((selection > 0) && (selection < wf_steps(wf_index))) {
38
+        wf_move_step_down(wf_index, selection);
39
+    }
40
+}
41
+
42
+static void upper_cb(int selection) {
43
+    if ((selection >= 0) && (selection < (wf_steps(wf_index) - 1))) {
44
+        wf_move_step_up(wf_index, selection);
45
+    }
46
+}
47
+
48
+static void exit_cb(void) {
49
+    state_switch(STATE_SCAN);
50
+}
51
+
52
+void state_edit_wf_index(uint16_t index) {
53
+    wf_index = index;
54
+}
55
+
56
+void state_edit_wf_enter(void) {
57
+    menu_init(enter_cb, lower_cb, upper_cb, exit_cb);
58
+}
59
+
60
+void state_edit_wf_exit(void) {
61
+    menu_deinit();
62
+}
63
+
64
+static void draw(struct menu_state *menu) {
65
+    menu->length = wf_steps(wf_index);
66
+
67
+    int pos = 0;
68
+    for (uint16_t i = 0; i < menu->length; i++) {
69
+        if ((i < menu->off)
70
+            || ((i - menu->off) >= MENU_MAX_LINES)) {
71
+            continue;
72
+        }
73
+
74
+        if (i == menu->selection) {
75
+            pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos, "> ");
76
+        } else {
77
+            pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos, "  ");
78
+        }
79
+
80
+        struct wf_step step = wf_get_step(wf_index, i);
81
+        pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos,
82
+                        "% 2d: %s\n", i, wf_step_str(step));
83
+    }
84
+
85
+    if (menu->selection < 0) {
86
+        menu->selection = 0;
87
+    }
88
+}
89
+
90
+void state_edit_wf_run(void) {
91
+    menu_run(draw, false);
92
+}

+ 10
- 1
src/state_scan.c View File

24
 #include "models.h"
24
 #include "models.h"
25
 #include "menu.h"
25
 #include "menu.h"
26
 #include "state.h"
26
 #include "state.h"
27
+#include "state_volcano_workflow.h"
27
 #include "state_volcano_run.h"
28
 #include "state_volcano_run.h"
28
 #include "state_crafty.h"
29
 #include "state_crafty.h"
29
 #include "state_scan.h"
30
 #include "state_scan.h"
42
         if (devs++ == selection) {
43
         if (devs++ == selection) {
43
             if (dev == DEV_VOLCANO) {
44
             if (dev == DEV_VOLCANO) {
44
                 state_volcano_run_target(results[i].addr, results[i].type);
45
                 state_volcano_run_target(results[i].addr, results[i].type);
46
+                state_volcano_wf_edit(false);
45
                 state_switch(STATE_VOLCANO_WORKFLOW);
47
                 state_switch(STATE_VOLCANO_WORKFLOW);
46
             } else if (dev == DEV_CRAFTY) {
48
             } else if (dev == DEV_CRAFTY) {
47
                 state_crafty_target(results[i].addr, results[i].type);
49
                 state_crafty_target(results[i].addr, results[i].type);
52
     }
54
     }
53
 }
55
 }
54
 
56
 
57
+static void edit_cb(int selection) {
58
+    UNUSED(selection);
59
+
60
+    state_volcano_wf_edit(true);
61
+    state_switch(STATE_VOLCANO_WORKFLOW);
62
+}
63
+
55
 void state_scan_enter(void) {
64
 void state_scan_enter(void) {
56
-    menu_init(enter_cb, NULL);
65
+    menu_init(enter_cb, edit_cb, NULL, NULL);
57
     ble_scan(BLE_SCAN_ON);
66
     ble_scan(BLE_SCAN_ON);
58
 }
67
 }
59
 
68
 

+ 4
- 6
src/state_volcano_run.c View File

59
 }
59
 }
60
 
60
 
61
 void state_volcano_run_enter(void) {
61
 void state_volcano_run_enter(void) {
62
-    menu_init(NULL, NULL);
62
+    menu_init(NULL, NULL, NULL, NULL);
63
     buttons_callback(volcano_buttons);
63
     buttons_callback(volcano_buttons);
64
 
64
 
65
     debug("workflow connect");
65
     debug("workflow connect");
93
     switch (state.step.op) {
93
     switch (state.step.op) {
94
     case OP_SET_TEMPERATURE:
94
     case OP_SET_TEMPERATURE:
95
         pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos,
95
         pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos,
96
-                        "\nset temp %.1f C", state.step.val / 10.0f);
96
+                        "\n%s", wf_step_str(state.step));
97
         break;
97
         break;
98
 
98
 
99
     case OP_WAIT_TEMPERATURE:
99
     case OP_WAIT_TEMPERATURE:
100
         pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos,
100
         pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos,
101
-                        "wait temp %.1f C\n", state.step.val / 10.0f);
101
+                        "%s\n", wf_step_str(state.step));
102
         pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos,
102
         pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos,
103
                         "%.1f -> %.1f -> %.1f",
103
                         "%.1f -> %.1f -> %.1f",
104
                         state.start_val / 10.0f,
104
                         state.start_val / 10.0f,
109
     case OP_WAIT_TIME:
109
     case OP_WAIT_TIME:
110
     case OP_PUMP_TIME:
110
     case OP_PUMP_TIME:
111
         pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos,
111
         pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos,
112
-                        "%s time %.1f s\n",
113
-                        (state.step.op == OP_WAIT_TIME) ? "wait" : "pump",
114
-                        state.step.val / 1000.0f);
112
+                        "%s\n", wf_step_str(state.step));
115
         pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos,
113
         pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos,
116
                         "%.0f -> %.0f -> %.0f",
114
                         "%.0f -> %.0f -> %.0f",
117
                         state.start_val / 1000.0f,
115
                         state.start_val / 1000.0f,

+ 41
- 4
src/state_volcano_workflow.c View File

24
 #include "workflow.h"
24
 #include "workflow.h"
25
 #include "state.h"
25
 #include "state.h"
26
 #include "state_volcano_run.h"
26
 #include "state_volcano_run.h"
27
+#include "state_edit_workflow.h"
27
 #include "state_volcano_workflow.h"
28
 #include "state_volcano_workflow.h"
28
 
29
 
30
+static bool edit_mode = false;
31
+
29
 static void enter_cb(int selection) {
32
 static void enter_cb(int selection) {
30
     if ((selection >= 0) && (selection < wf_count())) {
33
     if ((selection >= 0) && (selection < wf_count())) {
31
-        state_volcano_run_index(selection);
32
-        state_switch(STATE_VOLCANO_RUN);
34
+        if (edit_mode) {
35
+            state_edit_wf_index(selection);
36
+            state_switch(STATE_EDIT_WORKFLOW);
37
+        } else {
38
+            state_volcano_run_index(selection);
39
+            state_switch(STATE_VOLCANO_RUN);
40
+        }
41
+    }
42
+}
43
+
44
+static void lower_cb(int selection) {
45
+    if (!edit_mode) {
46
+        return;
47
+    }
48
+
49
+    if ((selection > 0) && (selection < wf_count())) {
50
+        wf_move_down(selection);
51
+    }
52
+}
53
+
54
+static void upper_cb(int selection) {
55
+    if (!edit_mode) {
56
+        return;
57
+    }
58
+
59
+    if ((selection >= 0) && (selection < (wf_count() - 1))) {
60
+        wf_move_up(selection);
33
     }
61
     }
34
 }
62
 }
35
 
63
 
37
     state_switch(STATE_SCAN);
65
     state_switch(STATE_SCAN);
38
 }
66
 }
39
 
67
 
68
+void state_volcano_wf_edit(bool edit) {
69
+    edit_mode = edit;
70
+}
71
+
40
 void state_volcano_wf_enter(void) {
72
 void state_volcano_wf_enter(void) {
41
-    menu_init(enter_cb, exit_cb);
73
+    if (edit_mode) {
74
+        menu_init(enter_cb, lower_cb, upper_cb, exit_cb);
75
+    } else {
76
+        menu_init(enter_cb, NULL, NULL, exit_cb);
77
+    }
42
 }
78
 }
43
 
79
 
44
 void state_volcano_wf_exit(void) {
80
 void state_volcano_wf_exit(void) {
61
             pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos, "  ");
97
             pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos, "  ");
62
         }
98
         }
63
 
99
 
64
-        pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos, "'%s' by %s\n", wf_name(i), wf_author(i));
100
+        pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos,
101
+                        "'%s' by %s\n", wf_name(i), wf_author(i));
65
     }
102
     }
66
 
103
 
67
     if ((menu->selection < 0) && (menu->length > 0)) {
104
     if ((menu->selection < 0) && (menu->length > 0)) {

+ 116
- 144
src/workflow.c View File

16
  * See <http://www.gnu.org/licenses/>.
16
  * See <http://www.gnu.org/licenses/>.
17
  */
17
  */
18
 
18
 
19
+#include <stdio.h>
20
+
19
 #include "config.h"
21
 #include "config.h"
20
 #include "log.h"
22
 #include "log.h"
23
+#include "mem.h"
21
 #include "volcano.h"
24
 #include "volcano.h"
22
 #include "workflow.h"
25
 #include "workflow.h"
23
 
26
 
24
-#define WF_MAX_STEPS 42
25
-#define WF_MAX_FLOWS 6
26
-
27
-struct workflow {
28
-    const char *name;
29
-    const char *author;
30
-    struct wf_step steps[WF_MAX_STEPS];
31
-    uint16_t count;
32
-};
33
-
34
-#define NOTIFY \
35
-    { .op = OP_WAIT_TIME, .val = 1000 }, \
36
-    { .op = OP_PUMP_TIME, .val = 1000 }
37
-
38
-static const struct workflow wf[WF_MAX_FLOWS] = {
39
-    {
40
-        .name = "XXL",
41
-        .author = "xythobuz",
42
-        .steps = {
43
-            { .op = OP_WAIT_TEMPERATURE, .val = 1850 },
44
-            { .op = OP_WAIT_TIME, .val = 10000 },
45
-            { .op = OP_PUMP_TIME, .val = 8000 },
46
-
47
-            { .op = OP_WAIT_TEMPERATURE, .val = 1950 },
48
-            { .op = OP_WAIT_TIME, .val = 5000 },
49
-            { .op = OP_PUMP_TIME, .val = 25000 },
50
-
51
-            { .op = OP_WAIT_TEMPERATURE, .val = 2050 },
52
-            { .op = OP_WAIT_TIME, .val = 5000 },
53
-            { .op = OP_PUMP_TIME, .val = 25000 },
54
-
55
-            NOTIFY, NOTIFY, NOTIFY, NOTIFY,
56
-
57
-            { .op = OP_SET_TEMPERATURE, .val = 1900 },
58
-        },
59
-        .count = 18,
60
-    }, {
61
-        .name = "Default",
62
-        .author = "xythobuz",
63
-        .steps = {
64
-            { .op = OP_WAIT_TEMPERATURE, .val = 1850 },
65
-            { .op = OP_WAIT_TIME, .val = 10000 },
66
-            { .op = OP_PUMP_TIME, .val = 5000 },
67
-
68
-            { .op = OP_WAIT_TEMPERATURE, .val = 1950 },
69
-            { .op = OP_WAIT_TIME, .val = 5000 },
70
-            { .op = OP_PUMP_TIME, .val = 20000 },
71
-
72
-            { .op = OP_WAIT_TEMPERATURE, .val = 2050 },
73
-            { .op = OP_WAIT_TIME, .val = 5000 },
74
-            { .op = OP_PUMP_TIME, .val = 20000 },
75
-
76
-            NOTIFY, NOTIFY, NOTIFY, NOTIFY,
77
-
78
-            { .op = OP_SET_TEMPERATURE, .val = 1900 },
79
-        },
80
-        .count = 18,
81
-    }, {
82
-        .name = "Vorbi",
83
-        .author = "Rinor",
84
-        .steps = {
85
-            { .op = OP_WAIT_TEMPERATURE, .val = 1760 },
86
-            { .op = OP_WAIT_TIME, .val = 10000 },
87
-            { .op = OP_PUMP_TIME, .val = 6000 },
88
-
89
-            { .op = OP_WAIT_TEMPERATURE, .val = 1870 },
90
-            { .op = OP_WAIT_TIME, .val = 5000 },
91
-            { .op = OP_PUMP_TIME, .val = 10000 },
92
-
93
-            { .op = OP_WAIT_TEMPERATURE, .val = 2040 },
94
-            { .op = OP_WAIT_TIME, .val = 3000 },
95
-            { .op = OP_PUMP_TIME, .val = 10000 },
96
-
97
-            { .op = OP_WAIT_TEMPERATURE, .val = 2170 },
98
-            { .op = OP_WAIT_TIME, .val = 5000 },
99
-            { .op = OP_PUMP_TIME, .val = 10000 },
100
-        },
101
-        .count = 12,
102
-    }, {
103
-        .name = "Relaxo",
104
-        .author = "xythobuz",
105
-        .steps = {
106
-            { .op = OP_WAIT_TEMPERATURE, .val = 1750 },
107
-            { .op = OP_WAIT_TIME, .val = 10000 },
108
-            { .op = OP_PUMP_TIME, .val = 5000 },
109
-
110
-            { .op = OP_WAIT_TEMPERATURE, .val = 1850 },
111
-            { .op = OP_WAIT_TIME, .val = 5000 },
112
-            { .op = OP_PUMP_TIME, .val = 20000 },
113
-
114
-            { .op = OP_WAIT_TEMPERATURE, .val = 1950 },
115
-            { .op = OP_WAIT_TIME, .val = 5000 },
116
-            { .op = OP_PUMP_TIME, .val = 20000 },
117
-
118
-            NOTIFY, NOTIFY, NOTIFY, NOTIFY,
119
-
120
-            { .op = OP_SET_TEMPERATURE, .val = 1900 },
121
-        },
122
-        .count = 18,
123
-    }, {
124
-        .name = "Hotty",
125
-        .author = "xythobuz",
126
-        .steps = {
127
-            { .op = OP_WAIT_TEMPERATURE, .val = 1900 },
128
-            { .op = OP_WAIT_TIME, .val = 10000 },
129
-            { .op = OP_PUMP_TIME, .val = 5000 },
130
-
131
-            { .op = OP_WAIT_TEMPERATURE, .val = 2050 },
132
-            { .op = OP_WAIT_TIME, .val = 5000 },
133
-            { .op = OP_PUMP_TIME, .val = 20000 },
134
-
135
-            { .op = OP_WAIT_TEMPERATURE, .val = 2200 },
136
-            { .op = OP_WAIT_TIME, .val = 5000 },
137
-            { .op = OP_PUMP_TIME, .val = 20000 },
138
-
139
-            NOTIFY, NOTIFY, NOTIFY, NOTIFY,
140
-
141
-            { .op = OP_SET_TEMPERATURE, .val = 1900 },
142
-        },
143
-        .count = 18,
144
-    },
145
-};
146
-
147
-static const uint16_t count = 5;
148
-
149
 static enum wf_status status = WF_IDLE;
27
 static enum wf_status status = WF_IDLE;
150
 static uint16_t wf_i = 0;
28
 static uint16_t wf_i = 0;
151
 static uint16_t step = 0;
29
 static uint16_t step = 0;
154
 static uint16_t curr_val = 0;
32
 static uint16_t curr_val = 0;
155
 
33
 
156
 static void do_step(void) {
34
 static void do_step(void) {
157
-    switch (wf[wf_i].steps[step].op) {
35
+    switch (mem_data()->wf[wf_i].steps[step].op) {
158
     case OP_SET_TEMPERATURE:
36
     case OP_SET_TEMPERATURE:
159
     case OP_WAIT_TEMPERATURE:
37
     case OP_WAIT_TEMPERATURE:
160
-        debug("workflow temp %.1f C", wf[wf_i].steps[step].val / 10.0);
38
+        debug("workflow temp %.1f C", mem_data()->wf[wf_i].steps[step].val / 10.0);
161
         start_val = volcano_get_current_temp();
39
         start_val = volcano_get_current_temp();
162
         do {
40
         do {
163
-            volcano_set_target_temp(wf[wf_i].steps[step].val);
164
-        } while (volcano_get_target_temp() != wf[wf_i].steps[step].val);
41
+            volcano_set_target_temp(mem_data()->wf[wf_i].steps[step].val);
42
+        } while (volcano_get_target_temp() != mem_data()->wf[wf_i].steps[step].val);
165
         break;
43
         break;
166
 
44
 
167
     case OP_PUMP_TIME:
45
     case OP_PUMP_TIME:
168
         volcano_set_pump_state(true);
46
         volcano_set_pump_state(true);
169
         start_t = to_ms_since_boot(get_absolute_time());
47
         start_t = to_ms_since_boot(get_absolute_time());
170
         start_val = 0;
48
         start_val = 0;
171
-        debug("workflow pump %.3f s", wf[wf_i].steps[step].val / 1000.0);
49
+        debug("workflow pump %.3f s", mem_data()->wf[wf_i].steps[step].val / 1000.0);
172
         break;
50
         break;
173
 
51
 
174
     case OP_WAIT_TIME:
52
     case OP_WAIT_TIME:
175
         start_t = to_ms_since_boot(get_absolute_time());
53
         start_t = to_ms_since_boot(get_absolute_time());
176
         start_val = 0;
54
         start_val = 0;
177
-        debug("workflow time %.3f s", wf[wf_i].steps[step].val / 1000.0);
55
+        debug("workflow time %.3f s", mem_data()->wf[wf_i].steps[step].val / 1000.0);
178
         break;
56
         break;
179
     }
57
     }
180
 
58
 
182
 }
60
 }
183
 
61
 
184
 uint16_t wf_count(void) {
62
 uint16_t wf_count(void) {
185
-    return count;
63
+    return mem_data()->wf_count;
64
+}
65
+
66
+void wf_move_down(uint16_t index) {
67
+    if ((index < 1) || (index >= mem_data()->wf_count)) {
68
+        debug("invalid index %d", index);
69
+        return;
70
+    }
71
+
72
+    struct workflow tmp = mem_data()->wf[index - 1];
73
+    mem_data()->wf[index - 1] = mem_data()->wf[index];
74
+    mem_data()->wf[index] = tmp;
75
+}
76
+
77
+void wf_move_up(uint16_t index) {
78
+    if (index >= (mem_data()->wf_count - 1)) {
79
+        debug("invalid index %d", index);
80
+        return;
81
+    }
82
+
83
+    struct workflow tmp = mem_data()->wf[index + 1];
84
+    mem_data()->wf[index + 1] = mem_data()->wf[index];
85
+    mem_data()->wf[index] = tmp;
86
+}
87
+
88
+uint16_t wf_steps(uint16_t index) {
89
+    if (index >= mem_data()->wf_count) {
90
+        debug("invalid index %d", index);
91
+        return 0;
92
+    }
93
+    return mem_data()->wf[index].count;
94
+}
95
+
96
+void wf_move_step_down(uint16_t index, uint16_t step) {
97
+    if (index >= mem_data()->wf_count) {
98
+        debug("invalid index %d", index);
99
+        return;
100
+    }
101
+    if ((step < 1) || (step >= mem_data()->wf[index].count)) {
102
+        debug("invalid step %d", step);
103
+        return;
104
+    }
105
+
106
+    struct wf_step tmp = mem_data()->wf[index].steps[step - 1];
107
+    mem_data()->wf[index].steps[step - 1] = mem_data()->wf[index].steps[step];
108
+    mem_data()->wf[index].steps[step] = tmp;
109
+}
110
+
111
+void wf_move_step_up(uint16_t index, uint16_t step) {
112
+    if (index >= mem_data()->wf_count) {
113
+        debug("invalid index %d", index);
114
+        return;
115
+    }
116
+    if (step >= (mem_data()->wf[index].count - 1)) {
117
+        debug("invalid step %d", step);
118
+        return;
119
+    }
120
+
121
+    struct wf_step tmp = mem_data()->wf[index].steps[step + 1];
122
+    mem_data()->wf[index].steps[step + 1] = mem_data()->wf[index].steps[step];
123
+    mem_data()->wf[index].steps[step] = tmp;
124
+}
125
+
126
+struct wf_step wf_get_step(uint16_t index, uint16_t step) {
127
+    if (index >= mem_data()->wf_count) {
128
+        debug("invalid index %d", index);
129
+        return mem_data()->wf[0].steps[0];
130
+    }
131
+    return mem_data()->wf[index].steps[step];
132
+}
133
+
134
+const char *wf_step_str(struct wf_step step) {
135
+    static char buff[20];
136
+
137
+    switch (step.op) {
138
+    case OP_SET_TEMPERATURE:
139
+        snprintf(buff, sizeof(buff),
140
+                 "set temp %.1f C", step.val / 10.0f);
141
+        break;
142
+
143
+    case OP_WAIT_TEMPERATURE:
144
+        snprintf(buff, sizeof(buff),
145
+                 "wait temp %.1f C", step.val / 10.0f);
146
+        break;
147
+
148
+    case OP_WAIT_TIME:
149
+    case OP_PUMP_TIME:
150
+        snprintf(buff, sizeof(buff),
151
+                 "%s time %.1f s",
152
+                 (step.op == OP_WAIT_TIME) ? "wait" : "pump",
153
+                 step.val / 1000.0f);
154
+        break;
155
+    }
156
+
157
+    return buff;
186
 }
158
 }
187
 
159
 
188
 const char *wf_name(uint16_t index) {
160
 const char *wf_name(uint16_t index) {
189
-    if (index >= count) {
161
+    if (index >= mem_data()->wf_count) {
190
         debug("invalid index %d", index);
162
         debug("invalid index %d", index);
191
         return NULL;
163
         return NULL;
192
     }
164
     }
193
-    return wf[index].name;
165
+    return mem_data()->wf[index].name;
194
 }
166
 }
195
 
167
 
196
 const char *wf_author(uint16_t index) {
168
 const char *wf_author(uint16_t index) {
197
-    if (index >= count) {
169
+    if (index >= mem_data()->wf_count) {
198
         debug("invalid index %d", index);
170
         debug("invalid index %d", index);
199
         return NULL;
171
         return NULL;
200
     }
172
     }
201
-    return wf[index].author;
173
+    return mem_data()->wf[index].author;
202
 }
174
 }
203
 
175
 
204
 struct wf_state wf_status(void) {
176
 struct wf_state wf_status(void) {
205
     struct wf_state s = {
177
     struct wf_state s = {
206
         .status = status,
178
         .status = status,
207
         .index = step,
179
         .index = step,
208
-        .count = wf[wf_i].count,
209
-        .step = wf[wf_i].steps[step],
180
+        .count = mem_data()->wf[wf_i].count,
181
+        .step = mem_data()->wf[wf_i].steps[step],
210
         .start_val = start_val,
182
         .start_val = start_val,
211
         .curr_val = curr_val,
183
         .curr_val = curr_val,
212
     };
184
     };
218
         debug("workflow already running");
190
         debug("workflow already running");
219
         return;
191
         return;
220
     }
192
     }
221
-    if (index >= count) {
193
+    if (index >= mem_data()->wf_count) {
222
         debug("invalid index %d", index);
194
         debug("invalid index %d", index);
223
         return;
195
         return;
224
     }
196
     }
248
 
220
 
249
     bool done = false;
221
     bool done = false;
250
 
222
 
251
-    switch (wf[wf_i].steps[step].op) {
223
+    switch (mem_data()->wf[wf_i].steps[step].op) {
252
     case OP_SET_TEMPERATURE:
224
     case OP_SET_TEMPERATURE:
253
         done = true;
225
         done = true;
254
         break;
226
         break;
262
         }
234
         }
263
 
235
 
264
         curr_val = temp;
236
         curr_val = temp;
265
-        done = (temp >= (wf[wf_i].steps[step].val - 5));
237
+        done = (temp >= (mem_data()->wf[wf_i].steps[step].val - 5));
266
         break;
238
         break;
267
     }
239
     }
268
 
240
 
271
         uint32_t now = to_ms_since_boot(get_absolute_time());
243
         uint32_t now = to_ms_since_boot(get_absolute_time());
272
         uint32_t diff = now - start_t;
244
         uint32_t diff = now - start_t;
273
         curr_val = diff;
245
         curr_val = diff;
274
-        done = (diff >= wf[wf_i].steps[step].val);
246
+        done = (diff >= mem_data()->wf[wf_i].steps[step].val);
275
         break;
247
         break;
276
     }
248
     }
277
     }
249
     }
278
 
250
 
279
     if (done) {
251
     if (done) {
280
-        if (wf[wf_i].steps[step].op == OP_PUMP_TIME) {
252
+        if (mem_data()->wf[wf_i].steps[step].op == OP_PUMP_TIME) {
281
             volcano_set_pump_state(false);
253
             volcano_set_pump_state(false);
282
         }
254
         }
283
 
255
 
284
         step++;
256
         step++;
285
-        if (step >= wf[wf_i].count) {
257
+        if (step >= mem_data()->wf[wf_i].count) {
286
             status = WF_IDLE;
258
             status = WF_IDLE;
287
             volcano_set_heater_state(false);
259
             volcano_set_heater_state(false);
288
             debug("workflow finished");
260
             debug("workflow finished");

+ 135
- 0
src/workflow_default.c View File

1
+/*
2
+ * workflow_default.c
3
+ *
4
+ * Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * See <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+#include "config.h"
20
+#include "workflow.h"
21
+
22
+#define NOTIFY \
23
+    { .op = OP_WAIT_TIME, .val = 1000 }, \
24
+    { .op = OP_PUMP_TIME, .val = 1000 }
25
+
26
+const uint16_t wf_default_count = 5;
27
+
28
+const struct workflow wf_default_data[] = {
29
+    {
30
+        .name = "XXL",
31
+        .author = "xythobuz",
32
+        .steps = {
33
+            { .op = OP_WAIT_TEMPERATURE, .val = 1850 },
34
+            { .op = OP_WAIT_TIME, .val = 10000 },
35
+            { .op = OP_PUMP_TIME, .val = 8000 },
36
+
37
+            { .op = OP_WAIT_TEMPERATURE, .val = 1950 },
38
+            { .op = OP_WAIT_TIME, .val = 5000 },
39
+            { .op = OP_PUMP_TIME, .val = 25000 },
40
+
41
+            { .op = OP_WAIT_TEMPERATURE, .val = 2050 },
42
+            { .op = OP_WAIT_TIME, .val = 5000 },
43
+            { .op = OP_PUMP_TIME, .val = 25000 },
44
+
45
+            NOTIFY, NOTIFY, NOTIFY, NOTIFY,
46
+
47
+            { .op = OP_SET_TEMPERATURE, .val = 1900 },
48
+        },
49
+        .count = 18,
50
+    }, {
51
+        .name = "Default",
52
+        .author = "xythobuz",
53
+        .steps = {
54
+            { .op = OP_WAIT_TEMPERATURE, .val = 1850 },
55
+            { .op = OP_WAIT_TIME, .val = 10000 },
56
+            { .op = OP_PUMP_TIME, .val = 5000 },
57
+
58
+            { .op = OP_WAIT_TEMPERATURE, .val = 1950 },
59
+            { .op = OP_WAIT_TIME, .val = 5000 },
60
+            { .op = OP_PUMP_TIME, .val = 20000 },
61
+
62
+            { .op = OP_WAIT_TEMPERATURE, .val = 2050 },
63
+            { .op = OP_WAIT_TIME, .val = 5000 },
64
+            { .op = OP_PUMP_TIME, .val = 20000 },
65
+
66
+            NOTIFY, NOTIFY, NOTIFY, NOTIFY,
67
+
68
+            { .op = OP_SET_TEMPERATURE, .val = 1900 },
69
+        },
70
+        .count = 18,
71
+    }, {
72
+        .name = "Vorbi",
73
+        .author = "Rinor",
74
+        .steps = {
75
+            { .op = OP_WAIT_TEMPERATURE, .val = 1760 },
76
+            { .op = OP_WAIT_TIME, .val = 10000 },
77
+            { .op = OP_PUMP_TIME, .val = 6000 },
78
+
79
+            { .op = OP_WAIT_TEMPERATURE, .val = 1870 },
80
+            { .op = OP_WAIT_TIME, .val = 5000 },
81
+            { .op = OP_PUMP_TIME, .val = 10000 },
82
+
83
+            { .op = OP_WAIT_TEMPERATURE, .val = 2040 },
84
+            { .op = OP_WAIT_TIME, .val = 3000 },
85
+            { .op = OP_PUMP_TIME, .val = 10000 },
86
+
87
+            { .op = OP_WAIT_TEMPERATURE, .val = 2170 },
88
+            { .op = OP_WAIT_TIME, .val = 5000 },
89
+            { .op = OP_PUMP_TIME, .val = 10000 },
90
+        },
91
+        .count = 12,
92
+    }, {
93
+        .name = "Relaxo",
94
+        .author = "xythobuz",
95
+        .steps = {
96
+            { .op = OP_WAIT_TEMPERATURE, .val = 1750 },
97
+            { .op = OP_WAIT_TIME, .val = 10000 },
98
+            { .op = OP_PUMP_TIME, .val = 5000 },
99
+
100
+            { .op = OP_WAIT_TEMPERATURE, .val = 1850 },
101
+            { .op = OP_WAIT_TIME, .val = 5000 },
102
+            { .op = OP_PUMP_TIME, .val = 20000 },
103
+
104
+            { .op = OP_WAIT_TEMPERATURE, .val = 1950 },
105
+            { .op = OP_WAIT_TIME, .val = 5000 },
106
+            { .op = OP_PUMP_TIME, .val = 20000 },
107
+
108
+            NOTIFY, NOTIFY, NOTIFY, NOTIFY,
109
+
110
+            { .op = OP_SET_TEMPERATURE, .val = 1900 },
111
+        },
112
+        .count = 18,
113
+    }, {
114
+        .name = "Hotty",
115
+        .author = "xythobuz",
116
+        .steps = {
117
+            { .op = OP_WAIT_TEMPERATURE, .val = 1900 },
118
+            { .op = OP_WAIT_TIME, .val = 10000 },
119
+            { .op = OP_PUMP_TIME, .val = 5000 },
120
+
121
+            { .op = OP_WAIT_TEMPERATURE, .val = 2050 },
122
+            { .op = OP_WAIT_TIME, .val = 5000 },
123
+            { .op = OP_PUMP_TIME, .val = 20000 },
124
+
125
+            { .op = OP_WAIT_TEMPERATURE, .val = 2200 },
126
+            { .op = OP_WAIT_TIME, .val = 5000 },
127
+            { .op = OP_PUMP_TIME, .val = 20000 },
128
+
129
+            NOTIFY, NOTIFY, NOTIFY, NOTIFY,
130
+
131
+            { .op = OP_SET_TEMPERATURE, .val = 1900 },
132
+        },
133
+        .count = 18,
134
+    },
135
+};

Loading…
Cancel
Save