|
@@ -74,7 +74,8 @@ uint32_t Statemachine::DigitBuffer::getNumber(void) {
|
74
|
74
|
|
75
|
75
|
static const char *state_names[] = {
|
76
|
76
|
stringify(init),
|
77
|
|
- stringify(menu),
|
|
77
|
+ stringify(menu_a),
|
|
78
|
+ stringify(menu_b),
|
78
|
79
|
stringify(auto_mode_a),
|
79
|
80
|
stringify(auto_mode_b),
|
80
|
81
|
stringify(auto_fert),
|
|
@@ -86,6 +87,7 @@ static const char *state_names[] = {
|
86
|
87
|
stringify(fillnwater_plant),
|
87
|
88
|
stringify(fillnwater_tank_run),
|
88
|
89
|
stringify(fillnwater_plant_run),
|
|
90
|
+ stringify(automation_mode),
|
89
|
91
|
stringify(menu_pumps),
|
90
|
92
|
stringify(menu_pumps_time),
|
91
|
93
|
stringify(menu_pumps_go),
|
|
@@ -103,6 +105,10 @@ const char *Statemachine::getStateName(void) {
|
103
|
105
|
return state_names[state];
|
104
|
106
|
}
|
105
|
107
|
|
|
108
|
+bool Statemachine::isIdle(void) {
|
|
109
|
+ return state == init;
|
|
110
|
+}
|
|
111
|
+
|
106
|
112
|
Statemachine::Statemachine(print_fn _print, backspace_fn _backspace)
|
107
|
113
|
: db(7), selected_plants(plants.countPlants()) {
|
108
|
114
|
state = init;
|
|
@@ -116,6 +122,7 @@ Statemachine::Statemachine(print_fn _print, backspace_fn _backspace)
|
116
|
122
|
stop_time = 0;
|
117
|
123
|
last_animation_time = 0;
|
118
|
124
|
error_condition = "";
|
|
125
|
+ into_state_time = 0;
|
119
|
126
|
}
|
120
|
127
|
|
121
|
128
|
void Statemachine::begin(void) {
|
|
@@ -124,17 +131,24 @@ void Statemachine::begin(void) {
|
124
|
131
|
|
125
|
132
|
void Statemachine::input(int n) {
|
126
|
133
|
if (state == init) {
|
127
|
|
- switch_to(menu);
|
128
|
|
- } else if (state == menu) {
|
|
134
|
+ switch_to(menu_a);
|
|
135
|
+ } else if ((state == menu_a) || (state == menu_b)) {
|
129
|
136
|
if (n == 1) {
|
130
|
137
|
switch_to(auto_mode_a);
|
131
|
138
|
} else if (n == 2) {
|
132
|
|
- switch_to(menu_pumps);
|
|
139
|
+ switch_to(automation_mode);
|
133
|
140
|
} else if (n == 3) {
|
|
141
|
+ switch_to(menu_pumps);
|
|
142
|
+ } else if (n == 4) {
|
134
|
143
|
switch_to(menu_valves);
|
135
|
|
- } else if ((n == -1) || (n == -2)) {
|
|
144
|
+ } else if (n == -1) {
|
136
|
145
|
switch_to(init);
|
|
146
|
+ } else if (n == -2) {
|
|
147
|
+ switch_to((state == menu_a) ? menu_b : menu_a);
|
137
|
148
|
}
|
|
149
|
+ } else if (state == automation_mode) {
|
|
150
|
+ // TODO
|
|
151
|
+ switch_to(menu_a);
|
138
|
152
|
} else if ((state == auto_mode_a) || (state == auto_mode_b)) {
|
139
|
153
|
if (n == 1) {
|
140
|
154
|
switch_to(auto_fert);
|
|
@@ -161,7 +175,7 @@ void Statemachine::input(int n) {
|
161
|
175
|
selected_plants.clear();
|
162
|
176
|
switch_to(auto_plant);
|
163
|
177
|
} else if (n == -1) {
|
164
|
|
- switch_to(menu);
|
|
178
|
+ switch_to(menu_a);
|
165
|
179
|
} else if (n == -2) {
|
166
|
180
|
switch_to((state == auto_mode_a) ? auto_mode_b : auto_mode_a);
|
167
|
181
|
}
|
|
@@ -251,7 +265,7 @@ void Statemachine::input(int n) {
|
251
|
265
|
backspace();
|
252
|
266
|
db.removeDigit();
|
253
|
267
|
} else {
|
254
|
|
- switch_to(menu);
|
|
268
|
+ switch_to(menu_b);
|
255
|
269
|
}
|
256
|
270
|
} else if (n == -2) {
|
257
|
271
|
if (!db.hasDigits()) {
|
|
@@ -357,7 +371,6 @@ void Statemachine::input(int n) {
|
357
|
371
|
start_time = millis();
|
358
|
372
|
switch_to(fillnwater_plant_run);
|
359
|
373
|
} else if (wl == Plants::empty) {
|
360
|
|
- stop_time = millis();
|
361
|
374
|
switch_to(auto_mode_a);
|
362
|
375
|
} else if (wl == Plants::invalid) {
|
363
|
376
|
error_condition = "Invalid sensor state";
|
|
@@ -421,14 +434,14 @@ void Statemachine::input(int n) {
|
421
|
434
|
stop_time = millis();
|
422
|
435
|
switch_to(menu_pumps_done);
|
423
|
436
|
} else if (state == menu_pumps_done) {
|
424
|
|
- switch_to(menu);
|
|
437
|
+ switch_to(menu_b);
|
425
|
438
|
} else if (state == menu_valves) {
|
426
|
439
|
if (n == -1) {
|
427
|
440
|
if (db.hasDigits()) {
|
428
|
441
|
backspace();
|
429
|
442
|
db.removeDigit();
|
430
|
443
|
} else {
|
431
|
|
- switch_to(menu);
|
|
444
|
+ switch_to(menu_b);
|
432
|
445
|
}
|
433
|
446
|
} else if (n == -2) {
|
434
|
447
|
if (!db.hasDigits()) {
|
|
@@ -508,12 +521,12 @@ void Statemachine::input(int n) {
|
508
|
521
|
stop_time = millis();
|
509
|
522
|
switch_to(menu_valves_done);
|
510
|
523
|
} else if (state == menu_valves_done) {
|
511
|
|
- switch_to(menu);
|
|
524
|
+ switch_to(menu_b);
|
512
|
525
|
} else if (state == error) {
|
513
|
526
|
if (old_state != error) {
|
514
|
527
|
switch_to(old_state);
|
515
|
528
|
} else {
|
516
|
|
- switch_to(menu);
|
|
529
|
+ switch_to(menu_a);
|
517
|
530
|
}
|
518
|
531
|
}
|
519
|
532
|
}
|
|
@@ -587,7 +600,29 @@ void Statemachine::act(void) {
|
587
|
600
|
// stop if timeout has been reached
|
588
|
601
|
plants.abort();
|
589
|
602
|
stop_time = millis();
|
590
|
|
- switch_to(auto_done);
|
|
603
|
+ if (state == fillnwater_tank_run) {
|
|
604
|
+ auto wl = plants.getWaterlevel();
|
|
605
|
+ if ((wl != Plants::empty) && (wl != Plants::invalid)) {
|
|
606
|
+ for (int i = 0; i < plants.countPlants(); i++) {
|
|
607
|
+ if (selected_plants.isSet(i)) {
|
|
608
|
+ plants.startPlant(i);
|
|
609
|
+ }
|
|
610
|
+ }
|
|
611
|
+
|
|
612
|
+ selected_time = MAX_AUTO_PLANT_RUNTIME;
|
|
613
|
+ start_time = millis();
|
|
614
|
+ switch_to(fillnwater_plant_run);
|
|
615
|
+ } else if (wl == Plants::empty) {
|
|
616
|
+ stop_time = millis();
|
|
617
|
+ switch_to(auto_done);
|
|
618
|
+ } else if (wl == Plants::invalid) {
|
|
619
|
+ error_condition = "Invalid sensor state";
|
|
620
|
+ state = auto_mode_a;
|
|
621
|
+ switch_to(error);
|
|
622
|
+ }
|
|
623
|
+ } else {
|
|
624
|
+ switch_to(auto_done);
|
|
625
|
+ }
|
591
|
626
|
} else if ((millis() - last_animation_time) >= 500) {
|
592
|
627
|
// update animation if needed
|
593
|
628
|
last_animation_time = millis();
|
|
@@ -656,11 +691,36 @@ void Statemachine::act(void) {
|
656
|
691
|
switch_to(error);
|
657
|
692
|
}
|
658
|
693
|
}
|
|
694
|
+
|
|
695
|
+ if ((state == menu_a) || (state == menu_b) || (state == automation_mode)
|
|
696
|
+ || (state == auto_mode_a) || (state == auto_mode_b)
|
|
697
|
+ || (state == auto_fert) || (state == auto_done)
|
|
698
|
+ || (state == auto_plant) || (state == fillnwater_plant)
|
|
699
|
+ || (state == menu_pumps) || (state == menu_pumps_time)
|
|
700
|
+ || (state == menu_pumps_go) || (state == menu_pumps_done)
|
|
701
|
+ || (state == menu_valves) || (state == menu_valves_time)
|
|
702
|
+ || (state == menu_valves_go) || (state == menu_valves_done)) {
|
|
703
|
+ unsigned long runtime = millis() - into_state_time;
|
|
704
|
+ if (runtime >= BACK_TO_IDLE_TIMEOUT) {
|
|
705
|
+ debug.print("Idle timeout reached in state ");
|
|
706
|
+ debug.println(state_names[state]);
|
|
707
|
+ switch_to(init);
|
|
708
|
+ }
|
|
709
|
+ }
|
659
|
710
|
}
|
660
|
711
|
|
661
|
712
|
void Statemachine::switch_to(States s) {
|
662
|
713
|
old_state = state;
|
663
|
714
|
state = s;
|
|
715
|
+ into_state_time = millis();
|
|
716
|
+
|
|
717
|
+ if (old_state != state) {
|
|
718
|
+ // don't spam log with every animation state "change"
|
|
719
|
+ debug.print("switch_to ");
|
|
720
|
+ debug.print(state_names[old_state]);
|
|
721
|
+ debug.print(" --> ");
|
|
722
|
+ debug.println(state_names[state]);
|
|
723
|
+ }
|
664
|
724
|
|
665
|
725
|
if (s == init) {
|
666
|
726
|
String a = String("- Giess-o-mat V") + FIRMWARE_VERSION + String(" -");
|
|
@@ -670,20 +730,33 @@ void Statemachine::switch_to(States s) {
|
670
|
730
|
"* Delete prev. digit",
|
671
|
731
|
"# Execute input num.",
|
672
|
732
|
-1);
|
673
|
|
- } else if (s == menu) {
|
674
|
|
- print("------- Menu -------",
|
675
|
|
- "1: Automatic program",
|
676
|
|
- "2: Fertilizer pumps",
|
677
|
|
- "3: Outlet valves",
|
|
733
|
+ } else if (s == menu_a) {
|
|
734
|
+ print("----- Menu 1/2 -----",
|
|
735
|
+ "1: Manual Operation",
|
|
736
|
+ "2: Automation",
|
|
737
|
+ "#: Go to page 2/2...",
|
|
738
|
+ -1);
|
|
739
|
+ } else if (s == menu_b) {
|
|
740
|
+ print("----- Menu 2/2 -----",
|
|
741
|
+ "3: Fertilizer pumps",
|
|
742
|
+ "4: Outlet valves",
|
|
743
|
+ "#: Go to page 1/2...",
|
|
744
|
+ -1);
|
|
745
|
+ } else if (state == automation_mode) {
|
|
746
|
+ // TODO
|
|
747
|
+ print("---- Automation ----",
|
|
748
|
+ "TODO NOT IMPLEMENTED",
|
|
749
|
+ "TODO NOT IMPLEMENTED",
|
|
750
|
+ "TODO NOT IMPLEMENTED",
|
678
|
751
|
-1);
|
679
|
752
|
} else if (s == auto_mode_a) {
|
680
|
|
- print("----- Auto 1/2 -----",
|
|
753
|
+ print("---- Manual 1/2 ----",
|
681
|
754
|
"1: Add Fertilizer",
|
682
|
755
|
"2: Fill 'n' Water",
|
683
|
756
|
"#: Go to page 2/2...",
|
684
|
757
|
-1);
|
685
|
758
|
} else if (s == auto_mode_b) {
|
686
|
|
- print("----- Auto 2/2 -----",
|
|
759
|
+ print("---- Manual 2/2 ----",
|
687
|
760
|
"3: Fill Reservoir",
|
688
|
761
|
"4: Water a plant",
|
689
|
762
|
"#: Go to page 1/2...",
|