/** * esp-knx-ip library for KNX/IP communication on an ESP8266 * Author: Nico Weichbrodt * License: MIT */ #include "esp-knx-ip.h" void ESPKNXIP::__handle_root() { String m = F(""); #if USE_BOOTSTRAP m += F(""); m += F(""); #endif m += F("
"); m += F("

ESP KNX

"); // Feedback if (registered_feedbacks > 0) { m += F("

Feedback

"); for (feedback_id_t i = 0; i < registered_feedbacks; ++i) { if (feedbacks[i].cond && !feedbacks[i].cond()) { continue; } m += F("
"); m += F("
"); m += F("
"); m += feedbacks[i].name; m += F("
"); switch (feedbacks[i].type) { case FEEDBACK_TYPE_INT: m += F(""); m += String(*(int32_t *)feedbacks[i].data); m += F(""); break; case FEEDBACK_TYPE_FLOAT: m += F(""); 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(""); break; case FEEDBACK_TYPE_BOOL: m += F(""); m += (*(bool *)feedbacks[i].data) ? F("True") : F("False"); m += F(""); break; case FEEDBACK_TYPE_ACTION: m += F("
"); break; } m += F("
"); m += F("
"); } } if (registered_callbacks > 0) m += F("

Callbacks

"); if (registered_callback_assignments > 0) { 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; } address_t &addr = callback_assignments[i].address; m += F("
"); m += F("
"); m += F("
"); m += addr.ga.area; m += F("/"); m += addr.ga.line; m += F("/"); m += addr.ga.member; m += F(""); m += F(""); m += callbacks[callback_assignments[i].callback_id].name; m += F("
"); m += F("
"); m += F("
"); m += F("
"); } } if (registered_callbacks > 0) { m += F("
"); m += F("
"); m += F(""); m += F("
/
"); m += F(""); m += F("
/
"); m += F(""); m += F("
->
"); m += F(""); m += F("
"); m += F("
"); m += F("
"); } m += F("

Configuration

"); // Physical address m += F("
"); m += F("
"); m += F("
Physical address
"); m += F(""); m += F("
.
"); m += F(""); m += F("
.
"); m += F(""); m += F("
"); m += F("
"); m += F("
"); if (registered_configs > 0) { for (config_id_t i = 0; i < registered_configs; ++i) { // Check if this config option has a enable condition and if so check that condition if (custom_configs[i].cond && !custom_configs[i].cond()) continue; m += F("
"); m += F("
"); m += F("
"); m += custom_configs[i].name; m += F("
"); switch (custom_configs[i].type) { case CONFIG_TYPE_STRING: m += F(""); break; case CONFIG_TYPE_INT: m += F(""); break; case CONFIG_TYPE_BOOL: m += F("
"); m += F(""); m += F("
"); break; case CONFIG_TYPE_OPTIONS: { m += F(""); break; } case CONFIG_TYPE_GA: address_t a = config_get_ga(i); m += F(""); m += F("
/
"); m += F(""); m += F("
/
"); m += F(""); break; } m += F(""); m += F("
"); m += F("
"); m += F("
"); } } #if !(DISABLE_EEPROM_BUTTONS && DISABLE_RESTORE_BUTTON && DISABLE_REBOOT_BUTTON) // EEPROM save and restore m += F("
"); // Save to EEPROM #if !DISABLE_EEPROM_BUTTONS m += F("
"); m += F("
"); m += F(""); m += F(""); m += F("
"); m += F("
"); // Restore from EEPROM m += F("
"); m += F("
"); m += F(""); m += F(""); m += F("
"); m += F("
"); #endif #if !DISABLE_RESTORE_BUTTON // Load Defaults m += F("
"); m += F("
"); m += F(""); m += F("
"); m += F("
"); #endif #if !DISABLE_REBOOT_BUTTON // Reboot m += F("
"); m += F("
"); m += F(""); m += F("
"); m += F("
"); #endif m += F("
"); // row #endif // End of page m += F("
"); server->send(200, F("text/html"), m); } void ESPKNXIP::__handle_register() { DEBUG_PRINTLN(F("Register called")); if (server->hasArg(F("area")) && server->hasArg(F("line")) && server->hasArg(F("member")) && server->hasArg(F("cb"))) { uint8_t area = server->arg(F("area")).toInt(); uint8_t line = server->arg(F("line")).toInt(); uint8_t member = server->arg(F("member")).toInt(); callback_id_t cb = (callback_id_t)server->arg(F("cb")).toInt(); DEBUG_PRINT(F("Got args: ")); DEBUG_PRINT(area); DEBUG_PRINT(F("/")); DEBUG_PRINT(line); DEBUG_PRINT(F("/")); DEBUG_PRINT(member); DEBUG_PRINT(F("/")); DEBUG_PRINT(cb); DEBUG_PRINTLN(F("")); if (area > 31 || line > 7) { DEBUG_PRINTLN(F("Area or Line wrong")); goto end; } if (!__callback_is_id_valid(cb)) { DEBUG_PRINTLN(F("Invalid callback id")); goto end; } address_t ga = {.ga={line, area, member}}; __callback_register_assignment(ga, cb); } end: server->sendHeader(F("Location"),F(__ROOT_PATH)); server->send(302); } void ESPKNXIP::__handle_delete() { DEBUG_PRINTLN(F("Delete called")); if (server->hasArg(F("id"))) { callback_assignment_id_t id = (callback_assignment_id_t)server->arg(F("id")).toInt(); DEBUG_PRINT(F("Got args: ")); DEBUG_PRINT(id); DEBUG_PRINTLN(F("")); if (id >= registered_callback_assignments || (callback_assignments[id].slot_flags & SLOT_FLAGS_USED) == 0) { DEBUG_PRINTLN(F("ID wrong")); goto end; } __callback_delete_assignment(id); } end: server->sendHeader(F("Location"),F(__ROOT_PATH)); server->send(302); } void ESPKNXIP::__handle_set() { DEBUG_PRINTLN(F("Set called")); if (server->hasArg(F("area")) && server->hasArg(F("line")) && server->hasArg(F("member"))) { uint8_t area = server->arg(F("area")).toInt(); uint8_t line = server->arg(F("line")).toInt(); uint8_t member = server->arg(F("member")).toInt(); DEBUG_PRINT(F("Got args: ")); DEBUG_PRINT(area); DEBUG_PRINT(F(".")); DEBUG_PRINT(line); DEBUG_PRINT(F(".")); DEBUG_PRINT(member); DEBUG_PRINTLN(F("")); if (area > 31 || line > 7) { DEBUG_PRINTLN(F("Area or Line wrong")); goto end; } physaddr.bytes.high = (area << 4) | line; physaddr.bytes.low = member; } end: server->sendHeader(F("Location"),F(__ROOT_PATH)); server->send(302); } void ESPKNXIP::__handle_config() { DEBUG_PRINTLN(F("Config called")); if (server->hasArg(F("id"))) { config_id_t id = server->arg(F("id")).toInt(); DEBUG_PRINT(F("Got args: ")); DEBUG_PRINT(id); DEBUG_PRINTLN(F("")); if (id < 0 || id >= registered_configs) { DEBUG_PRINTLN(F("ID wrong")); goto end; } switch (custom_configs[id].type) { case CONFIG_TYPE_STRING: { String v = server->arg(F("value")); if (v.length() >= custom_configs[id].len) goto end; __config_set_flags(id, CONFIG_FLAGS_VALUE_SET); __config_set_string(id, v); break; } case CONFIG_TYPE_INT: { __config_set_flags(id, CONFIG_FLAGS_VALUE_SET); __config_set_int(id, server->arg(F("value")).toInt()); break; } case CONFIG_TYPE_BOOL: { __config_set_flags(id, CONFIG_FLAGS_VALUE_SET); __config_set_bool(id, server->arg(F("value")).compareTo(F("on")) == 0); break; } case CONFIG_TYPE_OPTIONS: { uint8_t val = (uint8_t)server->arg(F("value")).toInt(); DEBUG_PRINT(F("Value: ")); DEBUG_PRINTLN(val); config_set_options(id, val); break; } case CONFIG_TYPE_GA: { uint8_t area = server->arg(F("area")).toInt(); uint8_t line = server->arg(F("line")).toInt(); uint8_t member = server->arg(F("member")).toInt(); if (area > 31 || line > 7) { DEBUG_PRINTLN(F("Area or Line wrong")); goto end; } address_t tmp; tmp.bytes.high = (area << 3) | line; tmp.bytes.low = member; __config_set_flags(id, CONFIG_FLAGS_VALUE_SET); __config_set_ga(id, tmp); break; } } } end: server->sendHeader(F("Location"),F(__ROOT_PATH)); server->send(302); } void ESPKNXIP::__handle_feedback() { DEBUG_PRINTLN(F("Feedback called")); if (server->hasArg(F("id"))) { config_id_t id = server->arg(F("id")).toInt(); DEBUG_PRINT(F("Got args: ")); DEBUG_PRINT(id); DEBUG_PRINTLN(F("")); if (id < 0 || id >= registered_feedbacks) { DEBUG_PRINTLN(F("ID wrong")); goto end; } switch (feedbacks[id].type) { case FEEDBACK_TYPE_ACTION: { feedback_action_fptr_t func = (feedback_action_fptr_t)feedbacks[id].data; void *arg = feedbacks[id].options.action_options.arg; func(arg); break; } default: DEBUG_PRINTLN(F("Feedback has no action")); break; } } end: server->sendHeader(F("Location"),F(__ROOT_PATH)); server->send(302); } #if !DISABLE_RESTORE_BUTTONS void ESPKNXIP::__handle_restore() { DEBUG_PRINTLN(F("Restore called")); memcpy(custom_config_data, custom_config_default_data, MAX_CONFIG_SPACE); end: server->sendHeader(F("Location"),F(__ROOT_PATH)); server->send(302); } #endif #if !DISABLE_REBOOT_BUTTONS void ESPKNXIP::__handle_reboot() { DEBUG_PRINTLN(F("Rebooting!")); server->sendHeader(F("Location"),F(__ROOT_PATH)); server->send(302); delay(1000); ESP.restart(); //while(1); } #endif #if !DISABLE_EEPROM_BUTTONS void ESPKNXIP::__handle_eeprom() { DEBUG_PRINTLN(F("EEPROM called")); if (server->hasArg(F("mode"))) { uint8_t mode = server->arg(F("mode")).toInt(); DEBUG_PRINT(F("Got args: ")); DEBUG_PRINT(mode); DEBUG_PRINTLN(F("")); if (mode == 1) { // save save_to_eeprom(); } else if (mode == 2) { // restore restore_from_eeprom(); } } end: server->sendHeader(F("Location"),F(__ROOT_PATH)); server->send(302); } #endif