esp-knx-ip.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. /**
  2. * esp-knx-ip library for KNX/IP communication on an ESP8266
  3. * Author: Nico Weichbrodt <envy>
  4. * License: MIT
  5. */
  6. #ifndef ESP_KNX_IP_H
  7. #define ESP_KNX_IP_H
  8. /**
  9. * CONFIG
  10. * All MAX_ values must not exceed 255 (1 byte, except MAC_CONFIG_SPACE which can go up to 2 bytes, so 0xffff in theory) and must not be negative!
  11. * Config space is restriced by EEPROM_SIZE (default 1024).
  12. * Required EEPROM size is 8 + MAX_GA_CALLBACKS * 3 + 2 + MAX_CONFIG_SPACE which is 552 by default
  13. */
  14. #define EEPROM_SIZE 1024 // [Default 1024]
  15. #define MAX_CALLBACK_ASSIGNMENTS 10 // [Default 10] Maximum number of group address callbacks that can be stored
  16. #define MAX_CALLBACKS 10 // [Default 10] Maximum number of callbacks that can be stored
  17. #define MAX_CONFIGS 20 // [Default 20] Maximum number of config items that can be stored
  18. #define MAX_CONFIG_SPACE 0x0200 // [Default 0x0200] Maximum number of bytes that can be stored for custom config
  19. #define MAX_FEEDBACKS 20 // [Default 20] Maximum number of feedbacks that can be shown
  20. // Callbacks
  21. #define ALLOW_MULTIPLE_CALLBACKS_PER_ADDRESS 1 // [Default 0] Set to 1 to always test all assigned callbacks. This allows for multiple callbacks being assigned to the same address. If disabled, only the first assigned will be called.
  22. // Webserver related
  23. #define USE_BOOTSTRAP 0 // [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
  24. #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
  25. #define DISABLE_EEPROM_BUTTONS 1 // [Default 0] Set to 1 to disable the EEPROM buttons in the web ui.
  26. #define DISABLE_REBOOT_BUTTON 1 // [Default 0] Set to 1 to disable the reboot button in the web ui.
  27. #define DISABLE_RESTORE_BUTTON 1 // [Default 0] Set to 1 to disable the "restore defaults" button in the web ui.
  28. // These values normally don't need adjustment
  29. #define MULTICAST_PORT 3671 // [Default 3671]
  30. #define MULTICAST_IP IPAddress(224, 0, 23, 12) // [Default IPAddress(224, 0, 23, 12)]
  31. #define SEND_CHECKSUM 0
  32. // Uncomment to enable printing out debug messages.
  33. //#define ESP_KNX_DEBUG
  34. /**
  35. * END CONFIG
  36. */
  37. #include "Arduino.h"
  38. #include <EEPROM.h>
  39. #include <ESP8266WiFi.h>
  40. #include <WiFiUdp.h>
  41. #include <ESP8266WebServer.h>
  42. #include "DPT.h"
  43. #define EEPROM_MAGIC (0xDEADBEEF00000000 + (MAX_CONFIG_SPACE) + (MAX_CALLBACK_ASSIGNMENTS << 16) + (MAX_CALLBACKS << 8))
  44. // Define where debug output will be printed.
  45. #ifndef DEBUG_PRINTER
  46. #define DEBUG_PRINTER Serial
  47. #endif
  48. // Setup debug printing macros.
  49. #ifdef ESP_KNX_DEBUG
  50. #define DEBUG_PRINT(...) { DEBUG_PRINTER.print(__VA_ARGS__); }
  51. #define DEBUG_PRINTLN(...) { DEBUG_PRINTER.println(__VA_ARGS__); }
  52. #else
  53. #define DEBUG_PRINT(...) {}
  54. #define DEBUG_PRINTLN(...) {}
  55. #endif
  56. #define __ROOT_PATH ROOT_PREFIX"/"
  57. #define __REGISTER_PATH ROOT_PREFIX"/register"
  58. #define __DELETE_PATH ROOT_PREFIX"/delete"
  59. #define __PHYS_PATH ROOT_PREFIX"/phys"
  60. #define __EEPROM_PATH ROOT_PREFIX"/eeprom"
  61. #define __CONFIG_PATH ROOT_PREFIX"/config"
  62. #define __FEEDBACK_PATH ROOT_PREFIX"/feedback"
  63. #define __RESTORE_PATH ROOT_PREFIX"/restore"
  64. #define __REBOOT_PATH ROOT_PREFIX"/reboot"
  65. /**
  66. * Different service types, we are mainly interested in KNX_ST_ROUTING_INDICATION
  67. */
  68. typedef enum __knx_service_type
  69. {
  70. KNX_ST_SEARCH_REQUEST = 0x0201,
  71. KNX_ST_SEARCH_RESPONSE = 0x0202,
  72. KNX_ST_DESCRIPTION_REQUEST = 0x0203,
  73. KNX_ST_DESCRIPTION_RESPONSE = 0x0204,
  74. KNX_ST_CONNECT_REQUEST = 0x0205,
  75. KNX_ST_CONNECT_RESPONSE = 0x0206,
  76. KNX_ST_CONNECTIONSTATE_REQUEST = 0x0207,
  77. KNX_ST_CONNECTIONSTATE_RESPONSE = 0x0208,
  78. KNX_ST_DISCONNECT_REQUEST = 0x0209,
  79. KNX_ST_DISCONNECT_RESPONSE = 0x020A,
  80. KNX_ST_DEVICE_CONFIGURATION_REQUEST = 0x0310,
  81. KNX_ST_DEVICE_CONFIGURATION_ACK = 0x0311,
  82. KNX_ST_TUNNELING_REQUEST = 0x0420,
  83. KNX_ST_TUNNELING_ACK = 0x0421,
  84. KNX_ST_ROUTING_INDICATION = 0x0530,
  85. KNX_ST_ROUTING_LOST_MESSAGE = 0x0531,
  86. KNX_ST_ROUTING_BUSY = 0x0532,
  87. // KNX_ST_RLOG_START = 0x0600,
  88. // KNX_ST_RLOG_END = 0x06FF,
  89. KNX_ST_REMOTE_DIAGNOSTIC_REQUEST = 0x0740,
  90. KNX_ST_REMOTE_DIAGNOSTIC_RESPONSE = 0x0741,
  91. KNX_ST_REMOTE_BASIC_CONFIGURATION_REQUEST = 0x0742,
  92. KNX_ST_REMOTE_RESET_REQUEST = 0x0743,
  93. // KNX_ST_OBJSRV_START = 0x0800,
  94. // KNX_ST_OBJSRV_END = 0x08FF,
  95. } knx_service_type_t;
  96. /**
  97. * Differnt command types, first three are of main interest
  98. */
  99. typedef enum __knx_command_type
  100. {
  101. KNX_CT_READ = 0x00,
  102. KNX_CT_ANSWER = 0x01,
  103. KNX_CT_WRITE = 0x02,
  104. KNX_CT_INDIVIDUAL_ADDR_WRITE = 0x03,
  105. KNX_CT_INDIVIDUAL_ADDR_REQUEST = 0x04,
  106. KNX_CT_INDIVIDUAL_ADDR_RESPONSE = 0x05,
  107. KNX_CT_ADC_READ = 0x06,
  108. KNX_CT_ADC_ANSWER = 0x07,
  109. KNX_CT_MEM_READ = 0x08,
  110. KNX_CT_MEM_ANSWER = 0x09,
  111. KNX_CT_MEM_WRITE = 0x0A,
  112. //KNX_CT_UNKNOWN = 0x0B,
  113. KNX_CT_MASK_VERSION_READ = 0x0C,
  114. KNX_CT_MASK_VERSION_RESPONSE = 0x0D,
  115. KNX_CT_RESTART = 0x0E,
  116. KNX_CT_ESCAPE = 0x0F,
  117. } knx_command_type_t;
  118. /**
  119. * cEMI message types, mainly KNX_MT_L_DATA_IND is interesting
  120. */
  121. typedef enum __knx_cemi_msg_type
  122. {
  123. KNX_MT_L_DATA_REQ = 0x11,
  124. KNX_MT_L_DATA_IND = 0x29,
  125. KNX_MT_L_DATA_CON = 0x2E,
  126. } knx_cemi_msg_type_t;
  127. /**
  128. * TCPI communication type
  129. */
  130. typedef enum __knx_communication_type {
  131. KNX_COT_UDP = 0x00, // Unnumbered Data Packet
  132. KNX_COT_NDP = 0x01, // Numbered Data Packet
  133. KNX_COT_UCD = 0x02, // Unnumbered Control Data
  134. KNX_COT_NCD = 0x03, // Numbered Control Data
  135. } knx_communication_type_t;
  136. /**
  137. * acpi for KNX_COT_NCD
  138. */
  139. typedef enum __knx_cot_ncd_ack_type {
  140. KNX_COT_NCD_ACK = 0x10, // Inform positively reception of the Previouly received telegram
  141. KNX_COT_NCD_NACK = 0x11, // Inform negatively reception of the Previouly received telegram
  142. } knx_cot_ncd_ack_type_t;
  143. /**
  144. * KNX/IP header
  145. */
  146. typedef struct __knx_ip_pkt
  147. {
  148. uint8_t header_len; // Should always be 0x06
  149. uint8_t protocol_version; // Should be version 1.0, transmitted as 0x10
  150. uint16_t service_type; // See knx_service_type_t
  151. union
  152. {
  153. struct {
  154. uint8_t first_byte;
  155. uint8_t second_byte;
  156. } bytes;
  157. uint16_t len;
  158. } total_len; // header_len + rest of pkt. This is a bit weird as the spec says this: If the total number of bytes transmitted is greater than 252 bytes, the first “Total Length” byte is set to FF (255). Only in this case the second byte includes additional length information
  159. uint8_t pkt_data[]; // This is of type cemi_msg_t
  160. } knx_ip_pkt_t;
  161. typedef struct __cemi_addi
  162. {
  163. uint8_t type_id;
  164. uint8_t len;
  165. uint8_t data[];
  166. } cemi_addi_t;
  167. typedef union __address
  168. {
  169. uint16_t value;
  170. struct
  171. {
  172. uint8_t high;
  173. uint8_t low;
  174. } bytes;
  175. struct __attribute__((packed))
  176. {
  177. uint8_t line:3;
  178. uint8_t area:5;
  179. uint8_t member;
  180. } ga;
  181. struct __attribute__((packed))
  182. {
  183. uint8_t line:4;
  184. uint8_t area:4;
  185. uint8_t member;
  186. } pa;
  187. uint8_t array[2];
  188. } address_t;
  189. typedef struct __cemi_service
  190. {
  191. union
  192. {
  193. struct
  194. {
  195. // Struct is reversed due to bit order
  196. uint8_t confirm:1; // 0 = no error, 1 = error
  197. uint8_t ack:1; // 0 = no ack, 1 = ack
  198. uint8_t priority:2; // 0 = system, 1 = high, 2 = urgent/alarm, 3 = normal
  199. uint8_t system_broadcast:1; // 0 = system broadcast, 1 = broadcast
  200. uint8_t repeat:1; // 0 = repeated telegram, 1 = not repeated telegram
  201. uint8_t reserved:1; // always zero
  202. uint8_t frame_type:1; // 0 = extended, 1 = standard
  203. } bits;
  204. uint8_t byte;
  205. } control_1;
  206. union
  207. {
  208. struct
  209. {
  210. // Struct is reversed due to bit order
  211. uint8_t extended_frame_format:4;
  212. uint8_t hop_count:3;
  213. uint8_t dest_addr_type:1; // 0 = individual, 1 = group
  214. } bits;
  215. uint8_t byte;
  216. } control_2;
  217. address_t source;
  218. address_t destination;
  219. uint8_t data_len; // length of data, excluding the tpci byte
  220. struct
  221. {
  222. uint8_t apci:2; // If tpci.comm_type == KNX_COT_UCD or KNX_COT_NCD, then this is apparently control data?
  223. uint8_t tpci_seq_number:4;
  224. uint8_t tpci_comm_type:2; // See knx_communication_type_t
  225. } pci;
  226. uint8_t data[];
  227. } cemi_service_t;
  228. typedef struct __cemi_msg
  229. {
  230. uint8_t message_code;
  231. uint8_t additional_info_len;
  232. union
  233. {
  234. cemi_addi_t additional_info[];
  235. cemi_service_t service_information;
  236. } data;
  237. } cemi_msg_t;
  238. typedef enum __config_type
  239. {
  240. CONFIG_TYPE_UNKNOWN,
  241. CONFIG_TYPE_INT,
  242. CONFIG_TYPE_BOOL,
  243. CONFIG_TYPE_STRING,
  244. CONFIG_TYPE_OPTIONS,
  245. CONFIG_TYPE_GA,
  246. } config_type_t;
  247. typedef enum __feedback_type
  248. {
  249. FEEDBACK_TYPE_UNKNOWN,
  250. FEEDBACK_TYPE_INT,
  251. FEEDBACK_TYPE_FLOAT,
  252. FEEDBACK_TYPE_BOOL,
  253. FEEDBACK_TYPE_ACTION,
  254. } feedback_type_t;
  255. typedef enum __config_flags
  256. {
  257. CONFIG_FLAGS_NO_FLAGS = 0,
  258. CONFIG_FLAGS_VALUE_SET = 1,
  259. } config_flags_t;
  260. typedef enum __slot_flags
  261. {
  262. SLOT_FLAGS_EMPTY = 0, // Empty slots have no flags
  263. SLOT_FLAGS_USED = 1,
  264. } slot_flags_t;
  265. typedef struct __message
  266. {
  267. knx_command_type_t ct;
  268. address_t received_on;
  269. uint8_t data_len;
  270. uint8_t *data;
  271. } message_t;
  272. typedef bool (*enable_condition_t)(void);
  273. typedef void (*callback_fptr_t)(message_t const &msg, void *arg);
  274. typedef void (*feedback_action_fptr_t)(void *arg);
  275. typedef uint8_t callback_id_t;
  276. #define CALLBACK_ID_MAX UINT8_MAX
  277. typedef uint8_t callback_assignment_id_t;
  278. #define CALLBACK_ASSIGNMENT_ID_MAX UINT8_MAX
  279. typedef uint8_t config_id_t;
  280. typedef uint8_t feedback_id_t;
  281. typedef struct __option_entry
  282. {
  283. char const *name;
  284. uint8_t value;
  285. } option_entry_t;
  286. typedef struct __config
  287. {
  288. config_type_t type;
  289. String name;
  290. uint8_t offset;
  291. uint8_t len;
  292. enable_condition_t cond;
  293. union {
  294. option_entry_t *options;
  295. } data;
  296. } config_t;
  297. extern char const *string_defaults[];
  298. #define STRING_DEFAULT_DO_THIS (string_defaults[0])
  299. #define STRING_DEFAULT_TRUE (string_defaults[1])
  300. #define STRING_DEFAULT_FALSE (string_defaults[2])
  301. #define STRING_DEFAULT_EMPTY (string_defaults[3])
  302. typedef struct __feedback_float_options
  303. {
  304. uint8_t precision;
  305. char const *prefix;
  306. char const *suffix;
  307. } feedback_float_options_t;
  308. typedef struct __feedback_bool_options
  309. {
  310. char const *true_text;
  311. char const *false_text;
  312. } feedback_bool_options_t;
  313. typedef struct __feedback_action_options
  314. {
  315. void *arg;
  316. char const *btn_text;
  317. } feedback_action_options_t;
  318. typedef struct __feedback
  319. {
  320. feedback_type_t type;
  321. String name;
  322. enable_condition_t cond;
  323. void *data;
  324. union {
  325. feedback_bool_options_t bool_options;
  326. feedback_float_options_t float_options;
  327. feedback_action_options_t action_options;
  328. } options;
  329. } feedback_t;
  330. typedef struct __callback
  331. {
  332. uint8_t slot_flags;
  333. callback_fptr_t fkt;
  334. enable_condition_t cond;
  335. void *arg;
  336. String name;
  337. } callback_t;
  338. typedef struct __callback_assignment
  339. {
  340. uint8_t slot_flags;
  341. address_t address;
  342. callback_id_t callback_id;
  343. } callback_assignment_t;
  344. class ESPKNXIP {
  345. public:
  346. ESPKNXIP();
  347. void load();
  348. void start();
  349. void start(ESP8266WebServer *srv);
  350. void loop();
  351. void save_to_eeprom();
  352. void restore_from_eeprom();
  353. callback_id_t callback_register(String name, callback_fptr_t cb, void *arg = nullptr, enable_condition_t cond = nullptr);
  354. callback_assignment_id_t callback_assign(callback_id_t id, address_t val);
  355. void callback_deregister(callback_id_t id);
  356. void callback_unassign(callback_assignment_id_t id);
  357. void physical_address_set(address_t const &addr);
  358. address_t physical_address_get();
  359. // Configuration functions
  360. config_id_t config_register_string(String name, uint8_t len, String _default, enable_condition_t cond = nullptr);
  361. config_id_t config_register_int(String name, int32_t _default, enable_condition_t cond = nullptr);
  362. config_id_t config_register_bool(String name, bool _default, enable_condition_t cond = nullptr);
  363. config_id_t config_register_options(String name, option_entry_t *options, uint8_t _default, enable_condition_t cond = nullptr);
  364. config_id_t config_register_ga(String name, enable_condition_t cond = nullptr);
  365. String config_get_string(config_id_t id);
  366. int32_t config_get_int(config_id_t id);
  367. bool config_get_bool(config_id_t id);
  368. uint8_t config_get_options(config_id_t id);
  369. address_t config_get_ga(config_id_t id);
  370. void config_set_string(config_id_t id, String val);
  371. void config_set_int(config_id_t id, int32_t val);
  372. void config_set_bool(config_id_t, bool val);
  373. void config_set_options(config_id_t id, uint8_t val);
  374. void config_set_ga(config_id_t id, address_t const &val);
  375. // Feedback functions
  376. feedback_id_t feedback_register_int(String name, int32_t *value, enable_condition_t cond = nullptr);
  377. 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);
  378. 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);
  379. 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);
  380. // Send functions
  381. void send(address_t const &receiver, knx_command_type_t ct, uint8_t data_len, uint8_t *data);
  382. void send_1bit(address_t const &receiver, knx_command_type_t ct, uint8_t bit);
  383. void send_2bit(address_t const &receiver, knx_command_type_t ct, uint8_t twobit);
  384. void send_4bit(address_t const &receiver, knx_command_type_t ct, uint8_t fourbit);
  385. void send_1byte_int(address_t const &receiver, knx_command_type_t ct, int8_t val);
  386. void send_1byte_uint(address_t const &receiver, knx_command_type_t ct, uint8_t val);
  387. void send_2byte_int(address_t const &receiver, knx_command_type_t ct, int16_t val);
  388. void send_2byte_uint(address_t const &receiver, knx_command_type_t ct, uint16_t val);
  389. void send_2byte_float(address_t const &receiver, knx_command_type_t ct, float val);
  390. void send_3byte_time(address_t const &receiver, knx_command_type_t ct, uint8_t weekday, uint8_t hours, uint8_t minutes, uint8_t seconds);
  391. void send_3byte_time(address_t const &receiver, knx_command_type_t ct, time_of_day_t const &time) { send_3byte_time(receiver, ct, time.weekday, time.hours, time.minutes, time.seconds); }
  392. void send_3byte_date(address_t const &receiver, knx_command_type_t ct, uint8_t day, uint8_t month, uint8_t year);
  393. void send_3byte_date(address_t const &receiver, knx_command_type_t ct, date_t const &date) { send_3byte_date(receiver, ct, date.day, date.month, date.year); }
  394. void send_3byte_color(address_t const &receiver, knx_command_type_t ct, uint8_t red, uint8_t green, uint8_t blue);
  395. void send_3byte_color(address_t const &receiver, knx_command_type_t ct, color_t const &color) { send_3byte_color(receiver, ct, color.red, color.green, color.blue); }
  396. void send_4byte_int(address_t const &receiver, knx_command_type_t ct, int32_t val);
  397. void send_4byte_uint(address_t const &receiver, knx_command_type_t ct, uint32_t val);
  398. void send_4byte_float(address_t const &receiver, knx_command_type_t ct, float val);
  399. void write_1bit(address_t const &receiver, uint8_t bit) { send_1bit(receiver, KNX_CT_WRITE, bit); }
  400. void write_2bit(address_t const &receiver, uint8_t twobit) { send_2bit(receiver, KNX_CT_WRITE, twobit); }
  401. void write_4bit(address_t const &receiver, uint8_t fourbit) { send_4bit(receiver, KNX_CT_WRITE, fourbit); }
  402. void write_1byte_int(address_t const &receiver, int8_t val) { send_1byte_int(receiver, KNX_CT_WRITE, val); }
  403. void write_1byte_uint(address_t const &receiver, uint8_t val) { send_1byte_uint(receiver, KNX_CT_WRITE, val); }
  404. void write_2byte_int(address_t const &receiver, int16_t val) { send_2byte_int(receiver, KNX_CT_WRITE, val); }
  405. void write_2byte_uint(address_t const &receiver, uint16_t val) { send_2byte_uint(receiver, KNX_CT_WRITE, val); }
  406. void write_2byte_float(address_t const &receiver, float val) { send_2byte_float(receiver, KNX_CT_WRITE, val); }
  407. void write_3byte_time(address_t const &receiver, uint8_t weekday, uint8_t hours, uint8_t minutes, uint8_t seconds) { send_3byte_time(receiver, KNX_CT_WRITE, weekday, hours, minutes, seconds); }
  408. void write_3byte_time(address_t const &receiver, time_of_day_t const &time) { send_3byte_time(receiver, KNX_CT_WRITE, time.weekday, time.hours, time.minutes, time.seconds); }
  409. void write_3byte_date(address_t const &receiver, uint8_t day, uint8_t month, uint8_t year) { send_3byte_date(receiver, KNX_CT_WRITE, day, month, year); }
  410. void write_3byte_date(address_t const &receiver, date_t const &date) { send_3byte_date(receiver, KNX_CT_WRITE, date.day, date.month, date.year); }
  411. void write_3byte_color(address_t const &receiver, uint8_t red, uint8_t green, uint8_t blue) { send_3byte_color(receiver, KNX_CT_WRITE, red, green, blue); }
  412. void write_3byte_color(address_t const &receiver, color_t const &color) { send_3byte_color(receiver, KNX_CT_WRITE, color); }
  413. void write_4byte_int(address_t const &receiver, int32_t val) { send_4byte_int(receiver, KNX_CT_WRITE, val); }
  414. void write_4byte_uint(address_t const &receiver, uint32_t val) { send_4byte_uint(receiver, KNX_CT_WRITE, val); }
  415. void write_4byte_float(address_t const &receiver, float val) { send_4byte_float(receiver, KNX_CT_WRITE, val);}
  416. void answer_1bit(address_t const &receiver, uint8_t bit) { send_1bit(receiver, KNX_CT_ANSWER, bit); }
  417. void answer_2bit(address_t const &receiver, uint8_t twobit) { send_2bit(receiver, KNX_CT_ANSWER, twobit); }
  418. void answer_4bit(address_t const &receiver, uint8_t fourbit) { send_4bit(receiver, KNX_CT_ANSWER, fourbit); }
  419. void answer_1byte_int(address_t const &receiver, int8_t val) { send_1byte_int(receiver, KNX_CT_ANSWER, val); }
  420. void answer_1byte_uint(address_t const &receiver, uint8_t val) { send_1byte_uint(receiver, KNX_CT_ANSWER, val); }
  421. void answer_2byte_int(address_t const &receiver, int16_t val) { send_2byte_int(receiver, KNX_CT_ANSWER, val); }
  422. void answer_2byte_uint(address_t const &receiver, uint16_t val) { send_2byte_uint(receiver, KNX_CT_ANSWER, val); }
  423. void answer_2byte_float(address_t const &receiver, float val) { send_2byte_float(receiver, KNX_CT_ANSWER, val); }
  424. void answer_3byte_time(address_t const &receiver, uint8_t weekday, uint8_t hours, uint8_t minutes, uint8_t seconds) { send_3byte_time(receiver, KNX_CT_ANSWER, weekday, hours, minutes, seconds); }
  425. void answer_3byte_time(address_t const &receiver, time_of_day_t const &time) { send_3byte_time(receiver, KNX_CT_ANSWER, time.weekday, time.hours, time.minutes, time.seconds); }
  426. void answer_3byte_date(address_t const &receiver, uint8_t day, uint8_t month, uint8_t year) { send_3byte_date(receiver, KNX_CT_ANSWER, day, month, year); }
  427. void answer_3byte_date(address_t const &receiver, date_t const &date) { send_3byte_date(receiver, KNX_CT_ANSWER, date.day, date.month, date.year); }
  428. void answer_3byte_color(address_t const &receiver, uint8_t red, uint8_t green, uint8_t blue) { send_3byte_color(receiver, KNX_CT_ANSWER, red, green, blue); }
  429. void answer_3byte_color(address_t const &receiver, color_t const &color) { send_3byte_color(receiver, KNX_CT_ANSWER, color); }
  430. void answer_4byte_int(address_t const &receiver, int32_t val) { send_4byte_int(receiver, KNX_CT_ANSWER, val); }
  431. void answer_4byte_uint(address_t const &receiver, uint32_t val) { send_4byte_uint(receiver, KNX_CT_ANSWER, val); }
  432. void answer_4byte_float(address_t const &receiver, float val) { send_4byte_float(receiver, KNX_CT_ANSWER, val);}
  433. bool data_to_bool(uint8_t *data);
  434. int8_t data_to_1byte_int(uint8_t *data);
  435. uint8_t data_to_1byte_uint(uint8_t *data);
  436. int16_t data_to_2byte_int(uint8_t *data);
  437. uint16_t data_to_2byte_uint(uint8_t *data);
  438. float data_to_2byte_float(uint8_t *data);
  439. color_t data_to_3byte_color(uint8_t *data);
  440. time_of_day_t data_to_3byte_time(uint8_t *data);
  441. date_t data_to_3byte_data(uint8_t *data);
  442. int32_t data_to_4byte_int(uint8_t *data);
  443. uint32_t data_to_4byte_uint(uint8_t *data);
  444. float data_to_4byte_float(uint8_t *data);
  445. static address_t GA_to_address(uint8_t area, uint8_t line, uint8_t member)
  446. {
  447. // Yes, the order is correct, see the struct definition above
  448. address_t tmp = {.ga={line, area, member}};
  449. return tmp;
  450. }
  451. static address_t PA_to_address(uint8_t area, uint8_t line, uint8_t member)
  452. {
  453. // Yes, the order is correct, see the struct definition above
  454. address_t tmp = {.pa={line, area, member}};
  455. return tmp;
  456. }
  457. private:
  458. void __start();
  459. void __loop_knx();
  460. // Webserver functions
  461. void __loop_webserver();
  462. void __handle_root();
  463. void __handle_register();
  464. void __handle_delete();
  465. void __handle_set();
  466. #if !DISABLE_EEPROM_BUTTONS
  467. void __handle_eeprom();
  468. #endif
  469. void __handle_config();
  470. void __handle_feedback();
  471. #if !DISABLE_RESTORE_BUTTONS
  472. void __handle_restore();
  473. #endif
  474. #if !DISABLE_REBOOT_BUTTONS
  475. void __handle_reboot();
  476. #endif
  477. void __config_set_flags(config_id_t id, config_flags_t flags);
  478. void __config_set_string(config_id_t id, String &val);
  479. void __config_set_int(config_id_t id, int32_t val);
  480. void __config_set_bool(config_id_t id, bool val);
  481. void __config_set_options(config_id_t id, uint8_t val);
  482. void __config_set_ga(config_id_t id, address_t const &val);
  483. bool __callback_is_id_valid(callback_id_t id);
  484. callback_assignment_id_t __callback_register_assignment(address_t address, callback_id_t id);
  485. void __callback_delete_assignment(callback_assignment_id_t id);
  486. ESP8266WebServer *server;
  487. address_t physaddr;
  488. WiFiUDP udp;
  489. callback_assignment_id_t registered_callback_assignments;
  490. callback_assignment_id_t free_callback_assignment_slots;
  491. callback_assignment_t callback_assignments[MAX_CALLBACK_ASSIGNMENTS];
  492. callback_id_t registered_callbacks;
  493. callback_id_t free_callback_slots;
  494. callback_t callbacks[MAX_CALLBACKS];
  495. config_id_t registered_configs;
  496. uint8_t custom_config_data[MAX_CONFIG_SPACE];
  497. uint8_t custom_config_default_data[MAX_CONFIG_SPACE];
  498. config_t custom_configs[MAX_CONFIGS];
  499. feedback_id_t registered_feedbacks;
  500. feedback_t feedbacks[MAX_FEEDBACKS];
  501. uint16_t __ntohs(uint16_t);
  502. };
  503. // Global "singleton" object
  504. extern ESPKNXIP knx;
  505. #endif