Open envy opened 6 years ago
Still Thinking...
What about that the order of elements on the webpage be just the ID, so they will show up in the same order you register them on the main application?
What do you mean with "buttons to callbacks"? Buttons to issue callbacks from the webui?
Yes! exactly +1
This is not easily possible. Callbacks can try to read data from the packet. So there are two options:
There already exists the possiblity to add buttons via feedback_register_action
. That way, arbitrary functions that don't take any arguments can be registered and are called on button press. I think this should be enough for now.
What about that the order of elements on the webpage be just the ID, so they will show up in the same order you register them on the main application?
They actually are displayed in the order they are registered, just grouped by type/category. Feedback items first, then assigned callbacks + callback assign form, then all config options and lastly the buttons. Order of items is registration order in their respective categories.
Hi
I made the following picture + code as an example of the idea to use the full library with webserver on other proyects like Tasmota. I know that for supporting this, some features should be added to the actual routines of the library, but I think that is going to solve #36, #37, #38, #14, #4.
These are just ideas and I would like to discuss them:
Idea on how it looks:
Idea on the code to be used on the main program to generate that configuration page:
// KNX WebPage Configuration
// -------------------------
// The order of the knx.***_register_*** code, is the order shown on the web page.
knx.config_register_WebPageTitle("KNX Configuration");
knx.config_register_Title("KNX Parameters");
knx.config_register_line();
knx.config_register_SubTitle("General");
// Names to be displayed on the Physical Address Object. So, translations can be done by the main program
knx.config_register_pa("Physical Address","Set");
// (optional) Set Physical KNX Address of the device
knx.physical_address_set(knx.PA_to_address(1, 1, 1));
knx.config_register_label("(must be unique on the KNX Network)");
knx.config_register_blankspace();
if (Settings.flag.knx_enabled) {
// On the feedback_register_action can be defined the names to display.
// knx_disable_pressed is a callback that uses enable_knx_id to call
// feedback_set_action and modify that feedback action
enable_knx_id = knx.feedback_register_action("KNX: Enabled", "Disable", knx_disable_pressed);
}
else {
enable_knx_id = knx.feedback_register_action("KNX: Disabled", "Enable", knx_enable_pressed);
}
knx.config_register_line();
knx.config_register_SubTitle("Send Data to Group Addresses");
// Register Group Addresses to Send Data to
Relay[0].status_ga_id = knx.config_register_ga("Relay 1 Status", &Relay[0].enabled, "Add"); // "Add" is the text on the Group Address button. True is the Enable/Disable of that Address
Relay[1].status_ga_id = knx.config_register_ga("Relay 2 Status", &Relay[1].enabled);
Relay[2].status_ga_id = knx.config_register_ga("Relay 3 Status", &Relay[2].enabled);
Relay[3].status_ga_id = knx.config_register_ga("Relay 4 Status", &Relay[3].enabled);
Button[0].status_ga_id = knx.config_register_ga("Button 1 Status", &Button[1].enabled);
Button[1].status_ga_id = knx.config_register_ga("Button 2 Status", &Button[2].enabled);
Button[2].status_ga_id = knx.config_register_ga("Button 3 Status", &Button[3].enabled);
Button[3].status_ga_id = knx.config_register_ga("Button 4 Status", &Button[4].enabled);
sensor_temp.ga_id = knx.config_register_ga("Temperature", true);
// (optional) Set Group Addresses to Send Data to
knx.config_set_ga(Relay[0].status_ga_id, knx.GA_to_address(2,2,1));
Relay[0].enabled = true;
knx.config_set_ga(sensor_temp.ga_id, knx.GA_to_address(4,1,1));
knx.config_register_blankspace();
label_test_send_Relay1 = "Relay 1 Status: " + Relay[0].state ? "ON" : "OFF";
knx.feedback_register_action(&label_test_send_Relay1, send_data, "Test Send"); // "Test Send" is the text of the button. label_test_send_Relay1 is going to be updated on void loop()
// all feedback action buttons are yellow as warning because they execute things
label_test_send_temp = "Temperature (°C): " + last_temp;
knx.feedback_register_action(&label_test_send_temp, send_data, "Test Send"); // "Test Send" is the text of the button. label_test_send_temp is going to be updated on void loop()
knx.config_register_blankspace();
Relay[0].update_rate_id = knx.config_register_int("Relay 1 Status Update rate (ms)", UPDATE_INTERVAL_RELAY, "Set"); // "Set" is the text on the button
sensor_temp.update_rate_id = knx.config_register_int("Relay 1 Status Update rate (ms)", UPDATE_INTERVAL, "Set"); // "Set" is the text on the button
knx.config_register_label("Set Update Rate to 0 ms for not sending regular updates.");
knx.config_register_label("Updates will be sent only for relay toggle or button press");
knx.config_register_line();
knx.config_register_SubTitle("Receive Data from Group Addresses");
// Register Group Addresses to Receive data from and execute callbacks
Relay[0].callback_id = knx.callback_register("Toggle Relay 1", relay_cb, &Relay[0], &Relay[0].enabled_cb, "Add");
Relay[1].callback_id = knx.callback_register("Toggle Relay 2", relay_cb, &Relay[1], &Relay[1].enabled_cb);
Relay[2].callback_id = knx.callback_register("Toggle Relay 3", relay_cb, &Relay[2], &Relay[2].enabled_cb);
Relay[3].callback_id = knx.callback_register("Toggle Relay 4", relay_cb, &Relay[3], &Relay[3].enabled_cb);
sensor_temp.callback_id = knx.callback_register("Reply Temperature", reply_temp_cb, &sensor_temp, &sensor_temp.enabled_cb);
// (Optional) Set Group Addresses to receive Data from
knx.callback_assign(Relay[0].callback_id, knx.GA_to_address(2,2,1));
Relay[0].enabled_cb = false; // Disabled GA. will not call the callback. Because it has a registered address is going to be shown on the page.
// Disabled GA shows the yellow enable button to activate again the use of the callback
knx.callback_assign(sensor_temp.callback_id, knx.GA_to_address(4,1,1));
sensor_temp.enabled_cb = true;
knx.config_register_blankspace();
label_test_action_Relay1 = "Toggle Relay 1 (Actual: " + Relay[0].state ? "ON)" : "OFF)";
knx.feedback_register_action(&label_test_action_Relay1, relay_cb_1, "Test Action"); // "Test Action" is the text of the button.
label_test_action_temp = "Reply Temperature (" + last_temp + " °C)";
knx.feedback_register_action(&label_test_action_temp, reply_temp_cb, "Test Action"); // "Test Action" is the text of the button. label_test_send_temp is going to be updated on void loop()
knx.config_register_line();
knx.feedback_register_custom_button("Save", KNXSaveSettings); // KNXSaveSettings is a subroutine on the main program. custom_button are yellow
knx.feedback_register_return_button("Return", "/"); // "/" is the address to return.
// END KNX WebPage Configuration
@envy,
What do you think of the above approach?
In which:
Everything is shown in the order where the functions xxxx_register_xxxx where used.
New functions:
knx.config_register_WebPageTitle("KNX Configuration");
<h2>
text: knx.config_register_Title("KNX Parameters");
<hr>
: knx.config_register_line();
<h4>
text: knx.config_register_SubTitle("General");
knx.config_register_pa("Physical Address","Set");
knx.config_register_label("(must be unique on the KNX Network)");
<br>
: knx.config_register_blankspace();
knx.feedback_register_return_button("Return", "/");
knx.feedback_register_custom_button("Save", KNXSaveSettings);
This one can be also a feedback_register_action ("", "Save", KNXSaveSettings)
, where the blank text means just the button without the label. :smile: Modification to functions:
knx.config_register_xxxxx have text for the button
feedback_register_action has text for the button knx.feedback_register_action("KNX: Enabled", "Disable", knx_disable_pressed);
knx.config_register_ga has text for the button and works like knx.callback_register that has a main object to choose actions and can set addresses. And below that, you see the already set ones.
So, knx.config_register_ga register a device parameter (->) to an address to write and, knx.callback_register register an address to receive (->) a comand
I currently don't have the time to take a look at this. I'll come back in 2-3 weeks.
Don't worry. I think I will simplify a little more this ideas and we can take a look at this later.
El 14 mar. 2018 18:17, "Nico Weichbrodt" notifications@github.com escribió:
I currently don't have the time to take a look at this. I'll come back in 2-3 weeks.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/envy/esp-knx-ip/issues/36#issuecomment-373177869, or mute the thread https://github.com/notifications/unsubscribe-auth/Ahw-h61_Mo2YbLZPX1yw3JCEripWCA_Vks5teYj1gaJpZM4SjTKI .
Hi @envy ,
First of all, thanks a lot for your time and patience! This library is really good. I'm using it a lot.
What do you think of this simpified approach (following graph):
With the translations done byknx.config_web_UI(config_webUI);
where config_webUI
is
typedef struct __config_webUI
{
const char *WebPageTitle;
const char *PhysAddrLabel;
const char *Set;
const char *Add;
const char *Delete;
} config_webUI_t;
So, the code for making that Webpage:
// Web Page Translations
#define D_CONFIGURE_KNX "Configure KNX"
#define D_KNX_PARAMETERS "KNX parameters"
#define D_KNX_GENERAL_CONFIG "General"
#define D_KNX_PHYSICAL_ADDRESS "Physical Address"
#define D_KNX_SET "Set"
#define D_KNX_ADD "Add"
#define D_DELETE "Delete"
#define D_REPLY "Reply"
#define D_KNX_PHYSICAL_ADDRESS_NOTE "(Must be unique on the KNX network)"
#define D_KNX_GROUP_ADDRESS_TO_WRITE "Group Addresses to Send Data to"
#define D_KNX_GROUP_ADDRESS_TO_READ "Group Addresses to Receive Data from"
#define D_KNX_PARAMETER_TO_SEND "Parameter to Send"
#define D_KNX_UPDATE_INTERVAL "Sensor Update Interval (sec)"
// Translations
config_webUI_t config_webUI = {
D_CONFIGURE_KNX,
D_KNX_PHYSICAL_ADDRESS,
D_KNX_SET,
D_KNX_ADD,
D_DELETE
};
// KNX WebPage Configuration
// -------------------------
// The order of the knx.***_register_*** code, is the order that is going to be shown on the web page.
// Translations
knx.config_web_UI(config_webUI);
knx.config_register_Title( D_KNX_PARAMETERS );
knx.config_register_line();
//Set Physical KNX Address of the device
knx.config_register_pa(); // to position physical address config at top of page
knx.physical_address_set(knx.PA_to_address(1, 1, 1));
knx.config_register_label( D_KNX_PHYSICAL_ADDRESS_NOTE );
knx.config_register_blankspace();
knx.feedback_register_action("KNX: " D_ON, knx_toggle_flag_enabled, D_STOP, nullptr, knx_status_enabled);
knx.feedback_register_action("KNX: " D_OFF, knx_toggle_flag_enabled, D_START, nullptr, knx_status_disabled);
knx.config_register_line();
knx.config_register_SubTitle( D_KNX_GROUP_ADDRESS_TO_WRITE );
// Register Group Addresses to Send Data to
for (int i = 0; i < Settings.knx_Registered_GA; ++i)
{
if (device_param[i].show)
{
device_param[i].id = knx.config_register_ga(String(device_param[i].name));
knx.config_set_ga(device_param[i].id, Settings.knx_GA_addr(i));
}
}
knx.config_register_blankspace();
update_rate_id = knx.config_register_int( D_KNX_UPDATE_INTERVAL , Settings.knx_update_rate);
knx.config_register_line();
knx.config_register_SubTitle( D_KNX_GROUP_ADDRESS_TO_READ );
// Register Group Addresses to Receive data from and execute callbacks
for (int i = 0; i < Settings.knx_Registered_CB; ++i)
{
if (device_param[i].show)
{
cb_conf_id = knx.callback_register( String( device_param_cb[i] ), action_cb, &device_param[i]);
//////buscar en la config el param para setearlo
//knx.callback_assign(ga_conf, Settings.knx_CB_addr(i));
if (i==0)
{
//knx.callback_assign(cb_conf_id, knx.GA_to_address(2,2,1));
}
}
}
knx.config_register_line();
knx.feedback_register_action("", KNXSaveSettings, D_SAVE); // Save Button
knx.feedback_register_action("", KNX_Return_button, D_CONFIGURATION); // return to previous configuration menu
// END KNX WebPage Configuration
So, as a summary, the modifications proposed are:
_Add web_uiconfig functions for:
Modifications to actual functions:
Add new functions:
So, what do you think?
Please, let me know where I can help you.
Made the PR #45, #46, #47 with the knx.config_web_UI
function and the modified feedback_action
function with the text label added parameter.
Yes! exactly :+1:
I'm still thinking on how to order.
But, I think, first of all, could be making everything centered on the page and be able of changing the order with an index or with the order you register them, like:
(1) Title of the page
(2) a Label (like Physical Address config) (3) Physical Address Config
(4) Separator (a line)
(5) Group Address to Write to (config_register_ga) (6) config_register_int (like the checkbox of the example - sending updates (ms)) (7) config_register_bool (like the checkbox of the example - sending updates (ms))
(8) Group Address to Read From (callback_register)
(9) Feedbacks (10) Actions (11) Links (12) Buttons
buttons can be configured to run a callback, so there is no need to config on esp-knx-ip-webserver.cpp the buttons REBOOT, EEPROM SAVE, EEPROM RESTORE, etc.
What do you think?