mirror of https://github.com/arendst/Tasmota.git
Update to new API version of ESP-KNX-IP
This commit is contained in:
parent
2ce8faec62
commit
83d6049fe5
|
@ -41,7 +41,9 @@ void ESPKNXIP::__handle_root()
|
|||
break;
|
||||
case FEEDBACK_TYPE_FLOAT:
|
||||
m += F("<span class='input-group-text'>");
|
||||
m += feedbacks[i].options.float_options.prefix;
|
||||
m += String(*(float *)feedbacks[i].data, feedbacks[i].options.float_options.precision);
|
||||
m += feedbacks[i].options.float_options.suffix;
|
||||
m += F("</span>");
|
||||
break;
|
||||
case FEEDBACK_TYPE_BOOL:
|
||||
|
@ -52,7 +54,9 @@ void ESPKNXIP::__handle_root()
|
|||
case FEEDBACK_TYPE_ACTION:
|
||||
m += F("<input class='form-control' type='hidden' name='id' value='");
|
||||
m += i;
|
||||
m += F("' /><div class='input-group-append'><button type='submit' class='btn btn-primary'>Do this</button></div>");
|
||||
m += F("' /><div class='input-group-append'><button type='submit' class='btn btn-primary'>");
|
||||
m += feedbacks[i].options.action_options.btn_text;
|
||||
m += F("</button></div>");
|
||||
break;
|
||||
}
|
||||
m += F("</div></div></div>");
|
||||
|
@ -67,6 +71,12 @@ void ESPKNXIP::__handle_root()
|
|||
{
|
||||
for (uint8_t i = 0; i < registered_callback_assignments; ++i)
|
||||
{
|
||||
// Skip empty slots
|
||||
if ((callback_assignments[i].slot_flags & SLOT_FLAGS_USED) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Skip disabled callbacks
|
||||
if (callbacks[callback_assignments[i].callback_id].cond && !callbacks[callback_assignments[i].callback_id].cond())
|
||||
{
|
||||
continue;
|
||||
|
@ -105,6 +115,12 @@ void ESPKNXIP::__handle_root()
|
|||
m += F("<select class='form-control' name='cb'>");
|
||||
for (callback_id_t i = 0; i < registered_callbacks; ++i)
|
||||
{
|
||||
// Skip empty slots
|
||||
if ((callbacks[i].slot_flags & SLOT_FLAGS_USED) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Skip disabled callbacks
|
||||
if (callbacks[i].cond && !callbacks[i].cond())
|
||||
{
|
||||
continue;
|
||||
|
@ -295,7 +311,7 @@ void ESPKNXIP::__handle_register()
|
|||
goto end;
|
||||
}
|
||||
|
||||
if (cb >= registered_callbacks)
|
||||
if (!__callback_is_id_valid(cb))
|
||||
{
|
||||
DEBUG_PRINTLN(F("Invalid callback id"));
|
||||
goto end;
|
||||
|
@ -319,7 +335,7 @@ void ESPKNXIP::__handle_delete()
|
|||
DEBUG_PRINT(id);
|
||||
DEBUG_PRINTLN(F(""));
|
||||
|
||||
if (id >= registered_callback_assignments)
|
||||
if (id >= registered_callback_assignments || (callback_assignments[id].slot_flags & SLOT_FLAGS_USED) == 0)
|
||||
{
|
||||
DEBUG_PRINTLN(F("ID wrong"));
|
||||
goto end;
|
||||
|
|
|
@ -6,7 +6,21 @@
|
|||
|
||||
#include "esp-knx-ip.h"
|
||||
|
||||
ESPKNXIP::ESPKNXIP() : server(nullptr), registered_callback_assignments(0), registered_callbacks(0), registered_configs(0), registered_feedbacks(0)
|
||||
char const *string_defaults[] =
|
||||
{
|
||||
"Do this",
|
||||
"True",
|
||||
"False",
|
||||
""
|
||||
};
|
||||
|
||||
ESPKNXIP::ESPKNXIP() : server(nullptr),
|
||||
registered_callback_assignments(0),
|
||||
free_callback_assignment_slots(0),
|
||||
registered_callbacks(0),
|
||||
free_callback_slots(0),
|
||||
registered_configs(0),
|
||||
registered_feedbacks(0)
|
||||
{
|
||||
DEBUG_PRINTLN();
|
||||
DEBUG_PRINTLN("ESPKNXIP starting up");
|
||||
|
@ -27,65 +41,65 @@ void ESPKNXIP::load()
|
|||
restore_from_eeprom();
|
||||
}
|
||||
|
||||
void ESPKNXIP::start(ESP8266WebServer *srv, bool espknxip_webpage)
|
||||
void ESPKNXIP::start(ESP8266WebServer *srv)
|
||||
{
|
||||
server = srv;
|
||||
if (espknxip_webpage) { __start_espknxip_webpage(); }
|
||||
__start();
|
||||
}
|
||||
|
||||
void ESPKNXIP::start()
|
||||
{
|
||||
server = new ESP8266WebServer(80);
|
||||
__start_espknxip_webpage();
|
||||
__start();
|
||||
}
|
||||
|
||||
void ESPKNXIP::__start_espknxip_webpage()
|
||||
{
|
||||
server->on(ROOT_PREFIX, [this](){
|
||||
__handle_root();
|
||||
});
|
||||
server->on(__ROOT_PATH, [this](){
|
||||
__handle_root();
|
||||
});
|
||||
server->on(__REGISTER_PATH, [this](){
|
||||
__handle_register();
|
||||
});
|
||||
server->on(__DELETE_PATH, [this](){
|
||||
__handle_delete();
|
||||
});
|
||||
server->on(__PHYS_PATH, [this](){
|
||||
__handle_set();
|
||||
});
|
||||
#if !DISABLE_EEPROM_BUTTONS
|
||||
server->on(__EEPROM_PATH, [this](){
|
||||
__handle_eeprom();
|
||||
});
|
||||
#endif
|
||||
server->on(__CONFIG_PATH, [this](){
|
||||
__handle_config();
|
||||
});
|
||||
server->on(__FEEDBACK_PATH, [this](){
|
||||
__handle_feedback();
|
||||
});
|
||||
#if !DISABLE_RESTORE_BUTTON
|
||||
server->on(__RESTORE_PATH, [this](){
|
||||
__handle_restore();
|
||||
});
|
||||
#endif
|
||||
#if !DISABLE_REBOOT_BUTTON
|
||||
server->on(__REBOOT_PATH, [this](){
|
||||
__handle_reboot();
|
||||
});
|
||||
#endif
|
||||
server->begin();
|
||||
}
|
||||
|
||||
void ESPKNXIP::__start()
|
||||
{
|
||||
if (server != nullptr)
|
||||
{
|
||||
server->on(ROOT_PREFIX, [this](){
|
||||
__handle_root();
|
||||
});
|
||||
server->on(__ROOT_PATH, [this](){
|
||||
__handle_root();
|
||||
});
|
||||
server->on(__REGISTER_PATH, [this](){
|
||||
__handle_register();
|
||||
});
|
||||
server->on(__DELETE_PATH, [this](){
|
||||
__handle_delete();
|
||||
});
|
||||
server->on(__PHYS_PATH, [this](){
|
||||
__handle_set();
|
||||
});
|
||||
#if !DISABLE_EEPROM_BUTTONS
|
||||
server->on(__EEPROM_PATH, [this](){
|
||||
__handle_eeprom();
|
||||
});
|
||||
#endif
|
||||
server->on(__CONFIG_PATH, [this](){
|
||||
__handle_config();
|
||||
});
|
||||
server->on(__FEEDBACK_PATH, [this](){
|
||||
__handle_feedback();
|
||||
});
|
||||
#if !DISABLE_RESTORE_BUTTON
|
||||
server->on(__RESTORE_PATH, [this](){
|
||||
__handle_restore();
|
||||
});
|
||||
#endif
|
||||
#if !DISABLE_REBOOT_BUTTON
|
||||
server->on(__REBOOT_PATH, [this](){
|
||||
__handle_reboot();
|
||||
});
|
||||
#endif
|
||||
server->begin();
|
||||
}
|
||||
|
||||
udp.listenMulticast(MULTICAST_IP, MULTICAST_PORT);
|
||||
udp.onPacket([this](AsyncUDPPacket &packet) { __loop_knx(packet); });
|
||||
udp.onPacket([this](AsyncUDPPacket &packet) {
|
||||
DEBUG_PRINTLN("got packet");
|
||||
__loop_knx(packet); });
|
||||
}
|
||||
|
||||
void ESPKNXIP::save_to_eeprom()
|
||||
|
@ -139,6 +153,26 @@ void ESPKNXIP::restore_from_eeprom()
|
|||
for (uint8_t i = 0; i < MAX_CALLBACK_ASSIGNMENTS; ++i)
|
||||
{
|
||||
EEPROM.get(address, callback_assignments[i].address);
|
||||
if (callback_assignments[i].address.value != 0)
|
||||
{
|
||||
// if address is not 0/0/0 then mark slot as used
|
||||
callback_assignments[i].slot_flags |= SLOT_FLAGS_USED;
|
||||
DEBUG_PRINTLN("used slot");
|
||||
}
|
||||
else
|
||||
{
|
||||
// if address is 0/0/0, then we found a free slot, yay!
|
||||
// however, only count those slots, if we have not reached registered_callback_assignments yet
|
||||
if (i < registered_callback_assignments)
|
||||
{
|
||||
DEBUG_PRINTLN("free slot before reaching registered_callback_assignments");
|
||||
free_callback_assignment_slots++;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_PRINTLN("free slot");
|
||||
}
|
||||
}
|
||||
address += sizeof(address_t);
|
||||
}
|
||||
for (uint8_t i = 0; i < MAX_CALLBACK_ASSIGNMENTS; ++i)
|
||||
|
@ -188,68 +222,106 @@ callback_assignment_id_t ESPKNXIP::__callback_register_assignment(address_t addr
|
|||
if (registered_callback_assignments >= MAX_CALLBACK_ASSIGNMENTS)
|
||||
return -1;
|
||||
|
||||
callback_assignment_id_t aid = registered_callback_assignments;
|
||||
if (free_callback_assignment_slots == 0)
|
||||
{
|
||||
callback_assignment_id_t aid = registered_callback_assignments;
|
||||
|
||||
callback_assignments[aid].address = address;
|
||||
callback_assignments[aid].callback_id = id;
|
||||
registered_callback_assignments++;
|
||||
callback_assignments[aid].slot_flags |= SLOT_FLAGS_USED;
|
||||
callback_assignments[aid].address = address;
|
||||
callback_assignments[aid].callback_id = id;
|
||||
registered_callback_assignments++;
|
||||
return aid;
|
||||
}
|
||||
else
|
||||
{
|
||||
// find the free slot
|
||||
for (callback_assignment_id_t aid = 0; aid < registered_callback_assignments; ++aid)
|
||||
{
|
||||
if (callback_assignments[aid].slot_flags & SLOT_FLAGS_USED)
|
||||
{
|
||||
// found a used slot
|
||||
continue;
|
||||
}
|
||||
// and now an empty one
|
||||
callback_assignments[aid].slot_flags |= SLOT_FLAGS_USED;
|
||||
callback_assignments[aid].address = address;
|
||||
callback_assignments[aid].callback_id = id;
|
||||
|
||||
DEBUG_PRINT("Assigned callback id >");
|
||||
DEBUG_PRINT(id);
|
||||
DEBUG_PRINT("/ga[");
|
||||
DEBUG_PRINT(address.ga.area);
|
||||
DEBUG_PRINT("/");
|
||||
DEBUG_PRINT(address.ga.line);
|
||||
DEBUG_PRINT("/");
|
||||
DEBUG_PRINT(address.ga.member);
|
||||
DEBUG_PRINTLN("]");
|
||||
|
||||
return aid;
|
||||
}
|
||||
|
||||
void ESPKNXIP::callback_delete_assignment(callback_assignment_id_t id)
|
||||
{
|
||||
__callback_delete_assignment(id);
|
||||
free_callback_assignment_slots--;
|
||||
return id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ESPKNXIP::__callback_delete_assignment(callback_assignment_id_t id)
|
||||
{
|
||||
if (id >= registered_callback_assignments)
|
||||
return;
|
||||
// TODO this can be optimized if we are deleting the last element
|
||||
// as then we can decrement registered_callback_assignments
|
||||
|
||||
uint32_t dest_offset = 0;
|
||||
uint32_t src_offset = 0;
|
||||
uint32_t len = 0;
|
||||
if (id == 0)
|
||||
// clear slot and mark it as empty
|
||||
callback_assignments[id].slot_flags = SLOT_FLAGS_EMPTY;
|
||||
callback_assignments[id].address.value = 0;
|
||||
callback_assignments[id].callback_id = 0;
|
||||
|
||||
if (id == registered_callback_assignments - 1)
|
||||
{
|
||||
// start of array, so delete first entry
|
||||
src_offset = 1;
|
||||
// registered_ga_callbacks will be 1 in case of only one entry
|
||||
// registered_ga_callbacks will be 2 in case of two entries, etc..
|
||||
// so only copy anything, if there is it at least more then one element
|
||||
len = (registered_callback_assignments - 1);
|
||||
}
|
||||
else if (id == registered_callback_assignments - 1)
|
||||
{
|
||||
// last element, don't do anything, simply decrement counter
|
||||
DEBUG_PRINTLN("last cba deleted");
|
||||
// If this is the last callback, we can delete it by decrementing registered_callbacks.
|
||||
registered_callback_assignments--;
|
||||
|
||||
// However, if the assignment before this slot are also empty, we can decrement even further
|
||||
// First check if this was also the first element
|
||||
if (id == 0)
|
||||
{
|
||||
DEBUG_PRINTLN("really last cba");
|
||||
// If this was the last, then we are done.
|
||||
return;
|
||||
}
|
||||
|
||||
id--;
|
||||
while(true)
|
||||
{
|
||||
DEBUG_PRINT("checking ");
|
||||
DEBUG_PRINTLN((int32_t)id);
|
||||
if ((callback_assignments[id].slot_flags & SLOT_FLAGS_USED) == 0)
|
||||
{
|
||||
DEBUG_PRINTLN("merged free slot");
|
||||
// Slot before is empty
|
||||
free_callback_assignment_slots--;
|
||||
registered_callback_assignments--;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_PRINTLN("aborted on used slot");
|
||||
// Slot is used, abort
|
||||
return;
|
||||
}
|
||||
id--;
|
||||
if (id == CALLBACK_ASSIGNMENT_ID_MAX)
|
||||
{
|
||||
DEBUG_PRINTLN("abort on wrap");
|
||||
// Wrap around, abort
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// somewhere in the middle
|
||||
// need to calc offsets
|
||||
|
||||
// skip all prev elements
|
||||
dest_offset = id; // id is equal to how many element are in front of it
|
||||
src_offset = dest_offset + 1; // start after the current element
|
||||
len = (registered_callback_assignments - 1 - id);
|
||||
DEBUG_PRINTLN("free slot created");
|
||||
// there is now one more free slot
|
||||
free_callback_assignment_slots++;
|
||||
}
|
||||
}
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
memmove(callback_assignments + dest_offset, callback_assignments + src_offset, len * sizeof(callback_assignment_t));
|
||||
}
|
||||
bool ESPKNXIP::__callback_is_id_valid(callback_id_t id)
|
||||
{
|
||||
if (id < registered_callbacks)
|
||||
return true;
|
||||
|
||||
registered_callback_assignments--;
|
||||
if (callbacks[id].slot_flags & SLOT_FLAGS_USED)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
callback_id_t ESPKNXIP::callback_register(String name, callback_fptr_t cb, void *arg, enable_condition_t cond)
|
||||
|
@ -257,68 +329,108 @@ callback_id_t ESPKNXIP::callback_register(String name, callback_fptr_t cb, void
|
|||
if (registered_callbacks >= MAX_CALLBACKS)
|
||||
return -1;
|
||||
|
||||
callback_id_t id = registered_callbacks;
|
||||
|
||||
callbacks[id].name = name;
|
||||
callbacks[id].fkt = cb;
|
||||
callbacks[id].cond = cond;
|
||||
callbacks[id].arg = arg;
|
||||
registered_callbacks++;
|
||||
|
||||
DEBUG_PRINT("Registered callback >");
|
||||
DEBUG_PRINT(name);
|
||||
DEBUG_PRINT("< @ ");
|
||||
DEBUG_PRINTLN(id);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void ESPKNXIP::callback_delete_register(callback_id_t id)
|
||||
{
|
||||
if (id >= registered_callbacks)
|
||||
return;
|
||||
|
||||
uint32_t dest_offset = 0;
|
||||
uint32_t src_offset = 0;
|
||||
uint32_t len = 0;
|
||||
if (id == 0)
|
||||
if (free_callback_slots == 0)
|
||||
{
|
||||
// start of array, so delete first entry
|
||||
src_offset = 1;
|
||||
// registered_ga_callbacks will be 1 in case of only one entry
|
||||
// registered_ga_callbacks will be 2 in case of two entries, etc..
|
||||
// so only copy anything, if there is it at least more then one element
|
||||
len = (registered_callbacks - 1);
|
||||
}
|
||||
else if (id == registered_callbacks - 1)
|
||||
{
|
||||
// last element, don't do anything, simply decrement counter
|
||||
callback_id_t id = registered_callbacks;
|
||||
|
||||
callbacks[id].slot_flags |= SLOT_FLAGS_USED;
|
||||
callbacks[id].name = name;
|
||||
callbacks[id].fkt = cb;
|
||||
callbacks[id].cond = cond;
|
||||
callbacks[id].arg = arg;
|
||||
registered_callbacks++;
|
||||
return id;
|
||||
}
|
||||
else
|
||||
{
|
||||
// somewhere in the middle
|
||||
// need to calc offsets
|
||||
// find the free slot
|
||||
for (callback_id_t id = 0; id < registered_callbacks; ++id)
|
||||
{
|
||||
if (callbacks[id].slot_flags & SLOT_FLAGS_USED)
|
||||
{
|
||||
// found a used slot
|
||||
continue;
|
||||
}
|
||||
// and now an empty one
|
||||
callbacks[id].slot_flags |= SLOT_FLAGS_USED;
|
||||
callbacks[id].name = name;
|
||||
callbacks[id].fkt = cb;
|
||||
callbacks[id].cond = cond;
|
||||
callbacks[id].arg = arg;
|
||||
|
||||
// skip all prev elements
|
||||
dest_offset = id; // id is equal to how many element are in front of it
|
||||
src_offset = dest_offset + 1; // start after the current element
|
||||
len = (registered_callbacks - 1 - id);
|
||||
free_callback_slots--;
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
memmove(callbacks + dest_offset, callbacks + src_offset, len * sizeof(callback_t));
|
||||
}
|
||||
|
||||
registered_callbacks--;
|
||||
}
|
||||
|
||||
void ESPKNXIP::callback_assign(callback_id_t id, address_t val)
|
||||
void ESPKNXIP::callback_deregister(callback_id_t id)
|
||||
{
|
||||
if (id >= registered_callbacks)
|
||||
if (!__callback_is_id_valid(id))
|
||||
return;
|
||||
|
||||
__callback_register_assignment(val, id);
|
||||
// clear slot and mark it as empty
|
||||
callbacks[id].slot_flags = SLOT_FLAGS_EMPTY;
|
||||
callbacks[id].fkt = nullptr;
|
||||
callbacks[id].cond = nullptr;
|
||||
callbacks[id].arg = nullptr;
|
||||
|
||||
if (id == registered_callbacks - 1)
|
||||
{
|
||||
// If this is the last callback, we can delete it by decrementing registered_callbacks.
|
||||
registered_callbacks--;
|
||||
|
||||
// However, if the callbacks before this slot are also empty, we can decrement even further
|
||||
// First check if this was also the first element
|
||||
if (id == 0)
|
||||
{
|
||||
// If this was the last, then we are done.
|
||||
return;
|
||||
}
|
||||
|
||||
id--;
|
||||
while(true)
|
||||
{
|
||||
if ((callbacks[id].slot_flags & SLOT_FLAGS_USED) == 0)
|
||||
{
|
||||
// Slot is empty
|
||||
free_callback_slots--;
|
||||
registered_callbacks--;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Slot is used, abort
|
||||
return;
|
||||
}
|
||||
id--;
|
||||
if (id == CALLBACK_ASSIGNMENT_ID_MAX)
|
||||
{
|
||||
// Wrap around, abort
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is now one more free slot
|
||||
free_callback_slots++;
|
||||
}
|
||||
}
|
||||
|
||||
callback_assignment_id_t ESPKNXIP::callback_assign(callback_id_t id, address_t val)
|
||||
{
|
||||
if (!__callback_is_id_valid(id))
|
||||
return -1;
|
||||
|
||||
return __callback_register_assignment(val, id);
|
||||
}
|
||||
|
||||
void ESPKNXIP::callback_unassign(callback_assignment_id_t id)
|
||||
{
|
||||
if (!__callback_is_id_valid(id))
|
||||
return;
|
||||
|
||||
__callback_delete_assignment(id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -342,7 +454,7 @@ feedback_id_t ESPKNXIP::feedback_register_int(String name, int32_t *value, enabl
|
|||
return id;
|
||||
}
|
||||
|
||||
feedback_id_t ESPKNXIP::feedback_register_float(String name, float *value, uint8_t precision, enable_condition_t cond)
|
||||
feedback_id_t ESPKNXIP::feedback_register_float(String name, float *value, uint8_t precision, char const *prefix, char const *suffix, enable_condition_t cond)
|
||||
{
|
||||
if (registered_feedbacks >= MAX_FEEDBACKS)
|
||||
return -1;
|
||||
|
@ -354,13 +466,15 @@ feedback_id_t ESPKNXIP::feedback_register_float(String name, float *value, uint8
|
|||
feedbacks[id].cond = cond;
|
||||
feedbacks[id].data = (void *)value;
|
||||
feedbacks[id].options.float_options.precision = precision;
|
||||
feedbacks[id].options.float_options.prefix = prefix ? strdup(prefix) : STRING_DEFAULT_EMPTY;
|
||||
feedbacks[id].options.float_options.suffix = suffix ? strdup(suffix) : STRING_DEFAULT_EMPTY;
|
||||
|
||||
registered_feedbacks++;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
feedback_id_t ESPKNXIP::feedback_register_bool(String name, bool *value, enable_condition_t cond)
|
||||
feedback_id_t ESPKNXIP::feedback_register_bool(String name, bool *value, char const *true_text, char const *false_text, enable_condition_t cond)
|
||||
{
|
||||
if (registered_feedbacks >= MAX_FEEDBACKS)
|
||||
return -1;
|
||||
|
@ -371,13 +485,15 @@ feedback_id_t ESPKNXIP::feedback_register_bool(String name, bool *value, enable_
|
|||
feedbacks[id].name = name;
|
||||
feedbacks[id].cond = cond;
|
||||
feedbacks[id].data = (void *)value;
|
||||
feedbacks[id].options.bool_options.true_text = true_text ? strdup(true_text) : STRING_DEFAULT_TRUE;
|
||||
feedbacks[id].options.bool_options.false_text = false_text ? strdup(false_text) : STRING_DEFAULT_FALSE;
|
||||
|
||||
registered_feedbacks++;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
feedback_id_t ESPKNXIP::feedback_register_action(String name, feedback_action_fptr_t value, void *arg, enable_condition_t cond)
|
||||
feedback_id_t ESPKNXIP::feedback_register_action(String name, feedback_action_fptr_t value, const char *btn_text, void *arg, enable_condition_t cond)
|
||||
{
|
||||
if (registered_feedbacks >= MAX_FEEDBACKS)
|
||||
return -1;
|
||||
|
@ -389,6 +505,7 @@ feedback_id_t ESPKNXIP::feedback_register_action(String name, feedback_action_fp
|
|||
feedbacks[id].cond = cond;
|
||||
feedbacks[id].data = (void *)value;
|
||||
feedbacks[id].options.action_options.arg = arg;
|
||||
feedbacks[id].options.action_options.btn_text = btn_text ? strdup(btn_text) : STRING_DEFAULT_DO_THIS;
|
||||
|
||||
registered_feedbacks++;
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
// Webserver related
|
||||
#define USE_BOOTSTRAP 1 // [Default 1] Set to 1 to enable use of bootstrap CSS for nicer webconfig. CSS is loaded from bootstrapcdn.com. Set to 0 to disable
|
||||
#define ROOT_PREFIX "/knx" // [Default ""] This gets prepended to all webserver paths, default is empty string "". Set this to "/knx" if you want the config to be available on http://<ip>/knx
|
||||
#define ROOT_PREFIX "" // [Default ""] This gets prepended to all webserver paths, default is empty string "". Set this to "/knx" if you want the config to be available on http://<ip>/knx
|
||||
#define DISABLE_EEPROM_BUTTONS 1 // [Default 0] Set to 1 to disable the EEPROM buttons in the web ui.
|
||||
#define DISABLE_REBOOT_BUTTON 1 // [Default 0] Set to 1 to disable the reboot button in the web ui.
|
||||
#define DISABLE_RESTORE_BUTTON 1 // [Default 0] Set to 1 to disable the "restore defaults" button in the web ui.
|
||||
|
@ -282,6 +282,12 @@ typedef enum __config_flags
|
|||
CONFIG_FLAGS_VALUE_SET = 1,
|
||||
} config_flags_t;
|
||||
|
||||
typedef enum __slot_flags
|
||||
{
|
||||
SLOT_FLAGS_EMPTY = 0, // Empty slots have no flags
|
||||
SLOT_FLAGS_USED = 1,
|
||||
} slot_flags_t;
|
||||
|
||||
typedef struct __message
|
||||
{
|
||||
knx_command_type_t ct;
|
||||
|
@ -295,13 +301,15 @@ typedef void (*callback_fptr_t)(message_t const &msg, void *arg);
|
|||
typedef void (*feedback_action_fptr_t)(void *arg);
|
||||
|
||||
typedef uint8_t callback_id_t;
|
||||
#define CALLBACK_ID_MAX UINT8_MAX
|
||||
typedef uint8_t callback_assignment_id_t;
|
||||
#define CALLBACK_ASSIGNMENT_ID_MAX UINT8_MAX
|
||||
typedef uint8_t config_id_t;
|
||||
typedef uint8_t feedback_id_t;
|
||||
|
||||
typedef struct __option_entry
|
||||
{
|
||||
char *name;
|
||||
char const *name;
|
||||
uint8_t value;
|
||||
} option_entry_t;
|
||||
|
||||
|
@ -317,14 +325,29 @@ typedef struct __config
|
|||
} data;
|
||||
} config_t;
|
||||
|
||||
extern char const *string_defaults[];
|
||||
#define STRING_DEFAULT_DO_THIS (string_defaults[0])
|
||||
#define STRING_DEFAULT_TRUE (string_defaults[1])
|
||||
#define STRING_DEFAULT_FALSE (string_defaults[2])
|
||||
#define STRING_DEFAULT_EMPTY (string_defaults[3])
|
||||
|
||||
typedef struct __feedback_float_options
|
||||
{
|
||||
uint8_t precision;
|
||||
char const *prefix;
|
||||
char const *suffix;
|
||||
} feedback_float_options_t;
|
||||
|
||||
typedef struct __feedback_bool_options
|
||||
{
|
||||
char const *true_text;
|
||||
char const *false_text;
|
||||
} feedback_bool_options_t;
|
||||
|
||||
typedef struct __feedback_action_options
|
||||
{
|
||||
void * arg;
|
||||
void *arg;
|
||||
char const *btn_text;
|
||||
} feedback_action_options_t;
|
||||
|
||||
typedef struct __feedback
|
||||
|
@ -334,6 +357,7 @@ typedef struct __feedback
|
|||
enable_condition_t cond;
|
||||
void *data;
|
||||
union {
|
||||
feedback_bool_options_t bool_options;
|
||||
feedback_float_options_t float_options;
|
||||
feedback_action_options_t action_options;
|
||||
} options;
|
||||
|
@ -341,6 +365,7 @@ typedef struct __feedback
|
|||
|
||||
typedef struct __callback
|
||||
{
|
||||
uint8_t slot_flags;
|
||||
callback_fptr_t fkt;
|
||||
enable_condition_t cond;
|
||||
void *arg;
|
||||
|
@ -349,6 +374,7 @@ typedef struct __callback
|
|||
|
||||
typedef struct __callback_assignment
|
||||
{
|
||||
uint8_t slot_flags;
|
||||
address_t address;
|
||||
callback_id_t callback_id;
|
||||
} callback_assignment_t;
|
||||
|
@ -358,45 +384,44 @@ class ESPKNXIP {
|
|||
ESPKNXIP();
|
||||
void load();
|
||||
void start();
|
||||
void start(ESP8266WebServer *srv, bool espknxip_webpage = true);
|
||||
void start(ESP8266WebServer *srv);
|
||||
void loop();
|
||||
|
||||
void save_to_eeprom();
|
||||
void restore_from_eeprom();
|
||||
|
||||
callback_id_t callback_register(String name, callback_fptr_t cb, void *arg = nullptr, enable_condition_t cond = nullptr);
|
||||
void callback_assign(callback_id_t id, address_t val);
|
||||
callback_id_t callback_register(String name, callback_fptr_t cb, void *arg = nullptr, enable_condition_t cond = nullptr);
|
||||
callback_assignment_id_t callback_assign(callback_id_t id, address_t val);
|
||||
void callback_deregister(callback_id_t id);
|
||||
void callback_unassign(callback_assignment_id_t id);
|
||||
|
||||
void callback_delete_register(callback_id_t id);
|
||||
void callback_delete_assignment(callback_assignment_id_t id);
|
||||
|
||||
void physical_address_set(address_t const &addr);
|
||||
address_t physical_address_get();
|
||||
void physical_address_set(address_t const &addr);
|
||||
address_t physical_address_get();
|
||||
|
||||
// Configuration functions
|
||||
config_id_t config_register_string(String name, uint8_t len, String _default, enable_condition_t cond = nullptr);
|
||||
config_id_t config_register_int(String name, int32_t _default, enable_condition_t cond = nullptr);
|
||||
config_id_t config_register_bool(String name, bool _default, enable_condition_t cond = nullptr);
|
||||
config_id_t config_register_options(String name, option_entry_t *options, uint8_t _default, enable_condition_t cond = nullptr);
|
||||
config_id_t config_register_ga(String name, enable_condition_t cond = nullptr);
|
||||
config_id_t config_register_string(String name, uint8_t len, String _default, enable_condition_t cond = nullptr);
|
||||
config_id_t config_register_int(String name, int32_t _default, enable_condition_t cond = nullptr);
|
||||
config_id_t config_register_bool(String name, bool _default, enable_condition_t cond = nullptr);
|
||||
config_id_t config_register_options(String name, option_entry_t *options, uint8_t _default, enable_condition_t cond = nullptr);
|
||||
config_id_t config_register_ga(String name, enable_condition_t cond = nullptr);
|
||||
|
||||
String config_get_string(config_id_t id);
|
||||
int32_t config_get_int(config_id_t id);
|
||||
bool config_get_bool(config_id_t id);
|
||||
uint8_t config_get_options(config_id_t id);
|
||||
address_t config_get_ga(config_id_t id);
|
||||
String config_get_string(config_id_t id);
|
||||
int32_t config_get_int(config_id_t id);
|
||||
bool config_get_bool(config_id_t id);
|
||||
uint8_t config_get_options(config_id_t id);
|
||||
address_t config_get_ga(config_id_t id);
|
||||
|
||||
void config_set_string(config_id_t id, String val);
|
||||
void config_set_int(config_id_t id, int32_t val);
|
||||
void config_set_bool(config_id_t, bool val);
|
||||
void config_set_options(config_id_t id, uint8_t val);
|
||||
void config_set_ga(config_id_t id, address_t const &val);
|
||||
void config_set_string(config_id_t id, String val);
|
||||
void config_set_int(config_id_t id, int32_t val);
|
||||
void config_set_bool(config_id_t, bool val);
|
||||
void config_set_options(config_id_t id, uint8_t val);
|
||||
void config_set_ga(config_id_t id, address_t const &val);
|
||||
|
||||
// Feedback functions
|
||||
feedback_id_t feedback_register_int(String name, int32_t *value, enable_condition_t cond = nullptr);
|
||||
feedback_id_t feedback_register_float(String name, float *value, uint8_t precision = 2, enable_condition_t cond = nullptr);
|
||||
feedback_id_t feedback_register_bool(String name, bool *value, enable_condition_t cond = nullptr);
|
||||
feedback_id_t feedback_register_action(String name, feedback_action_fptr_t value, void *arg = nullptr, enable_condition_t = nullptr);
|
||||
feedback_id_t feedback_register_int(String name, int32_t *value, enable_condition_t cond = nullptr);
|
||||
feedback_id_t feedback_register_float(String name, float *value, uint8_t precision = 2, char const *prefix = nullptr, char const *suffix = nullptr, enable_condition_t cond = nullptr);
|
||||
feedback_id_t feedback_register_bool(String name, bool *value, char const *true_text = nullptr, char const *false_text = nullptr, enable_condition_t cond = nullptr);
|
||||
feedback_id_t feedback_register_action(String name, feedback_action_fptr_t value, char const *btn_text = nullptr, void *arg = nullptr, enable_condition_t = nullptr);
|
||||
|
||||
// Send functions
|
||||
void send(address_t const &receiver, knx_command_type_t ct, uint8_t data_len, uint8_t *data);
|
||||
|
@ -484,7 +509,6 @@ class ESPKNXIP {
|
|||
|
||||
private:
|
||||
void __start();
|
||||
void __start_espknxip_webpage();
|
||||
void __loop_knx(AsyncUDPPacket &packet);
|
||||
|
||||
// Webserver functions
|
||||
|
@ -513,6 +537,8 @@ class ESPKNXIP {
|
|||
void __config_set_options(config_id_t id, uint8_t val);
|
||||
void __config_set_ga(config_id_t id, address_t const &val);
|
||||
|
||||
bool __callback_is_id_valid(callback_id_t id);
|
||||
|
||||
callback_assignment_id_t __callback_register_assignment(address_t address, callback_id_t id);
|
||||
void __callback_delete_assignment(callback_assignment_id_t id);
|
||||
|
||||
|
@ -521,9 +547,11 @@ class ESPKNXIP {
|
|||
AsyncUDP udp;
|
||||
|
||||
callback_assignment_id_t registered_callback_assignments;
|
||||
callback_assignment_id_t free_callback_assignment_slots;
|
||||
callback_assignment_t callback_assignments[MAX_CALLBACK_ASSIGNMENTS];
|
||||
|
||||
callback_id_t registered_callbacks;
|
||||
callback_id_t free_callback_slots;
|
||||
callback_t callbacks[MAX_CALLBACKS];
|
||||
|
||||
config_id_t registered_configs;
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
# datatypes
|
||||
address_t DATA_TYPE
|
||||
message_t DATA_TYPE
|
||||
callback_id_t DATA_TYPE
|
||||
callback_assignment_id_t DATA_TYPE
|
||||
option_entry_t DATA_TYPE
|
||||
config_id_t DATA_TYPE
|
||||
enable_condition_t DATA_TYPE
|
||||
callback_fptr_t DATA_TYPE
|
||||
feedback_action_fptr_t DATA_TYPE
|
||||
knx_command_type_t DATA_TYPE
|
||||
|
||||
# methods
|
||||
|
@ -14,18 +17,25 @@ GA_to_address KEYWORD2
|
|||
PA_to_address KEYWORD2
|
||||
callback_register KEYWORD2
|
||||
callback_assign KEYWORD2
|
||||
callback_deregister KEYWORD2
|
||||
callback_unassign KEYWORD2
|
||||
physical_address_set KEYWORD2
|
||||
physical_address_get KEYWORD2
|
||||
config_register_string KEYWORD2
|
||||
config_register_int KEYWORD2
|
||||
config_register_ga KEYWORD2
|
||||
config_register_bool KEYWORD2
|
||||
config_register_options KEYWORD2
|
||||
config_register_ga KEYWORD2
|
||||
config_get_string KEYWORD2
|
||||
config_get_int KEYWORD2
|
||||
config_get_ga KEYWORD2
|
||||
config_get_bool KEYWORD2
|
||||
config_get_options KEYWORD2
|
||||
config_get_ga KEYWORD2
|
||||
config_set_string KEYWORD2
|
||||
config_set_int KEYWORD2
|
||||
config_set_ga KEYWORD2
|
||||
config_set_bool KEYWORD2
|
||||
config_set_options KEYWORD2
|
||||
config_set_ga KEYWORD2
|
||||
feedback_register_int KEYWORD2
|
||||
feedback_register_float KEYWORD2
|
||||
feedback_register_bool KEYWORD2
|
||||
|
|
Loading…
Reference in New Issue