ESP_IOT v2.5
IOT ESP Coding
ModelController.cpp
Go to the documentation of this file.
1#include "../../Defines.h"
2#include "ModelController.h"
3
4//*** For the MenuSelection MODEL
5//! a pseudo Class
6
7#define MenusModel_Help 0
8#define MenusModel_Settings 1
9#define MenusModel_Pairing 2
10#define MenusModel_APMode 3
11#define MenusModel_Timer 4
12#define MenusModel_Status 5
13#define MenusModel_Advanced 6
14#define MenusModel_WIFIShare 7
15#define MenusModel_GuestFeed 8
16#define MenusModel_GuestPage 9
17#define MenusModel_DocFollow 10
18#define MenusModel_Max 11
19
20//!retrieves the state model for the modelKind
22
23//!storage of mapping
25//!init the mapping
27{
28 for (int i=0; i< MenusModel_Max; i++)
29 {
30 switch (i)
31 {
34 break;
37 break;
40 break;
43 break;
46 break;
49 break;
52 break;
55 break;
58 break;
61 break;
62 case MenusModel_Help:
64 break;
65 default:
66 SerialMin.println(" *** invalid menu item");
67 break;
68 }
69 }
70}
71//!
72//!create state variables for the ModelKindEnum entries
74char _timerBuffer[10];
75
76//!initialize the objects
78{
79 strcpy(_timerBuffer,"5");
81
82 for (int i=0;i< ModelKindEnumMax;i++)
83 {
86 switch (i)
87 {
91 break;
92 case rebootModel:
95
96 //STATE info..
97 //! for the next page state 0..n
99 // the max before goes back to 0, use SM_LAST from MainModule.h
103 _modelStateStructs[i].waveName = (char*)"KikahaPhotos"; // for now.. TODO .. explain this..
104 break;
105 case menusModel:
108 break;
109 case timerModel:
112 //! true if still waiting for delay to finish
114 //! length of delay
115 //!get from in EPROM
118 SerialCall.printf("initTimer: sec = %d\n", _modelStateStructs[i].currentCounterSeconds);
119#if defined(ESP_M5_CAMERA) || defined(ESP_32)
120 //! feed local instead of MQTT or BLE..
121 //! if camera then feed local == take a picture..
123#else
124 //! feed local instead of MQTT or BLE..
126#endif //ESP_32 or CAMERA
127 break;
128 }
129 }
130}
131
132//!! TIMER Remote control set delay seconds
133//!MQTT: set: timerdelay, val:seconds
135{
136 SerialDebug.printf("setTimerDelaySeconds_mainModule(%d)\n", delaySeconds);
137
138 ModelStateStruct *timerModelStruct = getModel(timerModel);
139 timerModelStruct->delaySeconds = delaySeconds;
140 timerModelStruct->currentCounterSeconds = delaySeconds;
141 //!save in EPROM
143
144}
145
146//!! TIMER Remote control start
147//!MQTT: set: starttimer, val: true/false (true == start timer, false = stop timer)
148void startStopTimer_mainModule(boolean startTimer)
149{
150 ModelStateStruct *timerModelStruct = getModel(timerModel);
151 timerModelStruct->delayRunning = startTimer;
152
153 SerialDebug.printf("startStopTimer_mainModule(%d, %d)\n", startTimer, timerModelStruct->delaySeconds);
154
155}
156
157//!print it out..
159{
160//#define PRINT_THIS
161#ifdef PRINT_THIS
162 ModelKindEnum modelKind = deviceState->modelKindEnum;
163 switch (modelKind)
164 {
166 {
167
168 SerialTemp.print("deviceState->pairedDeviceStateEnum: ");
169 switch (deviceState->pairedDeviceStateEnum)
170 {
171 //paired to a device, but BLE NOT connected right now
173 SerialLots.println("pairedButNotConnectedEnum");
174 break;
175 //paired to a device, and BLE connected right now
177 SerialLots.println("pairedAndConnectedEnum");
178 break;
179 //not paired (but could be paired as it's a named device])
181 SerialLots.println("pairableAndConnectedEnum");
182 break;
183 //!factory default but not connecte to anything..
184 case notConnectedEnum:
185 SerialLots.println("notConnectedEnum");
186 break;
187 }
188 break;
189 }
190 case rebootModel:
191 {
192 SerialTemp.println("deviceState = rebootModel ");
193 }
194 break;
195 case menusModel:
196 {
197 //!MENUS
198 //! WIFI Feed
199 //! Advanced
200 //! Status
201 //! WIFI sharing
202 //! APMode
203 //! Guest Feed
204 //! Settings
205 //! Pairing
206 //! DocFollow
207 //! help
208 //! HomePage
209
210 SerialTemp.println("deviceState = menusModel ");
211 }
212 break;
213 case timerModel:
214 {
215 SerialTemp.println("deviceState = timerModel ");
216 }
217 break;
218 }
219 SerialTemp.printf("deviceState->maxItems (%d) \n", deviceState->maxItems );
220 SerialTemp.printf("deviceState->currentItem (%d) \n", deviceState->currentItem );
221#endif
222}
223
224
225//!retrieves the state model for the modelKind
227{
228 ModelStateStruct *model = &_modelStateStructs[modelKind];
229 SerialCall.printf("getModel(%d) = %d\n", modelKind, model);
230 printDeviceState(model);
231
232 return model;
233}
234
235//!retrieves the state model for the SM_Mode (SM_0 .. SM_LAST) null if none
237{
238 for (int i=0;i< ModelKindEnumMax;i++)
239 {
240 if (_modelStateStructs[i].SM_Mode == SM_Mode)
241 {
242 SerialCall.printf("hasModelForSM_Mode(%d) == yes\n", SM_Mode);
243
245 return &_modelStateStructs[i];
246 }
247 }
248 SerialCall.printf("hasModelForSM_Mode(%d) == NO\n", SM_Mode);
249
250 return NULL;
251}
252
253//!increments the device states deviceState (wrapping around)
255{
256 ModelStateStruct *deviceState = getModel(modelKind);
257
258
259 int item = deviceState->currentItem;
260 int max = deviceState->maxItems;
261 item = (item + 1) % max;
262 deviceState->currentItem = item;
263
264 SerialCall.printf("incrementMenuState(%d) = %d \n", modelKind, item);;
265
266}
267
268//!restarts all the menu states to the first one .. useful for getting a clean start. This doesn't care if the menu is being shown
270{
271 SerialDebug.println("restartAllMenuStates");
272 for (int i=0;i< ModelKindEnumMax;i++)
273 {
274 ModelKindEnum modelKind = (ModelKindEnum)i;
275 ModelStateStruct *deviceState = getModel(modelKind);
276 deviceState->currentItem = 0;
277 }
278}
279
280//!storage..
281//char _smMessage_ModelController[30];
282
283//!send the command to the stepper.. not a BLE command
285{
287}
288
289//!performs the BLE feed
291{
292 char _smMessage_ModelController[30];
293
294 ///feed always (done after the code below..)
296
297#ifdef USE_MQTT_NETWORKING
298 //!unfortunately, the incrementFeedCount() is AFTER the redrawSemanticMarker..
299 /// This sets the semantic marker .. which is current SM
300 sprintf(_smMessage_ModelController,"{'cmd':'%s'}",charSMMode_mainModule(getCurrentSMMode_mainModule()));
301 // processJSONMessageMQTT(charSMMode_mainModule(getCurrentSMMode_mainModule()), TOPIC_TO_SEND);
302 processJSONMessageMQTT(_smMessage_ModelController, TOPIC_TO_SEND);
303
304#endif
305}
306
307//! just unpair .. don't skip
308//!performs the unpairing
310{
313
314#ifdef NO_MORE_PREFERENCE_BLE_USE_DISCOVERED_PAIRED_DEVICE_SETTING
316#endif
317 //!also unset the main storage..
318 setConnectedBLEDevice_mainModule((char *)"",false);
319
320}
321//! just unpair .. don't skip
322//!performs the unpairing
324{
325 //!refactored base
327
328#ifdef USE_BLE_CLIENT_NETWORKING
330#endif
331}
332
333//!performs the unpairing
334void invokeUnpair_ModelController(char *nameOrAddress)
335{
336 //!refactored base
338
339#ifdef USE_BLE_CLIENT_NETWORKING
342#endif
343
344}
345//!performs the pairing.. to whatever is currently connected, this means a message could make that happen
346//!for a device (ESP-32) with no user interface.
348{
349 char *deviceName = connectedBLEDeviceName_mainModule();
350 char *deviceNameAddress = connectedBLEDeviceNameAddress_mainModule();
351 boolean isGEN3 = connectedBLEDeviceIsGEN3_mainModule();
352
353 SerialLots.printf("invokePair(%s, gen3=%d)\n", deviceName, isGEN3);
354
355 //TODO...
356
357 //!this is where it needs to know if GEN3. If so, then if their is a paired name .. If GEN3, don't overreight the device name
358 //!in case it was set by the user..
359 if (!isGEN3)
361
362 //! always set the ADDRESS
364
365 //!This means the name
366#ifdef NO_MORE_PREFERENCE_BLE_USE_DISCOVERED_PAIRED_DEVICE_SETTING
368#endif
369}
370
371//!performs skip
372void invokeSkip_ModelController(char *nameOrAddress)
373{
374#ifdef USE_BLE_CLIENT_NETWORKING
375
377
378 //TODO: look to see if the Address can be used to not connect right away to same one...
380#endif
381}
382
383//! toggles the GEN3 setting
385{
386 //!change GEN3 preference
388
389 //!if connected and not a GEN3 but want only GEN3 .. then disconnect, otherwise keep connected
391 {
392 SerialTemp.println(" *** GEN3 only but connected to a non GEN3 .. so unpair **");
393 //!also unpair..
395 }
396}
397
398
399//!updates the model for the menu state, this sets max etc
401{
402 ModelStateStruct *deviceState = getModel(modelKind);
403 SerialCall.printf("updateMenuState(%d) \n", modelKind);
404
405 switch (modelKind)
406 {
408 {
409 //! must save since many preferences are called...
410 char pairedDeviceString[50];
411 char pairedDeviceAddressString[50];
412 //* NEW PLAN..
413 //! the pairedName stored in EPROM can be an Address (eg. 03:34:23:33)
414 //!
415 //!show the BLE connected status at the bottom (G3 if gen3), WIFI, and AP if APmode
416#ifdef USE_BLE_CLIENT_NETWORKING
417 boolean isConnectedBLE = isConnectedBLEClient();
418#else
419 boolean isConnectedBLE = false;
420#endif
421 SerialLots.printf("\nPAIRED_DEVICE_MODEL\n");
422 SerialLots.printf("isConnectedBLE(%d)\n", isConnectedBLE);
423
425 if (gen3Only)
426 SerialLots.printf("gen3Only(%d)\n", gen3Only);
427
428 //! whether the gateway is on.. this isn't using the Gx just BLE or GE3
430 if (gatewayOn)
431 SerialLots.printf("gatewayOn(%d)\n", gatewayOn);
432
433 //! name of paired device (if any) in EPROM
434 char *pairedDeviceTemp = getPairedDevice_mainModule();
435 strcpy(pairedDeviceString, pairedDeviceTemp);
436 SerialLots.printf("pairedDevice(%s)\n", pairedDeviceString);
437
439 strcpy(pairedDeviceAddressString, pairedDeviceAddressTemp);
440
441 SerialLots.printf("pairedDeviceAddress(%s)\n", pairedDeviceAddressString);
442
443 //!name of connected device, or "" if not specified, which means not pairable
444 char *connectedBLEDeviceName = connectedBLEDeviceName_mainModule();
445 SerialLots.printf("connectedBLEDeviceName(%s)\n", connectedBLEDeviceName);
446 //!compare to what's connected ..
447 char *connectedBLEDeviceNameAddress = connectedBLEDeviceNameAddress_mainModule();
448 SerialLots.printf("connectedBLEDeviceNameAddress(%s)\n", connectedBLEDeviceNameAddress);
449
450 //!is paired and connected (to that pair .. if BLECLient working right)
451 boolean pairedAndConnected = false;
452 boolean pairedButNotConnected = false;
453 boolean pairableAndConnected = false;
454 boolean unpaired = false;
455
456 //!if connectedBLE then either paired or not-paired
457 if (isConnectedBLE)
458 {
459 //!if the EPROM's pairedDevice/Address == what's connected, then we are paired and connected
460 if (strcmp(pairedDeviceString,connectedBLEDeviceName)==0 ||
461 strcmp(pairedDeviceAddressString,connectedBLEDeviceNameAddress)==0)
462 //! is paired
463 pairedAndConnected = true;
464 else
465 pairableAndConnected = true;
466 }
467 //! not connected, so paired if a valid paired name/address
468 else if (strlen(pairedDeviceString) > 0 || strlen(pairedDeviceAddressString) > 0)
469 {
470 if (strlen(pairedDeviceString) > 0 && strcmp(pairedDeviceString,(char*)"NONE")==0)
471 unpaired = true;
472 else if (strlen(pairedDeviceAddressString) > 0 && strcmp(pairedDeviceAddressString,(char*)"NONE")==0)
473 unpaired = true;
474 else
475 //!if the EPROM's pairedDevice/Address is set then paired and NOT connected
476 pairedButNotConnected = true;
477 }
478 else
479 {
480 //!unpaired
481 unpaired = true;
482 }
483
484 if (pairedButNotConnected)
485 SerialLots.printf("pairedButNotConnected(%d)\n", pairedButNotConnected);
486 if (pairedAndConnected)
487 SerialLots.printf("pairedAndConnected(%d)\n", pairedAndConnected);
488 if (pairableAndConnected)
489 SerialLots.printf("pairableAndConnected(%d)\n", pairableAndConnected);
490 if (unpaired)
491 SerialLots.printf("unpaired(%d)\n", unpaired);
492
493 if (pairedButNotConnected)
494 {
495 // scan, unpair, gen3
497 deviceState->maxItems = 3;
498 }
499 else if (pairedAndConnected)
500 {
501 // feed, unPair, gen3
503 deviceState->maxItems = 3;
504 }
505 else if (pairableAndConnected)
506 {
507 // feed, skip, pair, gen3only
509 deviceState->maxItems = 4;
510 }
511 else
512 {
513 // scan, gen3Only
515 deviceState->maxItems = 2;
516 }
517
518 break;
519 }
520 case rebootModel:
521
522 //reboot and poweroff, blank, color, semanticMarker, wifiTOO, WIFI Page, next wave page, next wave stream..
523 // 9 = PTClicker, 10 == Uno, 11 = Tumbler
524 deviceState->maxItems = 12;
525 break;
526
527 case menusModel:
528 //!MENUS
529 //! Pairing
530 //! APMode
531 //! Timer
532 //! Advanced
533 //! Status
534 //! WIFI sharing
535 //! Guest Feed
536 //! Settings
537 //! DocFollow
538 //! help
539 //! HomePage
540 //! /WIFI Feed
541 //! WIFI Share
542
543 deviceState->maxItems = MenusModel_Max;
544 break;
545 //updateMenu
546 case timerModel:
547 {
548 SerialCall.printf("updateMenuState timer(%d)\n", deviceState->delayRunning);
549 //! calculate the current second counter..
550 if (deviceState->delayRunning)
551 {
552 //counter.., running
553 deviceState->maxItems = 2;
554
555 int currentTimeMillis = millis();
556 int delayMillisSeconds = deviceState->delaySeconds * 1000;
557
558 SerialCall.printf("updateMenuState(%d) \n", modelKind);
559 SerialCall.printf("secondsDelay = %d\n", deviceState->delaySeconds * 1000);
560 SerialCall.printf("currentAbsoluteTime = %d\n", currentTimeMillis);
561 SerialLots.printf("delayStartMillis = %d\n", deviceState->delayStartMillis);
562 SerialLots.printf("diffMillis = %d\n", currentTimeMillis - deviceState->delayStartMillis);
563
564 //!substract the seconds from the set delay
565 deviceState->currentCounterSeconds = deviceState->delaySeconds - (currentTimeMillis - deviceState->delayStartMillis)/1000;
566
567 SerialCall.printf("currentCounterSeconds = %d\n", deviceState->currentCounterSeconds);
568
569 //!if count <=0 then finished..
570 if (deviceState->currentCounterSeconds <= 0)
571 {
572 SerialDebug.printf("delayFinished \n");
573
574 deviceState->delayStartMillis = millis(); // start delay
575 deviceState->currentCounterSeconds = deviceState->delaySeconds;
576
577 //!if local .. send a command directly to the device..
578 if (deviceState->feedLocalOnly)
579 {
580 //!send the command to the stepper.. not a BLE command
582 }
583 else
584 {
585 //! for now only invoke the feed ... todo mroe things.. STATUS, WIFI FEED, DOCFOLLOW
587 }
588 }
589 }
590 else
591 {
592 //counter.., running, change time..
593 deviceState->maxItems = 3;
594 }
595 }
596
597
598 break;
599 }
600
601 //!TODO: look at a scrolling idea if > 6 ...
602 if (deviceState->currentItem >= deviceState->maxItems)
603 {
604 // go to first one .. basically the menues changed since last time
605 deviceState->currentItem = 0;
606 }
607 printDeviceState(deviceState);
608}
609
610//!returns the menu string for the deviceState's item number (use woudl go 0..maxItems -1
611char *menuForState(ModelKindEnum modelKind, int item)
612{
613 SerialCall.printf("menuForState(%d,%d)\n", modelKind, item);
614 ModelStateStruct *deviceState = getModel(modelKind);
615 SerialCall.printf("connectedBLEDeviceName_mainModule(%s)\n", connectedBLEDeviceName_mainModule());
616 SerialCall.printf("getFullBLEDeviceName_mainModule(%s)\n", getFullBLEDeviceName_mainModule());
617
618
619 char *menu;
620 switch (modelKind)
621 {
623 {
624 switch (deviceState->pairedDeviceStateEnum)
625 {
627 switch (item)
628 {
629 case 0:
630 menu = (char*)"scan..";
631 break;
632 case 1:
633 //unpair is to forget and look for others..
634 menu = (char*)"unpair";
635 break;
636 case 2:
638 menu = (char*)"Gen3";
639 else
640 menu = (char*)"AnyBLE";
641 break;
642 default:
643 SerialMin.printf("a.**** Invalid item: %d\n",item);
644 break;
645 }
646 break;
648 switch (item)
649 {
650 case 0:
651 menu = (char*)"feed";
652 break;
653 case 1:
654 menu = (char*)"unpair";
655 break;
656 case 2:
658 menu = (char*)"Gen3";
659 else
660 menu = (char*)"AnyBLE";
661 break;
662 default:
663 SerialMin.printf("b. **** Invalid item: %d\n",item);
664 break;
665 }
666 break;
668 switch (item)
669 {
670 case 0:
671 menu = (char*)"feed";
672 break;
673 case 1:
674 menu = (char*)"skip";
675 break;
676 case 2:
677 menu = (char*)"pair";
678 break;
679 case 3:
681 menu = (char*)"Gen3";
682 else
683 menu = (char*)"AnyBLE";
684 break;
685 default:
686 SerialMin.printf("c. **** Invalid item: %d\n",item);
687 break;
688 }
689 break;
690 case notConnectedEnum:
691 switch (item)
692 {
693 case 0:
694 menu = (char*)"scan..";
695 break;
696 case 1:
698 menu = (char*)"Gen3";
699 else
700 menu = (char*)"AnyBLE";
701 break;
702 default:
703 SerialMin.printf("d. **** Invalid item: %d\n",item);
704 break;
705 }
706 break;
707 }
708 }
709 break;
710 case rebootModel:
711 {
712 //Max for >4 items is 10 characters..
713 switch (item)
714 {
715 case 0:
716 menu = (char*)"reboot";
717 break;
718 case 1:
719 menu = (char*)"poweroff";
720 break;
721 case 2: // blankscreen
722 // poweroff.. but send MQTT first..
723 menu = (char*)"blankscrn";
724 break;
725
726 case 3: // Uno
727 menu = (char *)"Set Uno";
728 break;
729 case 4: //FeedKindTumbler
730 menu = (char *)"Tumbler";
731 break;
732
733 case 5: // change color
734 menu = (char*)"colorscrn";
735 break;
736 case 6: // SemanticMarker
737 menu = (char*)"SemMarker";
738 break;
739 case 7: // Extra sends
741 menu = (char*)"BLE+WIFI";
742 else
743 menu = (char*)"BLEOnly";
744 // .. switch to WIFI too
745 break;
746 case 8: // WIFI Change Page on M5 units..
747 menu = (char*)"CycleScrn";
748 // .. switch to WIFI too
749 break;
750 case 9: // WIFI chage wave page, evetually Wave-Page, Wave+Stream
751 menu = (char*)"Wave+Page";
752 // .. switch to WIFI too
753 break;
754 case 10: // WIFI chage wave page, evetually Wave-Page, Wave+Stream
755 menu = (char*)"Wave+Strm";
756 // .. switch to WIFI too
757 break;
758 case 11: // look for PTClicker
760 menu = (char*)"PTClicker";
761 else
762 menu = (char*)"PTFeeder";
763 break;
764
765 default:
766 SerialMin.printf("e. **** Invalid item: %d\n",item);
767 break;
768 }
769 }
770 break;
771
772 case menusModel:
773 {
774 //!MENUS
775 //! Pairing
776 //! APMode
777 //! Timer
778 //! Advanced
779 //! Status
780 //! WIFI sharing
781 //! Guest Feed
782 //! Settings
783 //! DocFollow
784 //! help
785 //! HomePage
786 //! /WIFI Feed
787 //! WIFI Share
788
789
790 switch (item)
791 {
793 menu = (char*)"BLEPair";
794 break;
796 menu = (char*)"APMode";
797 break;
799 menu = (char*)"WIFIShare";
800 break;
801 case MenusModel_Timer:
802 menu = (char*)"Timer";
803 break;
805 menu = (char*)"Advanced";
806 break;
808 menu = (char*)"Status";
809 break;
811 menu = (char*)"GuestPage";
812 break;
814 menu = (char*)"GuestFeed";
815 break;
817 menu = (char*)"Settings";
818 break;
820 menu = (char*)"DocFollow";
821 break;
822 case MenusModel_Help:
823 menu = (char*)"Help";
824 break;
825
826 default:
827 SerialMin.printf("f. **** Invalid item: %d\n",item);
828 break;
829 }
830 }
831 break;
832
833 //menuForState
834 case timerModel:
835 {
836 switch (item)
837 {
838
839 case 0:
840 //!draw the state we are in..
841 if (deviceState->delayRunning)
842 menu = (char*)"Stop";
843 else
844 menu = (char*) "Start";
845 break;
846 case 1:
847 {
848 //!update menu with seconds countdown
849 sprintf(_timerBuffer,"%d", deviceState->currentCounterSeconds);
850 menu = _timerBuffer;
851 }
852 break;
853 //! only if stopped...
854 case 2:
855 {
856
857 menu = (char*)"Delay";
858 }
859 break;
860 default:
861 SerialMin.printf("g. **** Invalid item: %d\n",item);
862 break;
863 }
864 }
865 break;
866 }
867 return menu;
868}
869
870//!invokes the menu state, return true if the model state has change enough to refreesh your View (such as new menu items)
871//!NOTE: This is the LONG press on the M5 button (the BLUE item)
873{
874 //!default is the view is the same
875 boolean modelChanged = false;
876 //!what model struct to use
877 ModelStateStruct *deviceState = getModel(modelKind);
878 SerialTemp.printf("invokeMenuState(%d, pair=%d) \n", modelKind, deviceState->pairedDeviceStateEnum);
879
880 int item = deviceState->currentItem;
881 switch (modelKind)
882 {
883 //! the pairdDeviceModel kind
885 {
886 SerialCall.printf("pairedDeviceModel");
887
888 switch (deviceState->pairedDeviceStateEnum)
889 {
890 //paired to a device, but BLE NOT connected right now
892 switch (item)
893 {
894 case 0:
895 //scan .. default
896 break;
897 case 1:
898 //unpair
900 modelChanged = true;
901 break;
902 case 2:
903 //toggle..
905 modelChanged = true;
906 break;
907 }
908 break;
909 //paired to a device, and BLE connected right now
911 switch (item)
912 {
913 case 0:
914 //feed
915 //send BLE feed ... this help figure out which BLE is connected
917 break;
918 case 1:
919 //unpair
921 modelChanged = true;
922 break;
923 case 2:
924 //toggle..
926 modelChanged = true;
927 break;
928 }
929 break;
930 //not paired (but could be paired as it's a named device or address])
932 switch (item)
933 {
934 case 0:
935 //feed
937 break;
938 case 1:
939 //skip
941 modelChanged = true;
942 break;
943 case 2:
944 // pair
946 modelChanged = true;
947 break;
948 case 3:
949 //toggle..
951 modelChanged = true;
952 break;
953 }
954 break;
955 //!factory default but not connecte to anything..
956 case notConnectedEnum:
957 switch (item)
958 {
959 case 0:
960 //scan
961 break;
962 case 1:
963 //toggle..
965 modelChanged = true;
966 break;
967 }
968 break;
969 }
970 }
971 break;
972
973 case rebootModel:
974 {
975 SerialCall.println("*** rebootModel ***");
976
977 switch (item)
978 {
979 case 0: // reboot
981 break;
982 case 1: // poweroff
983 // poweroff.. but send MQTT first..
985 break;
986 case 2: // blankscreen
988 break;
989 case 3: // Uno
990#ifdef USE_BLE_CLIENT_NETWORKING
992#endif
993 break;
994 case 4: //FeedKindTumbler
995#ifdef USE_BLE_CLIENT_NETWORKING
997#endif
998 break;
999
1000 case 5: //color
1001 //! for now, the color is incremented in the displayModule
1003 break;
1004 case 6: // SemanticMarker
1006 modelChanged = true;
1007 break;
1008 case 7: // extra..
1010 modelChanged = true;
1011 break;
1012 case 8:
1013 //send WIFI to all except this page.. but keep some state.
1014#ifdef USE_MQTT_NETWORKING
1015 //eg: https://iDogWatch.com/bot/cmddevice/tao49@comcast.net/PASS/dev/sm1
1016 //! BUT at the MQTT level not web page level
1017
1018 //!9.30.22 IF SET .. send a feed but to all devices except ours and our pair (if any)
1019 //! uses new wildcard syntax either ! OUR NAME [ & ! OUR_CONNECTED_NAME
1020 // if (getTransientPreference_mainModule(TRANSIENT_PREFERENCE_SENDWIFI_WITH_BLE))
1021 {
1022 char pubString[60];
1023 //for now .. just send smN
1024 sprintf(pubString,"{'dev':'!%s', 'cmd':'sm%0d'}",deviceName_mainModule(), deviceState->currentPageState);
1026 //incremenet model, wrap around
1027 deviceState->currentPageState = (deviceState->currentPageState +1 ) % deviceState->maxPageState;
1028 }
1029
1030#endif // USE_MQTT_NETWORKING
1031 break;
1032 case 9:
1033 // WIFI chage wave page
1034#ifdef USE_MQTT_NETWORKING
1035 //eg: https://iDogWatch.com/bot/cmddevice/tao49@comcast.net/PASS/dev/sm1
1036 //! BUT at the MQTT level not web page level
1037
1038 //!9.30.22 IF SET .. send a feed but to all devices except ours and our pair (if any)
1039 //! uses new wildcard syntax either ! OUR NAME [ & ! OUR_CONNECTED_NAME
1040 // if (getTransientPreference_mainModule(TRANSIENT_PREFERENCE_SENDWIFI_WITH_BLE))
1041 {
1042 char pubString[100];
1043 //for now .. just send 'next' on a common wave (TODO: select wave we are in..)'
1044 sprintf(pubString,(char*)"#followMe {AVM=https://SemanticMarker.org/bot/wave/%s?action=next}", deviceState->waveName);
1045 //! this has the # so it is treated slightly different, but tacking on the device for example..
1046 sendMessageMQTT(pubString);
1047
1048 }
1049
1050#endif // USE_MQTT_NETWORKING
1051 break;
1052 case 10:
1053 // WIFI change stream (1..3)
1054#ifdef USE_MQTT_NETWORKING
1055 //eg: https://iDogWatch.com/bot/cmddevice/tao49@comcast.net/PASS/dev/sm1
1056 //! BUT at the MQTT level not web page level
1057
1058 //!9.30.22 IF SET .. send a feed but to all devices except ours and our pair (if any)
1059 //! uses new wildcard syntax either ! OUR NAME [ & ! OUR_CONNECTED_NAME
1060 // if (getTransientPreference_mainModule(TRANSIENT_PREFERENCE_SENDWIFI_WITH_BLE))
1061 {
1062 char pubString[100];
1063 //for now .. just send 'next' on a common wave (TODO: select wave we are in..)'
1064 //! This just goes to the 0'th page in the stream..
1065 sprintf(pubString,(char*)"#followMe {AVM=https://SemanticMarker.org/bot/wave/%s?stream=%0d&page=0}", deviceState->waveName, deviceState->currentStreamNum+1);
1066 //! 1 based (not 0 based)
1067 //publishMQTTMessageDefaultTopic(pubString);
1068 //! this has the # so it is treated slightly different, but tacking on the device for example..
1069 sendMessageMQTT(pubString);
1070
1071 deviceState->currentStreamNum = (deviceState->currentStreamNum +1 ) % deviceState->maxStream;
1072 }
1073
1074#endif // USE_MQTT_NETWORKING
1075 break;
1076 case 11:
1077 //! set transient look for PTClicker
1079 break;
1080 //! 11.4.22 (after Maggie Bluetic was fed with Pumpking Uno and GreyGoose
1081
1082
1083 default:
1084 SerialMin.println("h, *** invalid item ***");
1085 }
1086 }
1087 break;
1088
1089 case menusModel:
1090 {
1091 modelChanged = true;
1092 SerialCall.println("*** menusModel ***");
1093 //!use lookup
1094 int SMMode = _menuToSMMode[item];
1095 // invoke that page (note now those pages return here on ButB_longpress)
1097
1098 //! Issue: #222 for #206, this sets the current mode to SM_doc_follow, but
1099 //! when at that page in the the current mode (which is now SM_doc_follow) won't let
1100 //! the page go somewhere else (except in this case we are the same page). Only but a
1101 //! physical button click.
1102 //! I THINK THE ANSWER: if current and next are the same an SM_doc_follow, then do the page change..
1103
1104 //! if HELP then printout preferences to the debug window
1105 if (SMMode == SM_help)
1106 //! if HELP .. show the status
1107 //!print the preferences to SerialDebug
1109 }
1110 break;
1111 case timerModel:
1112 {
1113 //invokeMenuState
1114 SerialCall.printf("*** timerModel *** %d\n", deviceState->delayRunning);
1115 switch (item)
1116 {
1117
1118 case 0:
1119 //start stop..
1120 deviceState->delayRunning = !deviceState->delayRunning;
1121
1122 if (deviceState->delayRunning)
1123 {
1124 deviceState->delayStartMillis = millis(); // start delay
1125 deviceState->currentCounterSeconds = deviceState->delaySeconds;
1126 }
1127 break;
1128 case 1:
1129 //menu = (char*)"TimerTBD";
1130 // how about reset ... to delay..
1131 if (deviceState->delayRunning)
1132 {
1133 deviceState->delayStartMillis = millis(); // start delay
1134 }
1135 //!reset to default
1136 deviceState->currentCounterSeconds = deviceState->delaySeconds;
1137
1138 break;
1139 case 2:
1140 {
1141 //menu = (char*)"Bounds"; .. change timer 5 .. 30 .. 60 .. 120 .. 5
1142 int currentDelay = deviceState->delaySeconds;
1143
1144 if (currentDelay == 5)
1145 currentDelay = 30;
1146 else if (currentDelay == 30)
1147 currentDelay = 60;
1148 else if (currentDelay == 60)
1149 currentDelay = 120;
1150 else if (currentDelay == 120)
1151 currentDelay = 600;
1152 else
1153 currentDelay = 5;
1154 SerialTemp.printf(".. change delay = %d\n", currentDelay);
1155 deviceState->delaySeconds = currentDelay;
1156 deviceState->currentCounterSeconds = deviceState->delaySeconds;
1157 //save in EPROM
1159 }
1160 break;
1161 default:
1162 SerialMin.println("i. *** invalid item ***");
1163 }
1164 break;
1165 }
1166 }
1167 return modelChanged;
1168}
1169
1170//!retrieves a semantic marker for the current selected item
1172{
1173 //!default is the view is the same
1174 boolean modelChanged = false;
1175 //!what model struct to use
1176 ModelStateStruct *deviceState = getModel(modelKind);
1177 SerialLots.printf("invokeMenuState(%d, %d) \n", modelKind, deviceState->pairedDeviceStateEnum);
1178
1179 char *semanticMarker = NULL;
1180
1181#ifdef NOTHING_YET_SAVE_SOME_MEMORY
1182 int item = deviceState->currentItem;
1183
1184 switch (modelKind)
1185 {
1186 case rebootModel:
1187 {
1188 switch (item)
1189 {
1190 case 0: // reboot
1191 //REboot the device
1192 //sprintf(_semanticMarkerString,"%s/%s/%s", "https://SemanticMarker.org/bot/reboot", _mqttUserString?_mqttUserString:"NULL", guestPassword?guestPassword:"NULL");
1193 break;
1194 case 1: // poweroff
1195 // poweroff.. but send MQTT first..
1196 break;
1197 case 2: // blankscreen
1198 break;
1199 case 3: //color
1200 //! for now, the color is incremented in the displayModule
1201 break;
1202 case 4: // SemanticMarker
1203 break;
1204 case 5: // none
1205 break;
1206 case 6: // next page .. actually there is one .. later
1207 break;
1208 case 7: // next page .. actually there is one .. later
1209 break;
1210 }
1211 }
1212 }
1213#endif
1214 return semanticMarker;
1215}
boolean isConnectedBLEClient()
returns whether connected over BLE as a client to a server(like a ESP feeder)
void disconnect_BLEClientNetworking()
try to disconnect..
void skipNameOrAddress_BLEClientNetworking(char *nameOrAddress)
an address or name to skip (for at least 1 time)
void sendCommandBLEClient_13orLess(String cmdString)
send a string of 13 characters or less
void incrementScreenColor_displayModule()
void publishMQTTMessageDefaultTopic(char *message)
Wrapper of the mqttclient publish.
void sendMessageMQTT(char *message)
boolean processJSONMessageMQTT(char *ascii, char *topic)
process the JSON message (looking for FEED, etc). Note: topic can be nil, or if not,...
void setConnectedBLEDevice_mainModule(char *deviceName, boolean isGEN3)
char * connectedBLEDeviceNameAddress_mainModule()
returns address part of name.
char * charSMMode_mainModule(int whichSMMode)
returns string form whichSMMode, sg "sm0", sm1 ...
char * deviceName_mainModule()
gets the device name
Definition: MainModule.cpp:607
boolean connectedBLEDeviceIsGEN3_mainModule()
whether the connected is a GEN3 (so the name isn't valid)
void processClientCommandChar_mainModule(char cmd)
single character version of processClientCommand (since many used that already)
int getCurrentSMMode_mainModule()
returns the current SM Mode
char * getFullBLEDeviceName_mainModule()
full: ""Name: PTFeeder:HowieFeeder, Address: 7c:9e:bd:48:af:92, serviceUUID: 0xdead"
void setCurrentSMMode_mainModule(int whichSMMode)
sets the current screen mode .. which can be used by Button and Display processing
char * getPairedDevice_mainModule()
returns if the paired device is not NONE
Definition: MainModule.cpp:557
void main_dispatchAsyncCommand(int asyncCallCommand)
checks if any async commands are in 'dispatch' mode, and if so, invokes them, and sets their flag to ...
Definition: MainModule.cpp:789
char * connectedBLEDeviceName_mainModule()
returns the connected BLE Device name (the :NAME of advertisment, Address: 01:39:3f:33 part of name,...
#define SM_pair_dev
guest feed device
Definition: MainModule.h:308
#define ASYNC_REBOOT
sets the GATEWAY mode off
Definition: MainModule.h:163
#define SM_guest_feed
guest feed
Definition: MainModule.h:306
#define SM_guest_page
guest page
Definition: MainModule.h:299
#define ASYNC_SEND_MQTT_FEED_MESSAGE
sends a message (like FEED) on the users topic
Definition: MainModule.h:153
#define SM_timer
timer .. todo
Definition: MainModule.h:315
#define SM_status
//status
Definition: MainModule.h:295
#define SM_reboot
REboot.
Definition: MainModule.h:317
#define MAX_SM_EXPANDED_MODES
Definition: MainModule.h:323
#define SM_help
HELP.
Definition: MainModule.h:310
#define ASYNC_POWEROFF
sets the GATEWAY mode off
Definition: MainModule.h:165
#define ASYNC_BLANKSCREEN
blank the screen
Definition: MainModule.h:167
#define SM_home_simple_3
Definition: MainModule.h:287
#define SM_doc_follow
docfollow
Definition: MainModule.h:313
#define SM_smart_clicker_homepage
//! homepage
Definition: MainModule.h:293
#define TOPIC_TO_SEND
Definition: MainModule.h:41
#define SM_WIFI_ssid
WIFI ssid.
Definition: MainModule.h:297
#define SM_ap_mode
AP MODE.
Definition: MainModule.h:302
void updateMenuState(ModelKindEnum modelKind)
updates the model for the menu state, this sets max etc
void invokeUnpairNoNameBASE_ModelController()
void incrementMenuState(ModelKindEnum modelKind)
increments the device states deviceState (wrapping around)
boolean invokeMenuState(ModelKindEnum modelKind)
invokes the menu state, return true if the model state has change enough to refreesh your View (such ...
void initMenuToSMMode()
init the mapping
void invokeUnpair_ModelController(char *nameOrAddress)
performs the unpairing
void invokeFeed_ModelController()
performs the BLE feed
void invokePair_ModelController()
#define MenusModel_WIFIShare
void setTimerDelaySeconds_mainModule(int delaySeconds)
void invokeSkip_ModelController(char *nameOrAddress)
performs skip
void printDeviceState(ModelStateStruct *deviceState)
print it out..
#define MenusModel_Help
a pseudo Class
void startStopTimer_mainModule(boolean startTimer)
#define MenusModel_Status
char _timerBuffer[10]
char * menuForState(ModelKindEnum modelKind, int item)
returns the menu string for the deviceState's item number (use woudl go 0..maxItems -1
#define MenusModel_DocFollow
#define MenusModel_GuestFeed
#define MenusModel_Settings
void invokeUnpairNoName_ModelController()
ModelStateStruct * hasModelForSM_Mode(int SM_Mode)
retrieves the state model for the SM_Mode (SM_0 .. SM_LAST) null if none
#define MenusModel_Max
#define MenusModel_Timer
#define MenusModel_Advanced
int _menuToSMMode[MenusModel_Max]
storage of mapping
char * getModelSemanticMarker(ModelKindEnum modelKind)
retrieves a semantic marker for the current selected item
ModelStateStruct * getModel(ModelKindEnum modelKind)
retrieves the state model for the modelKind
void initModelStructs_ModelController()
initialize the objects
void invokeFeedLocally()
storage..
#define MenusModel_APMode
#define MenusModel_GuestPage
#define MenusModel_Pairing
void invokeToggleGen3_ModelController()
toggles the GEN3 setting
void restartAllMenuStates_ModelController()
restarts all the menu states to the first one .. useful for getting a clean start....
ModelStateStruct _modelStateStructs[ModelKindEnumMax]
ModelKindEnum
a pseudo Class
@ menusModel
@ pairedDeviceModel
@ timerModel
@ rebootModel
@ pairedButNotConnectedEnum
@ notConnectedEnum
factory default but not connecte to anything..
@ pairableAndConnectedEnum
@ pairedAndConnectedEnum
#define ModelKindEnumMax
void savePreferenceInt_mainModule(int preferenceID, int val)
sets an int preference
boolean getDiscoverM5PTClicker()
get option
void savePreferenceBoolean_mainModule(int preferenceID, boolean flag)
save a boolean preference
void setDiscoverM5PTClicker(boolean flag)
boolean getPreferenceBoolean_mainModule(int preferenceID)
called to set a preference (which will be an identifier and a string, which can be converted to a num...
void togglePreferenceBoolean_mainModule(int preferenceID)
toggles a preference boolean
int getPreferenceInt_mainModule(int preferenceID)
called to set a preference (which will be an identifier and a string, which can be converted to a num...
char * getPreferenceString_mainModule(int preferenceID)
returns the preference but in it's own string buffer. As long as you use it before calling getPrefere...
void printPreferenceValues_mainModule()
print the preferences to SerialDebug
void savePreference_mainModule(int preferenceID, String preferenceValue)
called to set a preference (which will be an identifier and a string, which can be converted to a num...
#define PREFERENCE_PAIRED_DEVICE_ADDRESS_SETTING
the paired device for guest device feeding (6.6.22) .. but the Address 9.3.22
#define PREFERENCE_ONLY_GEN3_CONNECT_SETTING
if true, only BLEClient connect to GEN3 feeders..
#define PREFERENCE_SENDWIFI_WITH_BLE
sends the WIFI to all except current device if set
#define PREFERENCE_SEMANTIC_MARKER_ZOOMED_VALUE
Display preferences (SemanticMarker etc) - boolean.
#define PREFERENCE_PAIRED_DEVICE_SETTING
the paired device for guest device feeding (6.6.22)
#define PREFERENCE_BLE_USE_DISCOVERED_PAIRED_DEVICE_SETTING
#define PREFERENCE_MAIN_GATEWAY_VALUE
#define PREFERENCE_TIMER_INT_SETTING
the preference timer
the struct for the models. Since this isn't straight OO, we are overlaying information....
ModelKindEnum modelKindEnum
What kind of model.
int currentCounterSeconds
current seconds (<= delaySeconds)
int currentPageState
for the next page state 0..n
boolean feedLocalOnly
feed local instead of MQTT or BLE..
int currentItem
the current item
int currentStreamNum
the stream number
char * waveName
which wave
int SM_Mode
which SM mode 0.. SM_LAST
boolean perfersBigText
a preference to the View that big text is desired
unsigned long delayStartMillis
Timer info (placeholder)
PairedDeviceStateEnum pairedDeviceStateEnum
boolean delayRunning
true if still waiting for delay to finish
int delaySeconds
length of delay (changable..)
int maxItems
the number of items in the model