Correct way for multiple pages autoconnect #515
-
Hello, I would like to know your opinion on the correct way to create several pages with autoconnect. My application has several pages with different global variables to deal with in my cake. PAGE1, data1, data2 ...... I have always worked with the mqttRSSI_FS.ino example and it has worked well for me, but I don't want to continue loading parameters.json separately. I am now using the mqttRSSI.ino example but I would like to check that it is the correct way without uploading separate files. for now it works and I have not had to load the .json separately my reduced example:
#include <AutoConnect.h>
//.......
#include "PAGE1.h"
#include "PAGE2.h"
void setup() {
//.......
FlashFS.begin(FORMAT_ON_FAIL);
portal.config(acConfig);
portal.begin();
PAGE1_SETUP();
PAGE2_SETUP();
}
void loop() {
#ifdef ARDUINO_ARCH_ESP8266
MDNS.update();
#endif
portal.handleClient(); ////////////////////////////////// PORTAL PORTAL
Serial.println(DATA1); //PAGE1
Serial.println(DATA8); //PAGE2
}
/////////////////////////////// PAGE1.h
const char* PARAM_PAGE1 = "/page1.json";
const char* AUX_SETTING_PAGE1 = "/page1_setting";
const char* AUX_SAVE_PAGE1 = "/page1_save";
.static const char AUX_mqtt_setting1[] PROGMEM = R"raw(
[
{
"title": "PAGE1",
"uri": "/page1_setting",
"menu": true,
"element": [
{
"name": "style",
"type": "ACStyle",
"value": "label+input,label+select{position:sticky;left:120px;width:230px!important;box-sizing:border-box;}"
},
{
"name": "DATA1",
"type": "ACInput",
"value": "",
"placeholder": "Msql server",
"label": "DATA1"
},
// DATA2, DATA3, DATA4 ........
{
"name": "save",
"type": "ACSubmit",
"value": "Save&Start",
"uri": "/page1_save"
},
{
"name": "discard",
"type": "ACSubmit",
"value": "Discard",
"uri": "/"
}
]
},
{
"title": "PAGE 1 SAVE",
"uri": "/page1_save",
"menu": false,
"element": [
{
"name": "caption",
"type": "ACText",
"value": "<h4>Parameters saved OK:</h4>",
"style": "text-align:center;color:#2f4f4f;padding:5px;"
},
{
"name": "HOME",
"type": "ACSubmit",
"value": "HOME",
"uri": "/_ac"
},
{
"name": "Reset",
"type": "ACSubmit",
"value": "Reset Board",
"uri": "/_ac/reset"
}
]
}
]
)raw";
String DATA1; // DATA2, DATA3, DATA4 ........
void getParams1(AutoConnectAux& aux1) {
DATA1 = aux1[F("DATA1")].value;
DATA1.trim();
DATA2 = aux1[F("DATA2")].value;
DATA2.trim();
// ..........
}
String loadParams1(AutoConnectAux& aux1, PageArgument& args1) {
(void)(args1);
Serial.print(PARAM_FILE1);
File param1 = FlashFS.open(PARAM_PAGE1, "r");
if (param1) {
if (aux1.loadElement(param1)) {
getParams1(aux1);
Serial.println(" loaded");
} else
Serial.println(" failed to load");
param1.close();
} else
Serial.println(" open failed");
return String("");
}
String saveParams1(AutoConnectAux& aux1, PageArgument& args1) {
AutoConnectAux& page1_setting = *portal.aux(portal.where());
getParams1(page1_setting);
File param1 = FlashFS.open(PARAM_PAGE1, "w");
page1_setting.saveElement(param1, { "DATA1, DATA2, DATA3...." });
param1.close();
return String();
}
void PAGE1_SETUP() {
///////////////////////////// PAGE 1
if (portal.load(FPSTR(AUX_mqtt_setting1))) {
PageArgument args1;
AutoConnectAux& page1_setting = *portal.aux(AUX_SETTING_PAGE1);
loadParams1(page1_setting, args1);
portal.on(AUX_SETTING_PAGE1, loadParams1);
portal.on(AUX_SAVE_PAGE1, saveParams1);
} else
Serial.println("load error");
}
//////////////////////////////////// PAGE2.h
//.................... another way I imagine that using autoconnect elements but I can't get the data of the variables to be global or to be printed when restarting without hitting the save or read buttons. but in this last one I can't get the variables to be loaded from native when restarting, they are recorded but they are not printed in a loop without giving the load button first or saved. In short, there are always many paths and ways to get to the same point and I would like to know your opinion on the best way to make a program with many pages and variables. I am putting the pages as simple libraries for later use on demand page 1 msql thank you very much in advance for guiding me on the correct structure |
Beta Was this translation helpful? Give feedback.
Replies: 7 comments 20 replies
-
Hello @FRANAIRBUS, After all, I think you have found already the ideal structure.
That's exactly. The question we need to address is, "So how do we implement that?"
OK, let's try to implement ... and before we -- you and me -- do that, I want to make sure I understand what you mean by one of your mentions.
By FYI |
Beta Was this translation helpful? Give feedback.
-
@FRANAIRBUS Thank you for invitation. I joined to LH_AC_4RELE_HOMEKIT-SQL Repo. I have drawn the following simple diagram that combines your conception with my technical insights. It is still abstract and incomplete, but it will serve as a compass so that we do not lose sight of each other's goals. I have already started to implement this diagram. Its implementation defines and introduces several new concepts as follows:
I previously mentioned that an event-driven model would be suitable, but I am now convinced that Edge framework can be implemented with an event-loop model. I have a favor to ask you: as the Edge framework implementation progresses, we will need to refer to and review each other's code. Can I use your Thank you. |
Beta Was this translation helpful? Give feedback.
-
hahaha I don't know if he's criticizing me for better or for worse :) my programming knowledge is limited and self-taught for that reason I understand that they are not beautiful and I appreciate your time I am very happy that he understands my approach and that with his knowledge and that of the community we can improve. for that reason you have my consent to publish my repository with the changes you consider necessary. As it is an initial code, it has no comments and some words are in Spanish. I did it yesterday quickly so you could see it. My previous iot thermostat code, although functional, was crazy spaghetti, that's why I'm renewing it.
As for your scheme, I have to look at it better and translate certain words and sit down with a little more time, but I think I understand it and it is very close to what we are looking for. Thank you very much for your interest and a great honor for your publication. |
Beta Was this translation helpful? Give feedback.
-
hi @Hieromon Tell me what the next steps are, I will be happy to collaborate. a bright image. |
Beta Was this translation helpful? Give feedback.
-
wow nothing nothing seeing that structure doesn't worry me at all. understand that I don't have as much programming experience as I would like and sometimes I have trouble interpreting certain new words or concepts to realize ..... the main setup declares the pins as inputs or outputs and by means of state variables each program retrieves it and treats it int turn_on1 = 0;
int latest1 = 0;
int status1 = 0;
void LH_GLOBAL_SETUP(){
pinMode(PIN_SWITCH1, OUTPUT);
digitalWrite(PIN_SWITCH1, LOW);
pinMode(PIN_SWITCH2, OUTPUT);
digitalWrite(PIN_SWITCH2, LOW);
pinMode(PIN_SWITCH3, OUTPUT);
digitalWrite(PIN_SWITCH3, LOW);
pinMode(PIN_SWITCH4, OUTPUT);
digitalWrite(PIN_SWITCH4, LOW);
pinMode(BUTTON1, INPUT_PULLUP);
pinMode(BUTTON2, INPUT_PULLUP);
pinMode(BUTTON3, INPUT_PULLUP);
pinMode(BUTTON4, INPUT_PULLUP);
}
void LH_RELE_STATE(){
//RELE 1
status1 = digitalRead(BUTTON1);
if(status1 && latest1 == 0)
{
turn_on1 = 1 - turn_on1;
delay(500);
}
latest1 = status1;
if(turn_on1)
{
digitalWrite(PIN_SWITCH1, LOW);
//Serial.println ("RELE1_OFF");
}
else
{
digitalWrite(PIN_SWITCH1, HIGH);
//Serial.println ("RELE1_ON");
}
}
then state 1 same with the declaration of probes temperature1 This main setup will have a probe type change through autoconnect element and its respective void probe1 = dht1 : = t1 & h1 Or do you propose it in another way? good job @Hieromon |
Beta Was this translation helpful? Give feedback.
-
hello @Hieromon I am advancing in the program: but i found this... when i use an ACSelect this doesn't work void getParams_PROBES(AutoConnectAux& aux_PROBES) {
PROBETYPE1 = aux_PROBES[F("PROBETYPE1")].value;
PROBETYPE1.trim();
but this yes void getParams_PROBES(AutoConnectAux& aux_PROBES) {
//PROBETYPE1 = aux_PROBES[F("PROBETYPE1")].value;
//PROBETYPE1.trim();
AutoConnectSelect& acPROBETYPE1 = aux_PROBES["PROBETYPE1"].as<AutoConnectSelect>();
PROBETYPE1 = acPROBETYPE1.value();
CALT1 = aux_PROBES[F("CALT1")].value;
CALT1.trim();
CALH1 = aux_PROBES[F("CALH1")].value;
CALH1.trim();
So for ACImput I imagine each of the 2 works, which one should I use? AutoConnectImput& acCALT1 = aux_PROBES["CALT1"].as<AutoConnectImput>();
CALT1 = acCALT1.value;
CALT1 = aux_PROBES[F("CALT1")].value;
CALT1.trim();
my lack of knowledge does not let me see the difference Thank you |
Beta Was this translation helpful? Give feedback.
-
@FRANAIRBUS I pushed the EdgeUnified library. Visit EdgeUnified-eval repository. C++11 does not support modules like JavaScript or Python. it was implemented starting with C++20. Thus we cannot use the module syntax in the Espressif toolchain. I have provided an example using the namespace syntax, but this is not the proper usage of the C++ standard. If you are envisioning a module import like JavaScript or Python, that would be something to reconsider. Please consider it. So, the EdgeUnified-eval repository is available for Discussions. Please go there for matters that need to be discussed and submit issues to Issues. |
Beta Was this translation helpful? Give feedback.
@FRANAIRBUS I pushed the EdgeUnified library. Visit EdgeUnified-eval repository.
Documentation is inadequate and I am currently in the process of writing it up. In the meantime, please refer to the examples and consider how your sketch code fits in.
I have prepared two different split-source file structures that achieve the same functionality as MQTT-GPIO example. One is a partitioning model that conforms to the C++ standard. The other is the "#include LH_XXX.h" method you are envisioning. It is aware of your goal of "simply include existing sketches and assemble the necessary components".
C++11 does not support modules like JavaScript or Python. it was implemented starting with C++20. Th…