Fork of the espurna firmware for `mhsw` switches
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

232 lines
6.1 KiB

8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
  1. /*
  2. SETTINGS MODULE
  3. Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
  4. */
  5. #include "Embedis.h"
  6. #include <EEPROM.h>
  7. #include "spi_flash.h"
  8. #include <StreamString.h>
  9. #define AUTO_SAVE 1
  10. Embedis embedis(Serial);
  11. // -----------------------------------------------------------------------------
  12. // Settings
  13. // -----------------------------------------------------------------------------
  14. unsigned long settingsSize() {
  15. unsigned pos = SPI_FLASH_SEC_SIZE - 1;
  16. while (size_t len = EEPROM.read(pos)) {
  17. pos = pos - len - 2;
  18. }
  19. return SPI_FLASH_SEC_SIZE - pos;
  20. }
  21. unsigned int settingsKeyCount() {
  22. unsigned count = 0;
  23. unsigned pos = SPI_FLASH_SEC_SIZE - 1;
  24. while (size_t len = EEPROM.read(pos)) {
  25. pos = pos - len - 2;
  26. count ++;
  27. }
  28. return count / 2;
  29. }
  30. String settingsKeyName(unsigned int index) {
  31. String s;
  32. unsigned count = 0;
  33. unsigned stop = index * 2 + 1;
  34. unsigned pos = SPI_FLASH_SEC_SIZE - 1;
  35. while (size_t len = EEPROM.read(pos)) {
  36. pos = pos - len - 2;
  37. count++;
  38. if (count == stop) {
  39. s.reserve(len);
  40. for (unsigned char i = 0 ; i < len; i++) {
  41. s += (char) EEPROM.read(pos + i + 1);
  42. }
  43. break;
  44. }
  45. }
  46. return s;
  47. }
  48. void settingsFactoryReset() {
  49. for (unsigned int i = 0; i < SPI_FLASH_SEC_SIZE; i++) {
  50. EEPROM.write(i, 0xFF);
  51. }
  52. EEPROM.commit();
  53. }
  54. void settingsSetup() {
  55. EEPROM.begin(SPI_FLASH_SEC_SIZE);
  56. Embedis::dictionary( F("EEPROM"),
  57. SPI_FLASH_SEC_SIZE,
  58. [](size_t pos) -> char { return EEPROM.read(pos); },
  59. [](size_t pos, char value) { EEPROM.write(pos, value); },
  60. #if AUTO_SAVE
  61. []() { EEPROM.commit(); }
  62. #else
  63. []() {}
  64. #endif
  65. );
  66. Embedis::hardware( F("WIFI"), [](Embedis* e) {
  67. StreamString s;
  68. WiFi.printDiag(s);
  69. e->response(s);
  70. }, 0);
  71. Embedis::command( F("RECONNECT"), [](Embedis* e) {
  72. wifiConfigure();
  73. wifiDisconnect();
  74. e->response(Embedis::OK);
  75. });
  76. Embedis::command( F("RESTART"), [](Embedis* e) {
  77. e->response(Embedis::OK);
  78. customReset(CUSTOM_RESET_TERMINAL);
  79. ESP.restart();
  80. });
  81. Embedis::command( F("RESET"), [](Embedis* e) {
  82. e->response(Embedis::OK);
  83. customReset(CUSTOM_RESET_TERMINAL);
  84. ESP.restart();
  85. });
  86. Embedis::command( F("FACTORY.RESET"), [](Embedis* e) {
  87. settingsFactoryReset();
  88. e->response(Embedis::OK);
  89. });
  90. Embedis::command( F("HEAP"), [](Embedis* e) {
  91. e->stream->printf("Free HEAP: %d bytes\n", ESP.getFreeHeap());
  92. e->response(Embedis::OK);
  93. });
  94. Embedis::command( F("RELAY"), [](Embedis* e) {
  95. if (e->argc < 2) {
  96. return e->response(Embedis::ARGS_ERROR);
  97. }
  98. int id = String(e->argv[1]).toInt();
  99. if (e->argc > 2) {
  100. int value = String(e->argv[2]).toInt();
  101. if (value == 2) {
  102. relayToggle(id);
  103. } else {
  104. relayStatus(id, value == 1);
  105. }
  106. }
  107. e->stream->printf("Status: %s\n", relayStatus(id) ? "true" : "false");
  108. e->response(Embedis::OK);
  109. });
  110. #if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
  111. Embedis::command( F("COLOR"), [](Embedis* e) {
  112. if (e->argc > 1) {
  113. String color = String(e->argv[1]);
  114. parseColor(color.c_str());
  115. lightColor(true, true);
  116. }
  117. e->stream->printf("Color: %s\n", lightColor().c_str());
  118. e->response(Embedis::OK);
  119. });
  120. #endif
  121. Embedis::command( F("EEPROM"), [](Embedis* e) {
  122. unsigned long freeEEPROM = SPI_FLASH_SEC_SIZE - settingsSize();
  123. e->stream->printf("Number of keys: %d\n", settingsKeyCount());
  124. e->stream->printf("Free EEPROM: %d bytes (%d%%)\n", freeEEPROM, 100 * freeEEPROM / SPI_FLASH_SEC_SIZE);
  125. e->response(Embedis::OK);
  126. });
  127. Embedis::command( F("DUMP"), [](Embedis* e) {
  128. unsigned int size = settingsKeyCount();
  129. for (unsigned int i=0; i<size; i++) {
  130. String key = settingsKeyName(i);
  131. String value = getSetting(key);
  132. e->stream->printf("+%s => %s\n", key.c_str(), value.c_str());
  133. }
  134. e->response(Embedis::OK);
  135. });
  136. Embedis::command( F("DUMP.RAW"), [](Embedis* e) {
  137. for (unsigned int i = 0; i < SPI_FLASH_SEC_SIZE; i++) {
  138. if (i % 16 == 0) e->stream->printf("\n[%04X] ", i);
  139. e->stream->printf("%02X ", EEPROM.read(i));
  140. }
  141. e->stream->printf("\n");
  142. e->response(Embedis::OK);
  143. });
  144. DEBUG_MSG_P(PSTR("[SETTINGS] EEPROM size: %d bytes\n"), SPI_FLASH_SEC_SIZE);
  145. DEBUG_MSG_P(PSTR("[SETTINGS] Settings size: %d bytes\n"), settingsSize());
  146. }
  147. void settingsLoop() {
  148. embedis.process();
  149. }
  150. void moveSetting(const char * from, const char * to) {
  151. String value = getSetting(from);
  152. if (value.length() > 0) setSetting(to, value);
  153. delSetting(from);
  154. }
  155. template<typename T> String getSetting(const String& key, T defaultValue) {
  156. String value;
  157. if (!Embedis::get(key, value)) value = String(defaultValue);
  158. return value;
  159. }
  160. template<typename T> String getSetting(const String& key, unsigned int index, T defaultValue) {
  161. return getSetting(key + String(index), defaultValue);
  162. }
  163. String getSetting(const String& key) {
  164. return getSetting(key, "");
  165. }
  166. template<typename T> bool setSetting(const String& key, T value) {
  167. return Embedis::set(key, String(value));
  168. }
  169. template<typename T> bool setSetting(const String& key, unsigned int index, T value) {
  170. return setSetting(key + String(index), value);
  171. }
  172. bool delSetting(const String& key) {
  173. return Embedis::del(key);
  174. }
  175. bool delSetting(const String& key, unsigned int index) {
  176. return delSetting(key + String(index));
  177. }
  178. bool hasSetting(const String& key) {
  179. return getSetting(key).length() != 0;
  180. }
  181. bool hasSetting(const String& key, unsigned int index) {
  182. return getSetting(key, index, "").length() != 0;
  183. }
  184. void saveSettings() {
  185. DEBUG_MSG_P(PSTR("[SETTINGS] Saving\n"));
  186. #if not AUTO_SAVE
  187. EEPROM.commit();
  188. #endif
  189. }