config.ino 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220
  1. // sets the corresponding config variable for 'param' to new value
  2. // does not trigger saving to flash
  3. // does not distinguish between config sets as they are only split on flash and
  4. // in web interface called from commands:
  5. // serial command: set [param] [value]
  6. // MQTT cmd topic, payload "set [param] [value]"
  7. // -> must be committed by command 'save' after all desired values are set
  8. // called from web interface setConf functions, which also saves the changed
  9. // conf set to flash immediately
  10. void setConfig(char *param, char *value)
  11. {
  12. if (serialdebug)
  13. {
  14. Serial.print("setConfig - '");
  15. Serial.print(param);
  16. Serial.print("' to '");
  17. Serial.print(value);
  18. Serial.println("'");
  19. }
  20. //char param_l[15];
  21. strlwr(param);
  22. // values
  23. if (strcmp(param, "temp") == 0)
  24. {
  25. float valueFloat = round(atof(value) * 2.0) / 2.0;
  26. setTempTo(valueFloat);
  27. }
  28. else if (strcmp(param, "templow") == 0)
  29. {
  30. float valueFloat = round(atof(value) * 2.0) / 2.0;
  31. setTempLowTo(valueFloat);
  32. }
  33. else if (strcmp(param, "templow2") == 0)
  34. {
  35. float valueFloat = round(atof(value) * 2.0) / 2.0;
  36. setTempLow2To(valueFloat);
  37. }
  38. else if (strcmp(param, "mode") == 0)
  39. {
  40. int val = atoi(value);
  41. if (val >= 0 && val <= 1)
  42. {
  43. setHeatingmodeTo(val);
  44. }
  45. }
  46. else if (strcmp(param, "preset") == 0)
  47. {
  48. int val = atoi(value);
  49. if (val >= 0 && val <= 2)
  50. {
  51. setPresetTo(val);
  52. }
  53. }
  54. // confDevWiFi
  55. else if (strcmp(param, "devname") == 0)
  56. {
  57. if (strlen(value) >= 4)
  58. strlcpy(confDevWiFi.deviceName, value, sizeof(confDevWiFi.deviceName));
  59. }
  60. else if (strcmp(param, "hostname") == 0)
  61. {
  62. if (strlen(value) >= 4)
  63. strlcpy(confDevWiFi.hostName, value, sizeof(confDevWiFi.hostName));
  64. }
  65. else if (strcmp(param, "ssid1") == 0)
  66. {
  67. strlcpy(confDevWiFi.WiFiSSID1, value, sizeof(confDevWiFi.WiFiSSID1));
  68. }
  69. else if (strcmp(param, "wpw1") == 0)
  70. {
  71. if(!strcmp(value,"****") == 0) strlcpy(confDevWiFi.WiFiPW1, value, sizeof(confDevWiFi.WiFiPW1));
  72. }
  73. else if (strcmp(param, "ssid2") == 0)
  74. {
  75. strlcpy(confDevWiFi.WiFiSSID2, value, sizeof(confDevWiFi.WiFiSSID2));
  76. }
  77. else if (strcmp(param, "wpw2") == 0)
  78. {
  79. if(!strcmp(value,"****") == 0) strlcpy(confDevWiFi.WiFiPW2, value, sizeof(confDevWiFi.WiFiPW2));
  80. }
  81. else if (strcmp(param, "wpwap") == 0)
  82. {
  83. if(!strcmp(value,"****") == 0) strlcpy(confDevWiFi.WiFiAPModePassword, value, sizeof(confDevWiFi.WiFiAPModePassword));
  84. }
  85. else if (strcmp(param, "waptout") == 0)
  86. {
  87. int tmpval = atoi(value);
  88. if (tmpval >= 0 && tmpval <= 120)
  89. confDevWiFi.WiFiAPModeTimeout = tmpval;
  90. }
  91. else if (strcmp(param, "wconncheck") == 0)
  92. {
  93. int tmpval = atoi(value);
  94. if (tmpval >= 10 && tmpval <= 3600)
  95. confDevWiFi.WiFiConnCheckInterval = tmpval;
  96. }
  97. else if (strcmp(param, "wretry") == 0)
  98. {
  99. int tmpval = atoi(value);
  100. if (tmpval >= 0 && tmpval <= 120)
  101. confDevWiFi.WiFiRetryInterval = tmpval;
  102. }
  103. else if (strcmp(param, "wreboot") == 0)
  104. {
  105. int tmpval = atoi(value);
  106. if (tmpval >= 0 && tmpval <= 2880)
  107. confDevWiFi.WiFiRebootOnNoConnect = tmpval;
  108. }
  109. // confWeb
  110. else if (strcmp(param, "apitoken") == 0)
  111. {
  112. if(!strcmp(value,"****") == 0) strlcpy(confWeb.http_token, value, sizeof(confWeb.http_token));
  113. }
  114. else if (strcmp(param, "httpua") == 0)
  115. {
  116. strlcpy(confWeb.http_user, value, sizeof(confWeb.http_user));
  117. }
  118. else if (strcmp(param, "httppa") == 0)
  119. {
  120. if(!strcmp(value,"****") == 0) strlcpy(confWeb.http_pass, value, sizeof(confWeb.http_pass));
  121. }
  122. else if (strcmp(param, "httpauth") == 0)
  123. {
  124. if (atoi(value) == 1)
  125. confWeb.http_user_auth = true;
  126. else
  127. confWeb.http_user_auth = false;
  128. }
  129. else if (strcmp(param, "httpu1") == 0)
  130. {
  131. strlcpy(confWeb.http_user1, value, sizeof(confWeb.http_user1));
  132. }
  133. else if (strcmp(param, "httpp1") == 0)
  134. {
  135. if(!strcmp(value,"****") == 0) strlcpy(confWeb.http_pass1, value, sizeof(confWeb.http_pass1));
  136. }
  137. else if (strcmp(param, "httpu2") == 0)
  138. {
  139. strlcpy(confWeb.http_user2, value, sizeof(confWeb.http_user2));
  140. }
  141. else if (strcmp(param, "httpp2") == 0)
  142. {
  143. if(!strcmp(value,"****") == 0) strlcpy(confWeb.http_pass2, value, sizeof(confWeb.http_pass2));
  144. }
  145. else if (strcmp(param, "enableconsole") == 0)
  146. {
  147. if (atoi(value) == 1)
  148. confWeb.enableConsole = true;
  149. else
  150. confWeb.enableConsole = false;
  151. }
  152. // confMqtt
  153. else if (strcmp(param, "mqttenable") == 0)
  154. {
  155. if (atoi(value) == 1)
  156. confMqtt.mqtt_enable = true;
  157. else
  158. confMqtt.mqtt_enable = false;
  159. }
  160. else if (strcmp(param, "mqtthost") == 0)
  161. {
  162. strlcpy(confMqtt.mqtt_server, value, sizeof(confMqtt.mqtt_server));
  163. }
  164. else if (strcmp(param, "mqttport") == 0)
  165. {
  166. confMqtt.mqtt_port = atoi(value);
  167. }
  168. else if (strcmp(param, "mqttuser") == 0)
  169. {
  170. strlcpy(confMqtt.mqtt_user, value, sizeof(confMqtt.mqtt_user));
  171. }
  172. else if (strcmp(param, "mqttpass") == 0)
  173. {
  174. if(!strcmp(value,"****") == 0) strlcpy(confMqtt.mqtt_pass, value, sizeof(confMqtt.mqtt_pass));
  175. }
  176. else if (strcmp(param, "intop") == 0)
  177. {
  178. strlcpy(confMqtt.mqtt_topic_in, value, sizeof(confMqtt.mqtt_topic_in));
  179. }
  180. else if (strcmp(param, "outtop") == 0)
  181. {
  182. strlcpy(confMqtt.mqtt_topic_out, value, sizeof(confMqtt.mqtt_topic_out));
  183. }
  184. else if (strcmp(param, "outret") == 0)
  185. {
  186. if (atoi(value) == 1)
  187. confMqtt.mqtt_outRetain = true;
  188. else
  189. confMqtt.mqtt_outRetain = false;
  190. publishDeleteRetainedOutMessages();
  191. }
  192. else if (strcmp(param, "outretsens") == 0)
  193. {
  194. if (atoi(value) == 1)
  195. confMqtt.mqtt_outRetain_sensors = true;
  196. else
  197. confMqtt.mqtt_outRetain_sensors = false;
  198. publishDeleteRetainedOutMessages_sensors();
  199. }
  200. else if (strcmp(param, "outpubint") == 0) {
  201. confMqtt.mqtt_outPubInterval = atoi(value);
  202. }
  203. else if (strcmp(param, "outpubintsens") == 0) {
  204. confMqtt.mqtt_outPubInterval_sensors = atoi(value);
  205. }
  206. else if (strcmp(param, "willtop") == 0)
  207. {
  208. strlcpy(confMqtt.mqtt_willTopic, value, sizeof(confMqtt.mqtt_willTopic));
  209. }
  210. else if (strcmp(param, "willqos") == 0)
  211. {
  212. int tmpval = atoi(value);
  213. if (tmpval >= 0 && tmpval <= 2)
  214. confMqtt.mqtt_willQos = tmpval;
  215. }
  216. else if (strcmp(param, "willret") == 0)
  217. {
  218. if (atoi(value) == 1)
  219. confMqtt.mqtt_willRetain = true;
  220. else
  221. confMqtt.mqtt_willRetain = false;
  222. }
  223. else if (strcmp(param, "willmsg") == 0)
  224. {
  225. strlcpy(confMqtt.mqtt_willMsg, value, sizeof(confMqtt.mqtt_willMsg));
  226. }
  227. else if (strcmp(param, "connmsg") == 0)
  228. {
  229. strlcpy(confMqtt.mqtt_connMsg, value, sizeof(confMqtt.mqtt_connMsg));
  230. }
  231. else if (strcmp(param, "hbenable") == 0)
  232. {
  233. if (atoi(value) == 1)
  234. confMqtt.mqtt_enable_heartbeat = true;
  235. else
  236. confMqtt.mqtt_enable_heartbeat = false;
  237. }
  238. else if (strcmp(param, "hbreconn") == 0)
  239. {
  240. int tmpval = atoi(value);
  241. if (tmpval == 0)
  242. confMqtt.mqtt_heartbeat_maxage_reconnect = 0;
  243. else if (tmpval >= 2 && tmpval <= 10)
  244. confMqtt.mqtt_heartbeat_maxage_reconnect = tmpval * 60000;
  245. }
  246. else if (strcmp(param, "hbreboot") == 0)
  247. {
  248. int tmpval = atoi(value);
  249. if (tmpval == 0)
  250. confMqtt.mqtt_heartbeat_maxage_reboot = 0;
  251. else if (tmpval >= 10 && tmpval <= 120)
  252. confMqtt.mqtt_heartbeat_maxage_reboot = tmpval * 60000;
  253. }
  254. // confBas
  255. else if (strcmp(param, "autosavetemp") == 0)
  256. {
  257. if (atoi(value) == 1)
  258. confBas.autoSaveSetTemp = true;
  259. else
  260. confBas.autoSaveSetTemp = false;
  261. }
  262. else if (strcmp(param, "autosavemode") == 0)
  263. {
  264. if (atoi(value) == 1)
  265. confBas.autoSaveHeatingMode = true;
  266. else
  267. confBas.autoSaveHeatingMode = false;
  268. }
  269. else if (strcmp(param, "savetomqttret") == 0)
  270. {
  271. if (atoi(value) == 1)
  272. confBas.saveToMqttRetained = true;
  273. else
  274. confBas.saveToMqttRetained = false;
  275. publishDeleteRetainedSavedStates();
  276. }
  277. else if (strcmp(param, "tempmin") == 0)
  278. {
  279. float valueFloat = round(atof(value) * 2.0) / 2.0;
  280. if (valueFloat >= 10 && valueFloat <= 16)
  281. {
  282. confBas.setTempMin = valueFloat;
  283. }
  284. }
  285. else if (strcmp(param, "tempmax") == 0)
  286. {
  287. float valueFloat = round(atof(value) * 2.0) / 2.0;
  288. if (valueFloat >= 18 && valueFloat <= 30)
  289. {
  290. confBas.setTempMax = valueFloat;
  291. }
  292. }
  293. else if (strcmp(param, "measint") == 0)
  294. {
  295. int valueInt = atoi(value);
  296. if (valueInt >= 5 && valueInt <= 120)
  297. {
  298. confBas.measureInterval = valueInt;
  299. }
  300. }
  301. else if (strcmp(param, "dispint") == 0)
  302. {
  303. int valueInt = atoi(value);
  304. if (valueInt >= 2 && valueInt <= 120)
  305. {
  306. confBas.displayInterval = valueInt;
  307. }
  308. }
  309. else if (strcmp(param, "disptout") == 0)
  310. {
  311. int valueInt = atoi(value);
  312. if (valueInt >= 2 && valueInt <= 1200)
  313. {
  314. confBas.displayTimeout = valueInt;
  315. }
  316. }
  317. else if (strcmp(param, "pirendisp") == 0)
  318. {
  319. int valueInt = atoi(value);
  320. if (valueInt == 1)
  321. confBas.PIR_enablesDisplay = true;
  322. else
  323. confBas.PIR_enablesDisplay = false;
  324. }
  325. else if (strcmp(param, "pirendispps0") == 0)
  326. {
  327. int valueInt = atoi(value);
  328. if (valueInt == 1)
  329. confBas.PIR_enablesDisplay_preset0only = true;
  330. else
  331. confBas.PIR_enablesDisplay_preset0only = false;
  332. }
  333. else if (strcmp(param, "togthdisp") == 0)
  334. {
  335. int valueInt = atoi(value);
  336. if (valueInt == 1)
  337. confBas.togglingTempHumAIDisplay = true;
  338. else
  339. confBas.togglingTempHumAIDisplay = false;
  340. }
  341. // confAdv
  342. else if (strcmp(param, "minofftime") == 0)
  343. {
  344. confAdv.heatingMinOffTime = atoi(value);
  345. }
  346. else if (strcmp(param, "tempdec") == 0)
  347. {
  348. float valueFloat = atof(value);
  349. if (valueFloat >= 0.0 && valueFloat <= 1.5)
  350. {
  351. confAdv.setTempDecreaseVal = valueFloat;
  352. }
  353. }
  354. else if (strcmp(param, "hyst") == 0)
  355. {
  356. float valueFloat = atof(value);
  357. if (valueFloat >= 0.1 && valueFloat <= 4.0)
  358. {
  359. confAdv.hysteresis = valueFloat;
  360. }
  361. }
  362. else if (strcmp(param, "tempcorr") == 0)
  363. {
  364. float valueFloat = atof(value);
  365. if (valueFloat >= -5.0 && valueFloat <= 5.0)
  366. {
  367. confAdv.tempCorrVal = valueFloat;
  368. }
  369. }
  370. else if (strcmp(param, "humcorr") == 0)
  371. {
  372. int valueInt = atoi(value);
  373. if (valueInt >= -40 && valueInt <= 40)
  374. {
  375. confAdv.humCorrVal = valueInt;
  376. }
  377. }
  378. else if (strcmp(param, "offmsg") == 0)
  379. {
  380. strlcpy(confAdv.offMessage, value, sizeof(confAdv.offMessage));
  381. }
  382. else if (strcmp(param, "modename0") == 0)
  383. {
  384. strlcpy(confAdv.modeName0, value, sizeof(confAdv.modeName0));
  385. }
  386. else if (strcmp(param, "modename1") == 0)
  387. {
  388. strlcpy(confAdv.modeName1, value, sizeof(confAdv.modeName1));
  389. }
  390. else if (strcmp(param, "psetname0") == 0)
  391. {
  392. strlcpy(confAdv.psetName0, value, sizeof(confAdv.psetName0));
  393. }
  394. else if (strcmp(param, "psetname1") == 0)
  395. {
  396. strlcpy(confAdv.psetName1, value, sizeof(confAdv.psetName1));
  397. }
  398. else if (strcmp(param, "psetname2") == 0)
  399. {
  400. strlcpy(confAdv.psetName2, value, sizeof(confAdv.psetName2));
  401. }
  402. else if (strcmp(param, "itemplab") == 0)
  403. {
  404. strlcpy(confAdv.iTempLabel, value, sizeof(confAdv.iTempLabel));
  405. }
  406. else if (strcmp(param, "otemplab") == 0)
  407. {
  408. strlcpy(confAdv.oTempLabel, value, sizeof(confAdv.oTempLabel));
  409. }
  410. // confAdd
  411. else if (strcmp(param, "outtemptop") == 0)
  412. {
  413. strlcpy(confAdd.outTemp_topic_in, value, sizeof(confAdd.outTemp_topic_in));
  414. }
  415. else if (strcmp(param, "outhumtop") == 0)
  416. {
  417. strlcpy(confAdd.outHum_topic_in, value, sizeof(confAdd.outHum_topic_in));
  418. }
  419. else if (strcmp(param, "pirtop") == 0)
  420. {
  421. strlcpy(confAdd.mqtt_topic_pir, value, sizeof(confAdd.mqtt_topic_pir));
  422. }
  423. else if (strcmp(param, "pironpld") == 0)
  424. {
  425. strlcpy(confAdd.mqtt_payload_pir_on, value, sizeof(confAdd.mqtt_payload_pir_on));
  426. }
  427. else if (strcmp(param, "piroffpld") == 0)
  428. {
  429. strlcpy(confAdd.mqtt_payload_pir_off, value, sizeof(confAdd.mqtt_payload_pir_off));
  430. }
  431. // confTime
  432. else if (strcmp(param, "tzstr") == 0)
  433. {
  434. strlcpy(confTime.timeZoneStr, value, sizeof(confTime.timeZoneStr));
  435. }
  436. else if (strcmp(param, "ntpenable") == 0)
  437. {
  438. int valueInt = atoi(value);
  439. if (valueInt == 1)
  440. confTime.ntpEnable = true;
  441. else
  442. confTime.ntpEnable = false;
  443. }
  444. else if (strcmp(param, "ntpserver1") == 0)
  445. {
  446. strlcpy(confTime.ntpServer1, value, sizeof(confTime.ntpServer1));
  447. }
  448. else if (strcmp(param, "ntpserver2") == 0)
  449. {
  450. strlcpy(confTime.ntpServer2, value, sizeof(confTime.ntpServer2));
  451. }
  452. else if (strcmp(param, "ntpsyncint") == 0)
  453. {
  454. confTime.ntpSyncInterval = atoi(value);
  455. }
  456. // confLog
  457. else if (strcmp(param, "loglevser") == 0)
  458. {
  459. int valueInt = atoi(value);
  460. if (valueInt >= 0 && valueInt <= 5)
  461. confLog.logLevelSerial = valueInt;
  462. }
  463. else if (strcmp(param, "loglevweb") == 0)
  464. {
  465. int valueInt = atoi(value);
  466. if (valueInt >= 0 && valueInt <= 5)
  467. confLog.logLevelWeb = valueInt;
  468. }
  469. else if (strcmp(param, "loglevmqtt") == 0)
  470. {
  471. int valueInt = atoi(value);
  472. if (valueInt >= 0 && valueInt <= 5)
  473. confLog.logLevelMqtt = valueInt;
  474. }
  475. }
  476. /*
  477. void getConfig(char *param)
  478. {
  479. // gets and prints the corresponding config variable for 'param'
  480. if (serialdebug)
  481. {
  482. Serial.print("getConfig - '");
  483. Serial.print(param);
  484. Serial.println("'");
  485. }
  486. char buf[101];
  487. // values
  488. if (strcmp(param, "temp") == 0)
  489. {
  490. char buf2[11];
  491. dtostrf(setTemp, 2, 1, buf2);
  492. sprintf(buf, "setTemp: '%s'", buf2);
  493. mqttSendLog(buf);
  494. }
  495. else if (strcmp(param, "tempLow") == 0)
  496. {
  497. char buf2[11];
  498. dtostrf(setTempLow, 2, 1, buf2);
  499. sprintf(buf, "setTempLow: '%s'", buf2);
  500. mqttSendLog(buf);
  501. }
  502. else if (strcmp(param, "tempLow2") == 0)
  503. {
  504. char buf2[11];
  505. dtostrf(setTempLow2, 2, 1, buf2);
  506. sprintf(buf, "setTempLow2: '%s'", buf2);
  507. mqttSendLog(buf);
  508. }
  509. else if (strcmp(param, "mode") == 0)
  510. {
  511. sprintf(buf, "heatingMode: '%d'", heatingMode);
  512. mqttSendLog(buf);
  513. }
  514. else if (strcmp(param, "preset") == 0)
  515. {
  516. sprintf(buf, "preset: '%d'", preset);
  517. mqttSendLog(buf);
  518. }
  519. // confdata
  520. else if (strcmp(param, "devName") == 0)
  521. {
  522. sprintf(buf, "devName: '%s'", deviceName);
  523. mqttSendLog(buf);
  524. }
  525. else if (strcmp(param, "hostName") == 0)
  526. {
  527. sprintf(buf, "hostName: '%s'", hostName);
  528. mqttSendLog(buf);
  529. }
  530. else if (strcmp(param, "wifiappw") == 0)
  531. {
  532. sprintf(buf, "wifiappw: '%s'", WiFiAPModePassword);
  533. mqttSendLog(buf);
  534. }
  535. else if (strcmp(param, "httpUser") == 0)
  536. {
  537. sprintf(buf, "httpUser: '%s'", http_user);
  538. mqttSendLog(buf);
  539. }
  540. else if (strcmp(param, "httpPass") == 0)
  541. {
  542. sprintf(buf, "httpPass: '%s'", http_pass);
  543. mqttSendLog(buf);
  544. }
  545. else if (strcmp(param, "httpToken") == 0)
  546. {
  547. sprintf(buf, "httpToken: '%s'", http_token);
  548. mqttSendLog(buf);
  549. }
  550. else if (strcmp(param, "mqttHost") == 0)
  551. {
  552. sprintf(buf, "mqttHost: '%s'", mqtt_server);
  553. mqttSendLog(buf);
  554. }
  555. else if (strcmp(param, "mqttPort") == 0)
  556. {
  557. sprintf(buf, "mqttPort: '%d'", mqtt_port);
  558. mqttSendLog(buf);
  559. }
  560. else if (strcmp(param, "mqttUser") == 0)
  561. {
  562. sprintf(buf, "mqttUser: '%s'", mqtt_user);
  563. mqttSendLog(buf);
  564. }
  565. else if (strcmp(param, "mqttPass") == 0)
  566. {
  567. sprintf(buf, "mqttPass: '%s'", mqtt_pass);
  568. mqttSendLog(buf);
  569. }
  570. else if (strcmp(param, "inTop") == 0)
  571. {
  572. sprintf(buf, "inTop: '%s'", mqtt_topic_in);
  573. mqttSendLog(buf);
  574. }
  575. else if (strcmp(param, "outTop") == 0)
  576. {
  577. sprintf(buf, "outTop: '%s'", mqtt_topic_out);
  578. mqttSendLog(buf);
  579. }
  580. else if (strcmp(param, "outRet") == 0)
  581. {
  582. char buf2[11];
  583. if (mqtt_outRetain)
  584. strcpy(buf2, "1");
  585. else
  586. strcpy(buf2, "0");
  587. sprintf(buf, "outRet: '%s'", buf2);
  588. mqttSendLog(buf);
  589. }
  590. else if (strcmp(param, "willTop") == 0)
  591. {
  592. sprintf(buf, "willTop: '%s'", mqtt_willTopic);
  593. mqttSendLog(buf);
  594. }
  595. else if (strcmp(param, "willQos") == 0)
  596. {
  597. sprintf(buf, "willQos: '%d'", mqtt_willQos);
  598. mqttSendLog(buf);
  599. }
  600. else if (strcmp(param, "willRet") == 0)
  601. {
  602. char buf2[11];
  603. if (mqtt_willRetain)
  604. strcpy(buf2, "1");
  605. else
  606. strcpy(buf2, "0");
  607. sprintf(buf, "willRet: '%s'", buf2);
  608. mqttSendLog(buf);
  609. }
  610. else if (strcmp(param, "willMsg") == 0)
  611. {
  612. sprintf(buf, "willMsg: '%s'", mqtt_willMsg);
  613. mqttSendLog(buf);
  614. }
  615. else if (strcmp(param, "connMsg") == 0)
  616. {
  617. sprintf(buf, "connMsg: '%s'", mqtt_connMsg);
  618. mqttSendLog(buf);
  619. }
  620. // confdata2
  621. else if (strcmp(param, "outTempTop") == 0)
  622. {
  623. sprintf(buf, "outTempTop: '%s'", outTemp_topic_in);
  624. mqttSendLog(buf);
  625. }
  626. else if (strcmp(param, "outHumTop") == 0)
  627. {
  628. sprintf(buf, "outHumTop: '%s'", outHum_topic_in);
  629. mqttSendLog(buf);
  630. }
  631. else if (strcmp(param, "PIRTop") == 0)
  632. {
  633. sprintf(buf, "PIRTop: '%s'", mqtt_topic_pir);
  634. mqttSendLog(buf);
  635. }
  636. else if (strcmp(param, "autoSaveTemp") == 0)
  637. {
  638. char buf2[11];
  639. if (autoSaveSetTemp)
  640. strcpy(buf2, "1");
  641. else
  642. strcpy(buf2, "0");
  643. sprintf(buf, "autoSaveTemp: '%s'", buf2);
  644. mqttSendLog(buf);
  645. }
  646. else if (strcmp(param, "autoSaveMode") == 0)
  647. {
  648. char buf2[11];
  649. if (autoSaveHeatingMode)
  650. strcpy(buf2, "1");
  651. else
  652. strcpy(buf2, "0");
  653. sprintf(buf, "autoSaveMode: '%s'", buf2);
  654. mqttSendLog(buf);
  655. }
  656. else if (strcmp(param, "minOffTime") == 0)
  657. {
  658. sprintf(buf, "minOffTime: '%d'", heatingMinOffTime);
  659. mqttSendLog(buf);
  660. }
  661. else if (strcmp(param, "tempMin") == 0)
  662. {
  663. char buf2[11];
  664. dtostrf(setTempMin, 2, 1, buf2);
  665. sprintf(buf, "tempMin: '%s'", buf2);
  666. mqttSendLog(buf);
  667. }
  668. else if (strcmp(param, "tempMax") == 0)
  669. {
  670. char buf2[11];
  671. dtostrf(setTempMax, 2, 1, buf2);
  672. sprintf(buf, "tempMax: '%s'", buf2);
  673. mqttSendLog(buf);
  674. }
  675. else if (strcmp(param, "tempDec") == 0)
  676. {
  677. char buf2[11];
  678. dtostrf(setTempDecreaseVal, 2, 1, buf2);
  679. sprintf(buf, "tempDec: '%s'", buf2);
  680. mqttSendLog(buf);
  681. }
  682. else if (strcmp(param, "hyst") == 0)
  683. {
  684. char buf2[11];
  685. dtostrf(hysteresis, 2, 1, buf2);
  686. sprintf(buf, "hyst: '%s'", buf2);
  687. mqttSendLog(buf);
  688. }
  689. else if (strcmp(param, "tempCorr") == 0)
  690. {
  691. char buf2[11];
  692. dtostrf(tempCorrVal, 2, 1, buf2);
  693. sprintf(buf, "tempCorr: '%s'", buf2);
  694. mqttSendLog(buf);
  695. }
  696. else if (strcmp(param, "humCorr") == 0)
  697. {
  698. sprintf(buf, "humCorr: '%d'", humCorrVal);
  699. mqttSendLog(buf);
  700. }
  701. else if (strcmp(param, "measInt") == 0)
  702. {
  703. sprintf(buf, "measInt: '%d'", measureInterval);
  704. mqttSendLog(buf);
  705. }
  706. else if (strcmp(param, "dispInt") == 0)
  707. {
  708. sprintf(buf, "dispInt: '%d'", displayInterval);
  709. mqttSendLog(buf);
  710. }
  711. else if (strcmp(param, "dispTout") == 0)
  712. {
  713. sprintf(buf, "dispTout: '%d'", displayTimeout);
  714. mqttSendLog(buf);
  715. }
  716. else if (strcmp(param, "offMsg") == 0)
  717. {
  718. sprintf(buf, "offMsg: '%s'", offMessage);
  719. mqttSendLog(buf);
  720. }
  721. else if (strcmp(param, "modename0") == 0)
  722. {
  723. sprintf(buf, "modename0: '%s'", modename0);
  724. mqttSendLog(buf);
  725. }
  726. else if (strcmp(param, "modename1") == 0)
  727. {
  728. sprintf(buf, "modename1: '%s'", modename1);
  729. mqttSendLog(buf);
  730. }
  731. else if (strcmp(param, "psetname0") == 0)
  732. {
  733. sprintf(buf, "psetname0: '%s'", psetname0);
  734. mqttSendLog(buf);
  735. }
  736. else if (strcmp(param, "psetname1") == 0)
  737. {
  738. sprintf(buf, "psetname1: '%s'", psetname1);
  739. mqttSendLog(buf);
  740. }
  741. else if (strcmp(param, "psetname2") == 0)
  742. {
  743. sprintf(buf, "psetname2: '%s'", psetname2);
  744. mqttSendLog(buf);
  745. }
  746. else if (strcmp(param, "itemplab") == 0)
  747. {
  748. sprintf(buf, "itemplab: '%s'", itemplab);
  749. mqttSendLog(buf);
  750. }
  751. else if (strcmp(param, "otemplab") == 0)
  752. {
  753. sprintf(buf, "otemplab: '%s'", otemplab);
  754. mqttSendLog(buf);
  755. }
  756. else if (strcmp(param, "PIRenDisp") == 0)
  757. {
  758. char buf2[11];
  759. if (PIR_enablesDisplay)
  760. strcpy(buf2, "1");
  761. else
  762. strcpy(buf2, "0");
  763. sprintf(buf, "pirEnDisp: '%d'", PIR_enablesDisplay);
  764. mqttSendLog(buf);
  765. }
  766. else if (strcmp(param, "togTHdisp") == 0)
  767. {
  768. char buf2[11];
  769. if (togglingTempHumAIDisplay)
  770. strcpy(buf2, "1");
  771. else
  772. strcpy(buf2, "0");
  773. sprintf(buf, "togTHdisp: '%d'", togglingTempHumAIDisplay);
  774. mqttSendLog(buf);
  775. }
  776. }*/
  777. void printConfigDevWiFi()
  778. {
  779. // prints current config vars to serial
  780. Serial.print("\nconfDataDevWiFi: ");
  781. Serial.print("devName: ");
  782. Serial.print(confDevWiFi.deviceName);
  783. Serial.print(", hostName: ");
  784. Serial.print(confDevWiFi.hostName);
  785. Serial.print(", WiFiSSID1: ");
  786. Serial.print(confDevWiFi.WiFiSSID1);
  787. //Serial.print(", WiFiPW1: ");
  788. //Serial.print(confDevWiFi.WiFiPW1);
  789. Serial.print(", WiFiSSID2: ");
  790. Serial.print(confDevWiFi.WiFiSSID2);
  791. //Serial.print(", WiFiPW2: ");
  792. //Serial.print(confDevWiFi.WiFiPW2);
  793. Serial.print(", WiFiAPModePassword: ");
  794. Serial.print(confDevWiFi.WiFiAPModePassword);
  795. Serial.print(", WiFiAPModeTimeout: ");
  796. Serial.print(confDevWiFi.WiFiAPModeTimeout);
  797. Serial.print(", WiFiConnCheckInterval: ");
  798. Serial.print(confDevWiFi.WiFiConnCheckInterval);
  799. Serial.print(", WiFiRetryInterval: ");
  800. Serial.print(confDevWiFi.WiFiRetryInterval);
  801. Serial.print(", WiFiRebootNoConnect: ");
  802. Serial.print(confDevWiFi.WiFiRebootOnNoConnect);
  803. Serial.println();
  804. }
  805. void printConfigWeb()
  806. {
  807. // prints current config vars to serial
  808. Serial.print("\nconfDataWeb: ");
  809. Serial.print("apiToken: ");
  810. Serial.print(confWeb.http_token);
  811. Serial.print(", httpUA: ");
  812. Serial.print(confWeb.http_user);
  813. //Serial.print(", httpPA: ");
  814. //Serial.print(confWeb.http_pass);
  815. Serial.print(", httpAuth: ");
  816. Serial.print(confWeb.http_user_auth);
  817. Serial.print(", httpU1: ");
  818. Serial.print(confWeb.http_user1);
  819. //Serial.print(", httpP1: ");
  820. //Serial.print(confWeb.http_pass1);
  821. Serial.print(", httpU2: ");
  822. Serial.print(confWeb.http_user2);
  823. //Serial.print(", httpP2: ");
  824. //Serial.print(confWeb.http_pass2);
  825. Serial.println();
  826. }
  827. void printConfigMqtt()
  828. {
  829. // prints current config vars to serial
  830. Serial.print("\nconfDataMqtt: ");
  831. Serial.print("mqttEnable: ");
  832. Serial.print(confMqtt.mqtt_enable);
  833. Serial.print(", mqttHost: ");
  834. Serial.print(confMqtt.mqtt_server);
  835. Serial.print(", mqttPort: ");
  836. Serial.print(confMqtt.mqtt_port);
  837. Serial.print(", mqttUser: ");
  838. Serial.print(confMqtt.mqtt_user);
  839. //Serial.print(", mqttPass: ");
  840. //Serial.print(confMqtt.mqtt_pass);
  841. Serial.print(", inTop: ");
  842. Serial.print(confMqtt.mqtt_topic_in);
  843. Serial.print(", outTop: ");
  844. Serial.print(confMqtt.mqtt_topic_out);
  845. Serial.print(", outRet: ");
  846. Serial.print(confMqtt.mqtt_outRetain);
  847. Serial.print(", outRetSens: ");
  848. Serial.print(confMqtt.mqtt_outRetain_sensors);
  849. Serial.print(", outPubInt: ");
  850. Serial.print(confMqtt.mqtt_outPubInterval);
  851. Serial.print(", outPubIntSens: ");
  852. Serial.print(confMqtt.mqtt_outPubInterval_sensors);
  853. Serial.print(", willTop: ");
  854. Serial.print(confMqtt.mqtt_willTopic);
  855. Serial.print(", willQos: ");
  856. Serial.print(confMqtt.mqtt_willQos);
  857. Serial.print(", willRet: ");
  858. Serial.print(confMqtt.mqtt_willRetain);
  859. Serial.print(", willMsg: ");
  860. Serial.print(confMqtt.mqtt_willMsg);
  861. Serial.print(", connMsg: ");
  862. Serial.print(confMqtt.mqtt_connMsg);
  863. Serial.print(", hbEnable: ");
  864. Serial.print(confMqtt.mqtt_enable_heartbeat);
  865. Serial.print(", hbReconn: ");
  866. Serial.print(confMqtt.mqtt_heartbeat_maxage_reconnect);
  867. Serial.print(", hbReboot: ");
  868. Serial.print(confMqtt.mqtt_heartbeat_maxage_reboot);
  869. Serial.println();
  870. }
  871. boolean loadConfigDevWiFi()
  872. {
  873. char configFileName[] = "/confDevWiFi.json";
  874. if (SPIFFS.exists(configFileName))
  875. {
  876. File configFile = SPIFFS.open(configFileName, "r");
  877. if (!configFile)
  878. {
  879. Serial.print(F("ERR: Failed to open file '"));
  880. Serial.print(configFileName);
  881. Serial.println("'");
  882. return false;
  883. }
  884. else
  885. {
  886. Serial.print("file '");
  887. Serial.print(configFileName);
  888. Serial.print("' opened. ");
  889. size_t size = configFile.size();
  890. Serial.print("size=");
  891. Serial.println(size);
  892. if (size > 1000)
  893. {
  894. Serial.println(F("Config file size is too large"));
  895. return false;
  896. }
  897. std::unique_ptr<char[]> buf(new char[size]);
  898. #ifdef DEBUGMODE
  899. Serial.println(F("file content:"));
  900. while (configFile.available())
  901. {
  902. Serial.write(configFile.read());
  903. }
  904. Serial.println();
  905. configFile.seek(0, SeekSet); // reset so that we can read again
  906. #endif
  907. configFile.readBytes(buf.get(), size);
  908. DynamicJsonDocument json(size + 50);
  909. DeserializationError error = deserializeJson(json, buf.get());
  910. if (error)
  911. {
  912. Serial.println(F("Failed to parse config file"));
  913. return false;
  914. }
  915. strlcpy(confDevWiFi.deviceName, json["devName"] | "", sizeof(confDevWiFi.deviceName));
  916. strlcpy(confDevWiFi.hostName, json["hostName"] | "", sizeof(confDevWiFi.hostName));
  917. strlcpy(confDevWiFi.WiFiSSID1, json["SSID1"] | "", sizeof(confDevWiFi.WiFiSSID1));
  918. strlcpy(confDevWiFi.WiFiPW1, json["WPW1"] | "", sizeof(confDevWiFi.WiFiPW1));
  919. strlcpy(confDevWiFi.WiFiSSID2, json["SSID2"] | "", sizeof(confDevWiFi.WiFiSSID2));
  920. strlcpy(confDevWiFi.WiFiPW2, json["WPW2"] | "", sizeof(confDevWiFi.WiFiPW2));
  921. strlcpy(confDevWiFi.WiFiAPModePassword, json["WPWAP"] | "", sizeof(confDevWiFi.WiFiAPModePassword));
  922. confDevWiFi.WiFiAPModeTimeout = json["WAPtout"] | DEFAULT_WIFI_APMODE_TIMEOUT;
  923. confDevWiFi.WiFiRetryInterval = json["Wretry"] | DEFAULT_WIFI_RETRY_INTERVAL;
  924. confDevWiFi.WiFiConnCheckInterval = json["WConnCheck"] | DEFAULT_WIFI_CONNCHECK_INTERVAL;
  925. confDevWiFi.WiFiRebootOnNoConnect = json["Wreboot"] | DEFAULT_WIFI_REBOOT_ONNOCONNECT;
  926. Serial.println(F("Loaded config values:"));
  927. printConfigDevWiFi();
  928. return true;
  929. }
  930. configFile.close();
  931. }
  932. else
  933. {
  934. Serial.print(F("NOTE: could not load confDevWiFi - file '"));
  935. Serial.print(configFileName);
  936. Serial.println(F("' does not exist."));
  937. return false;
  938. }
  939. } // loadConfigDevWiFi
  940. boolean loadConfigWeb()
  941. { // loadConfigWeb
  942. char configFileName[] = "/confWeb.json";
  943. if (SPIFFS.exists(configFileName))
  944. {
  945. File configFile = SPIFFS.open(configFileName, "r");
  946. if (!configFile)
  947. {
  948. Serial.print(F("ERR: Failed to open file '"));
  949. Serial.print(configFileName);
  950. Serial.println("'");
  951. return false;
  952. }
  953. else
  954. {
  955. Serial.print("file '");
  956. Serial.print(configFileName);
  957. Serial.print("' opened. ");
  958. size_t size = configFile.size();
  959. Serial.print("size=");
  960. Serial.println(size);
  961. if (size > 1000)
  962. {
  963. Serial.println(F("Config file size is too large"));
  964. return false;
  965. }
  966. std::unique_ptr<char[]> buf(new char[size]);
  967. #ifdef DEBUGMODE
  968. Serial.println(F("file content:"));
  969. while (configFile.available())
  970. {
  971. Serial.write(configFile.read());
  972. }
  973. Serial.println();
  974. configFile.seek(0, SeekSet); // reset so that we can read again
  975. #endif
  976. configFile.readBytes(buf.get(), size);
  977. DynamicJsonDocument json(size + 50);
  978. DeserializationError error = deserializeJson(json, buf.get());
  979. if (error)
  980. {
  981. Serial.println(F("Failed to parse config file"));
  982. return false;
  983. }
  984. strlcpy(confWeb.http_token, json["apiToken"] | "", sizeof(confWeb.http_token));
  985. strlcpy(confWeb.http_user, json["httpUA"] | "", sizeof(confWeb.http_user));
  986. strlcpy(confWeb.http_pass, json["httpPA"] | "", sizeof(confWeb.http_pass));
  987. if ((json["httpAuth"] | 0) == 1)
  988. confWeb.http_user_auth = true;
  989. else
  990. confWeb.http_user_auth = false;
  991. strlcpy(confWeb.http_user1, json["httpU1"] | "", sizeof(confWeb.http_user1));
  992. strlcpy(confWeb.http_pass1, json["httpP1"] | "", sizeof(confWeb.http_pass1));
  993. strlcpy(confWeb.http_user2, json["httpU2"] | "", sizeof(confWeb.http_user2));
  994. strlcpy(confWeb.http_pass2, json["httpP2"] | "", sizeof(confWeb.http_pass2));
  995. if ((json["enableConsole"] | 0) == 1)
  996. confWeb.enableConsole = true;
  997. else
  998. confWeb.enableConsole = false;
  999. Serial.println(F("Loaded config values:"));
  1000. printConfigWeb();
  1001. return true;
  1002. }
  1003. configFile.close();
  1004. }
  1005. else
  1006. {
  1007. Serial.print(F("NOTE: could not load confWeb - file '"));
  1008. Serial.print(configFileName);
  1009. Serial.println(F("' does not exist."));
  1010. return false;
  1011. }
  1012. } // loadConfigWeb
  1013. boolean loadConfigMqtt()
  1014. { // loadConfigMqtt
  1015. char configFileName[] = "/confMqtt.json";
  1016. if (SPIFFS.exists(configFileName))
  1017. {
  1018. File configFile = SPIFFS.open(configFileName, "r");
  1019. if (!configFile)
  1020. {
  1021. Serial.print(F("ERR: Failed to open file '"));
  1022. Serial.print(configFileName);
  1023. Serial.println("'");
  1024. return false;
  1025. }
  1026. else
  1027. {
  1028. Serial.print("file '");
  1029. Serial.print(configFileName);
  1030. Serial.print("' opened. ");
  1031. size_t size = configFile.size();
  1032. Serial.print("size=");
  1033. Serial.println(size);
  1034. if (size > 1000)
  1035. {
  1036. Serial.println(F("Config file size is too large"));
  1037. return false;
  1038. }
  1039. std::unique_ptr<char[]> buf(new char[size]);
  1040. #ifdef DEBUGMODE
  1041. Serial.println(F("file content:"));
  1042. while (configFile.available())
  1043. {
  1044. Serial.write(configFile.read());
  1045. }
  1046. Serial.println();
  1047. configFile.seek(0, SeekSet); // reset so that we can read again
  1048. #endif
  1049. configFile.readBytes(buf.get(), size);
  1050. DynamicJsonDocument json(size + 50);
  1051. DeserializationError error = deserializeJson(json, buf.get());
  1052. if (error)
  1053. {
  1054. Serial.println(F("Failed to parse config file"));
  1055. return false;
  1056. }
  1057. if ((json["mqttEnable"] | 0) == 1)
  1058. confMqtt.mqtt_enable = true;
  1059. else
  1060. confMqtt.mqtt_enable = false;
  1061. strlcpy(confMqtt.mqtt_server, json["mqttHost"] | "", sizeof(confMqtt.mqtt_server));
  1062. confMqtt.mqtt_port = json["mqttPort"] | 1883;
  1063. strlcpy(confMqtt.mqtt_user, json["mqttUser"] | "", sizeof(confMqtt.mqtt_user));
  1064. strlcpy(confMqtt.mqtt_pass, json["mqttPass"] | "", sizeof(confMqtt.mqtt_pass));
  1065. strlcpy(confMqtt.mqtt_topic_in, json["inTop"] | "", sizeof(confMqtt.mqtt_topic_in));
  1066. strlcpy(confMqtt.mqtt_topic_out, json["outTop"] | "", sizeof(confMqtt.mqtt_topic_out));
  1067. if ((json["outRet"] | 0) == 1)
  1068. confMqtt.mqtt_outRetain = true;
  1069. else
  1070. confMqtt.mqtt_outRetain = false;
  1071. if ((json["outRetSens"] | 0) == 1)
  1072. confMqtt.mqtt_outRetain_sensors = true;
  1073. else
  1074. confMqtt.mqtt_outRetain_sensors = false;
  1075. confMqtt.mqtt_outPubInterval = json["outPubInt"] | MQTT_OUT_PUBLISH_INTERVAL;
  1076. confMqtt.mqtt_outPubInterval_sensors = json["outPubIntSens"] | MQTT_OUT_PUBLISH_INTERVAL_SENSORS;
  1077. strlcpy(confMqtt.mqtt_willTopic, json["willTop"] | "", sizeof(confMqtt.mqtt_willTopic));
  1078. confMqtt.mqtt_willQos = json["willQos"] | 0;
  1079. if ((json["willRet"] | 0) == 1)
  1080. confMqtt.mqtt_willRetain = true;
  1081. else
  1082. confMqtt.mqtt_willRetain = false;
  1083. strlcpy(confMqtt.mqtt_willMsg, json["willMsg"] | "", sizeof(confMqtt.mqtt_willMsg));
  1084. strlcpy(confMqtt.mqtt_connMsg, json["connMsg"] | "", sizeof(confMqtt.mqtt_connMsg));
  1085. if ((json["hbEnable"] | 0) == 1)
  1086. confMqtt.mqtt_enable_heartbeat = true;
  1087. else
  1088. confMqtt.mqtt_enable_heartbeat = false;
  1089. uint16_t tmpval;
  1090. tmpval = json["hbReconn"] | 0;
  1091. if (tmpval == 0)
  1092. confMqtt.mqtt_heartbeat_maxage_reconnect = 0;
  1093. else if (tmpval >= 2 && tmpval <= 10)
  1094. confMqtt.mqtt_heartbeat_maxage_reconnect = tmpval * 60000;
  1095. tmpval = json["hbReboot"] | 0;
  1096. if (tmpval == 0)
  1097. confMqtt.mqtt_heartbeat_maxage_reboot = 0;
  1098. else if (tmpval >= 2 && tmpval <= 10)
  1099. confMqtt.mqtt_heartbeat_maxage_reboot = tmpval * 60000;
  1100. Serial.println(F("Loaded config values:"));
  1101. printConfigMqtt();
  1102. return true;
  1103. }
  1104. configFile.close();
  1105. }
  1106. else
  1107. {
  1108. Serial.print(F("NOTE: could not load confMqtt - file '"));
  1109. Serial.print(configFileName);
  1110. Serial.println(F("' does not exist."));
  1111. return false;
  1112. }
  1113. } // loadConfigMqtt
  1114. boolean loadConfigBas()
  1115. {
  1116. char configFileName[] = "/confBas.json";
  1117. if (SPIFFS.exists(configFileName))
  1118. {
  1119. File configFile = SPIFFS.open(configFileName, "r");
  1120. if (!configFile)
  1121. {
  1122. Serial.print(F("ERR: Failed to open file '"));
  1123. Serial.print(configFileName);
  1124. Serial.println("'");
  1125. return false;
  1126. }
  1127. else
  1128. {
  1129. Serial.print("file '");
  1130. Serial.print(configFileName);
  1131. Serial.print("' opened. ");
  1132. size_t size = configFile.size();
  1133. Serial.print("size=");
  1134. Serial.println(size);
  1135. if (size > 1000)
  1136. {
  1137. Serial.println(F("Config file size is too large"));
  1138. return false;
  1139. }
  1140. std::unique_ptr<char[]> buf(new char[size]);
  1141. #ifdef DEBUGMODE
  1142. Serial.println(F("file content:"));
  1143. while (configFile.available())
  1144. {
  1145. Serial.write(configFile.read());
  1146. }
  1147. Serial.println();
  1148. configFile.seek(0, SeekSet); // reset so that we can read again
  1149. #endif
  1150. configFile.readBytes(buf.get(), size);
  1151. DynamicJsonDocument json(size + 50);
  1152. DeserializationError error = deserializeJson(json, buf.get());
  1153. if (error)
  1154. {
  1155. Serial.println(F("Failed to parse config file"));
  1156. return false;
  1157. }
  1158. if ((json["autoSaveTemp"] | 0) == 1)
  1159. confBas.autoSaveSetTemp = true;
  1160. else
  1161. confBas.autoSaveSetTemp = false;
  1162. if ((json["autoSaveMode"] | 0) == 1)
  1163. confBas.autoSaveHeatingMode = true;
  1164. else
  1165. confBas.autoSaveHeatingMode = false;
  1166. if ((json["saveToMqttRet"] | 0) == 1)
  1167. confBas.saveToMqttRetained = true;
  1168. else
  1169. confBas.saveToMqttRetained = false;
  1170. if ((json["PIRenDisp"] | 0) == 1)
  1171. confBas.PIR_enablesDisplay = true;
  1172. else
  1173. confBas.PIR_enablesDisplay = false;
  1174. if ((json["PIRenDispPs0"] | 0) == 1)
  1175. confBas.PIR_enablesDisplay_preset0only = true;
  1176. else
  1177. confBas.PIR_enablesDisplay_preset0only = false;
  1178. if ((json["togTHdisp"] | 0) == 1)
  1179. confBas.togglingTempHumAIDisplay = true;
  1180. else
  1181. confBas.togglingTempHumAIDisplay = false;
  1182. confBas.setTempMin = json["tempMin"] | DEFAULT_SETTEMP_MIN;
  1183. confBas.setTempMax = json["tempMax"] | DEFAULT_SETTEMP_MAX;
  1184. confBas.measureInterval = json["measInt"] | DEFAULT_MEASURE_INTERVAL;
  1185. confBas.displayInterval = json["dispInt"] | DEFAULT_DISPLAY_INTERVAL;
  1186. confBas.displayTimeout = json["dispTout"] | DEFAULT_DISPLAY_TIMEOUT;
  1187. // Serial.println(F("Loaded config values:"));
  1188. // printConfigBas();
  1189. return true;
  1190. }
  1191. configFile.close();
  1192. }
  1193. else
  1194. {
  1195. Serial.print(F("NOTE: could not load confBas - file '"));
  1196. Serial.print(configFileName);
  1197. Serial.println(F("' does not exist."));
  1198. return false;
  1199. }
  1200. } // loadConfigBas
  1201. boolean loadConfigAdv()
  1202. {
  1203. char configFileName[] = "/confAdv.json";
  1204. if (SPIFFS.exists(configFileName))
  1205. {
  1206. File configFile = SPIFFS.open(configFileName, "r");
  1207. if (!configFile)
  1208. {
  1209. Serial.print(F("ERR: Failed to open file '"));
  1210. Serial.print(configFileName);
  1211. Serial.println("'");
  1212. return false;
  1213. }
  1214. else
  1215. {
  1216. Serial.print("file '");
  1217. Serial.print(configFileName);
  1218. Serial.print("' opened. ");
  1219. size_t size = configFile.size();
  1220. Serial.print("size=");
  1221. Serial.println(size);
  1222. if (size > 1000)
  1223. {
  1224. Serial.println(F("Config file size is too large"));
  1225. return false;
  1226. }
  1227. std::unique_ptr<char[]> buf(new char[size]);
  1228. #ifdef DEBUGMODE
  1229. Serial.println(F("file content:"));
  1230. while (configFile.available())
  1231. {
  1232. Serial.write(configFile.read());
  1233. }
  1234. Serial.println();
  1235. configFile.seek(0, SeekSet); // reset so that we can read again
  1236. #endif
  1237. configFile.readBytes(buf.get(), size);
  1238. DynamicJsonDocument json(size + 50);
  1239. DeserializationError error = deserializeJson(json, buf.get());
  1240. if (error)
  1241. {
  1242. Serial.println(F("Failed to parse config file"));
  1243. return false;
  1244. }
  1245. confAdv.hysteresis = json["hyst"] | 0.1;
  1246. confAdv.heatingMinOffTime = json["minOffTime"] | 120;
  1247. confAdv.tempCorrVal = json["tempCorr"] | 0;
  1248. confAdv.humCorrVal = json["humCorr"] | 0;
  1249. confAdv.setTempDecreaseVal = json["tempDec"] | 0;
  1250. strlcpy(confAdv.offMessage, json["offMsg"] | "", sizeof(confAdv.offMessage));
  1251. strlcpy(confAdv.iTempLabel, json["iTempLab"] | "", sizeof(confAdv.iTempLabel));
  1252. strlcpy(confAdv.oTempLabel, json["oTempLab"] | "", sizeof(confAdv.oTempLabel));
  1253. strlcpy(confAdv.modeName0, json["modeName0"] | "", sizeof(confAdv.modeName0));
  1254. strlcpy(confAdv.modeName1, json["modeName1"] | "", sizeof(confAdv.modeName1));
  1255. strlcpy(confAdv.psetName0, json["psetName0"] | "", sizeof(confAdv.psetName0));
  1256. strlcpy(confAdv.psetName1, json["psetName1"] | "", sizeof(confAdv.psetName1));
  1257. strlcpy(confAdv.psetName2, json["psetName2"] | "", sizeof(confAdv.psetName2));
  1258. // Serial.println("Loaded config values:");
  1259. // printConfigWeb();
  1260. return true;
  1261. }
  1262. configFile.close();
  1263. }
  1264. else
  1265. {
  1266. Serial.print(F("NOTE: could not load confAdv - file '"));
  1267. Serial.print(configFileName);
  1268. Serial.println(F("' does not exist."));
  1269. return false;
  1270. }
  1271. } // loadConfigAdv
  1272. boolean loadConfigAdd()
  1273. {
  1274. char configFileName[] = "/confAdd.json";
  1275. if (SPIFFS.exists(configFileName))
  1276. {
  1277. File configFile = SPIFFS.open(configFileName, "r");
  1278. if (!configFile)
  1279. {
  1280. Serial.print(F("ERR: Failed to open file '"));
  1281. Serial.print(configFileName);
  1282. Serial.println("'");
  1283. return false;
  1284. }
  1285. else
  1286. {
  1287. Serial.print("file '");
  1288. Serial.print(configFileName);
  1289. Serial.print("' opened. ");
  1290. size_t size = configFile.size();
  1291. Serial.print("size=");
  1292. Serial.println(size);
  1293. if (size > 1000)
  1294. {
  1295. Serial.println(F("Config file size is too large"));
  1296. return false;
  1297. }
  1298. std::unique_ptr<char[]> buf(new char[size]);
  1299. #ifdef DEBUGMODE
  1300. Serial.println(F("file content:"));
  1301. while (configFile.available())
  1302. {
  1303. Serial.write(configFile.read());
  1304. }
  1305. Serial.println();
  1306. configFile.seek(0, SeekSet); // reset so that we can read again
  1307. #endif
  1308. configFile.readBytes(buf.get(), size);
  1309. DynamicJsonDocument json(size + 50);
  1310. DeserializationError error = deserializeJson(json, buf.get());
  1311. if (error)
  1312. {
  1313. Serial.println(F("Failed to parse config file"));
  1314. return false;
  1315. }
  1316. strlcpy(confAdd.mqtt_topic_pir, json["PIRTop"] | "", sizeof(confAdd.mqtt_topic_pir));
  1317. strlcpy(confAdd.mqtt_payload_pir_on, json["PIROnPld"] | "", sizeof(confAdd.mqtt_payload_pir_on));
  1318. strlcpy(confAdd.mqtt_payload_pir_off, json["PIROffPld"] | "", sizeof(confAdd.mqtt_payload_pir_off));
  1319. strlcpy(confAdd.outTemp_topic_in, json["outTempTop"] | "", sizeof(confAdd.outTemp_topic_in));
  1320. strlcpy(confAdd.outHum_topic_in, json["outHumTop"] | "", sizeof(confAdd.outHum_topic_in));
  1321. // Serial.println("Loaded config values:");
  1322. // printConfigWeb();
  1323. return true;
  1324. }
  1325. configFile.close();
  1326. }
  1327. else
  1328. {
  1329. Serial.print(F("NOTE: could not load confAdd - file '"));
  1330. Serial.print(configFileName);
  1331. Serial.println(F("' does not exist."));
  1332. return false;
  1333. }
  1334. } // loadConfigAdd
  1335. boolean loadConfigTime()
  1336. {
  1337. char configFileName[] = "/confTime.json";
  1338. if (SPIFFS.exists(configFileName))
  1339. {
  1340. File configFile = SPIFFS.open(configFileName, "r");
  1341. if (!configFile)
  1342. {
  1343. Serial.print(F("ERR: Failed to open file '"));
  1344. Serial.print(configFileName);
  1345. Serial.println("'");
  1346. return false;
  1347. }
  1348. else
  1349. {
  1350. Serial.print("file '");
  1351. Serial.print(configFileName);
  1352. Serial.print("' opened. ");
  1353. size_t size = configFile.size();
  1354. Serial.print("size=");
  1355. Serial.println(size);
  1356. if (size > 1000)
  1357. {
  1358. Serial.println(F("Config file size is too large"));
  1359. return false;
  1360. }
  1361. std::unique_ptr<char[]> buf(new char[size]);
  1362. #ifdef DEBUGMODE
  1363. Serial.println(F("file content:"));
  1364. while (configFile.available())
  1365. {
  1366. Serial.write(configFile.read());
  1367. }
  1368. Serial.println();
  1369. configFile.seek(0, SeekSet); // reset so that we can read again
  1370. #endif
  1371. configFile.readBytes(buf.get(), size);
  1372. DynamicJsonDocument json(size + 50);
  1373. DeserializationError error = deserializeJson(json, buf.get());
  1374. if (error)
  1375. {
  1376. Serial.println(F("Failed to parse config file"));
  1377. return false;
  1378. }
  1379. if ((json["NTPEnable"] | 0) == 1)
  1380. confTime.ntpEnable = true;
  1381. else
  1382. confTime.ntpEnable = false;
  1383. strlcpy(confTime.ntpServer1, json["NTPServer1"] | "", sizeof(confTime.ntpServer1));
  1384. strlcpy(confTime.ntpServer2, json["NTPServer2"] | "", sizeof(confTime.ntpServer2));
  1385. confTime.ntpSyncInterval = json["NTPSyncInt"];
  1386. strlcpy(confTime.timeZoneStr, json["TZstr"] | "", sizeof(confTime.timeZoneStr));
  1387. // Serial.println("Loaded config values:");
  1388. // printConfigWeb();
  1389. return true;
  1390. }
  1391. configFile.close();
  1392. }
  1393. else
  1394. {
  1395. Serial.print(F("NOTE: could not load confTime - file '"));
  1396. Serial.print(configFileName);
  1397. Serial.println(F("' does not exist."));
  1398. return false;
  1399. }
  1400. } // loadConfigTime
  1401. boolean loadConfigLog()
  1402. {
  1403. char configFileName[] = "/confLog.json";
  1404. if (SPIFFS.exists(configFileName))
  1405. {
  1406. File configFile = SPIFFS.open(configFileName, "r");
  1407. if (!configFile)
  1408. {
  1409. Serial.print(F("ERR: Failed to open file '"));
  1410. Serial.print(configFileName);
  1411. Serial.println("'");
  1412. return false;
  1413. }
  1414. else
  1415. {
  1416. Serial.print("file '");
  1417. Serial.print(configFileName);
  1418. Serial.print("' opened. ");
  1419. size_t size = configFile.size();
  1420. Serial.print("size=");
  1421. Serial.println(size);
  1422. if (size > 1000)
  1423. {
  1424. Serial.println(F("Config file size is too large"));
  1425. return false;
  1426. }
  1427. std::unique_ptr<char[]> buf(new char[size]);
  1428. #ifdef DEBUGMODE
  1429. Serial.println(F("file content:"));
  1430. while (configFile.available())
  1431. {
  1432. Serial.write(configFile.read());
  1433. }
  1434. Serial.println();
  1435. configFile.seek(0, SeekSet); // reset so that we can read again
  1436. #endif
  1437. configFile.readBytes(buf.get(), size);
  1438. DynamicJsonDocument json(size + 50);
  1439. DeserializationError error = deserializeJson(json, buf.get());
  1440. if (error)
  1441. {
  1442. Serial.println(F("Failed to parse config file"));
  1443. return false;
  1444. }
  1445. //if ((json["NTPEnable"] | 0) == 1)
  1446. // confTime.ntpEnable = true;
  1447. //else
  1448. // confTime.ntpEnable = false;
  1449. confLog.logLevelSerial = json["logLevSer"];
  1450. confLog.logLevelWeb = json["logLevWeb"];
  1451. confLog.logLevelMqtt = json["logLevMqtt"];
  1452. // Serial.println("Loaded config values:");
  1453. // printConfigWeb();
  1454. return true;
  1455. }
  1456. configFile.close();
  1457. }
  1458. else
  1459. {
  1460. Serial.print(F("NOTE: could not load confTime - file '"));
  1461. Serial.print(configFileName);
  1462. Serial.println(F("' does not exist."));
  1463. return false;
  1464. }
  1465. } // loadConfigLog
  1466. boolean loadSetTemp()
  1467. { // loadSetTemp
  1468. File configFile = SPIFFS.open("/setTemp", "r");
  1469. if (!configFile)
  1470. {
  1471. Serial.println(F("NOTE: Failed to open file /setTemp"));
  1472. return false;
  1473. }
  1474. String s = configFile.readStringUntil('\n');
  1475. configFile.close();
  1476. float tmpSetTemp = s.toFloat();
  1477. if (tmpSetTemp >= confBas.setTempMin && tmpSetTemp <= confBas.setTempMax)
  1478. {
  1479. setTemp = tmpSetTemp;
  1480. setTempSaved = tmpSetTemp;
  1481. return true;
  1482. }
  1483. else
  1484. return false;
  1485. } // loadSetTemp
  1486. boolean loadSetTempLow()
  1487. { // loadSetTempLow
  1488. File configFile = SPIFFS.open("/setTempLow", "r");
  1489. if (!configFile)
  1490. {
  1491. Serial.println(F("NOTE: Failed to open file /setTempLow"));
  1492. return false;
  1493. }
  1494. String s = configFile.readStringUntil('\n');
  1495. configFile.close();
  1496. float tmpSetTempLow = s.toFloat();
  1497. if (tmpSetTempLow >= setTempLowMin && tmpSetTempLow <= setTempLowMax)
  1498. {
  1499. setTempLow = tmpSetTempLow;
  1500. setTempLowSaved = tmpSetTempLow;
  1501. return true;
  1502. }
  1503. else
  1504. return false;
  1505. } // loadSetTempLow
  1506. boolean loadSetTempLow2()
  1507. { // loadSetTempLow2
  1508. File configFile = SPIFFS.open("/setTempLow2", "r");
  1509. if (!configFile)
  1510. {
  1511. Serial.println(F("NOTE: Failed to open file /setTempLow2"));
  1512. return false;
  1513. }
  1514. String s = configFile.readStringUntil('\n');
  1515. configFile.close();
  1516. float tmpSetTempLow2 = s.toFloat();
  1517. if (tmpSetTempLow2 >= setTempLowMin && tmpSetTempLow2 <= setTempLowMax)
  1518. {
  1519. setTempLow2 = tmpSetTempLow2;
  1520. setTempLow2Saved = tmpSetTempLow2;
  1521. return true;
  1522. }
  1523. else
  1524. return false;
  1525. } // loadSetTempLow2
  1526. boolean loadHeatingMode()
  1527. { // loadHeatingMode
  1528. File configFile = SPIFFS.open("/heatingMode", "r");
  1529. if (!configFile)
  1530. {
  1531. Serial.println(F("NOTE: Failed to open file /heatingMode"));
  1532. return false;
  1533. }
  1534. String s = configFile.readStringUntil('\n');
  1535. configFile.close();
  1536. int tmpHeatingMode = s.toInt();
  1537. if (tmpHeatingMode >= 0 && tmpHeatingMode <= 1)
  1538. {
  1539. heatingMode = tmpHeatingMode;
  1540. heatingModeSaved = tmpHeatingMode;
  1541. return true;
  1542. }
  1543. else
  1544. return false;
  1545. } // loadHeatingMode
  1546. boolean loadPreset()
  1547. { // loadPreset
  1548. File configFile = SPIFFS.open("/preset", "r");
  1549. if (!configFile)
  1550. {
  1551. Serial.println(F("NOTE: Failed to open file /preset"));
  1552. return false;
  1553. }
  1554. String s = configFile.readStringUntil('\n');
  1555. configFile.close();
  1556. int tmpPreset = s.toInt();
  1557. if (tmpPreset >= 0 && tmpPreset <= 2)
  1558. {
  1559. preset = tmpPreset;
  1560. presetSaved = tmpPreset;
  1561. return true;
  1562. }
  1563. else
  1564. return false;
  1565. } // loadPreset
  1566. boolean saveConfigWeb()
  1567. { // saveConfig
  1568. char configFileName[] = "/confWeb.json";
  1569. DynamicJsonDocument json(1050);
  1570. json["apiToken"] = confWeb.http_token;
  1571. json["httpUA"] = confWeb.http_user;
  1572. json["httpPA"] = confWeb.http_pass;
  1573. if (confWeb.http_user_auth)
  1574. json["httpAuth"] = 1;
  1575. else
  1576. json["httpAuth"] = 0;
  1577. json["httpU1"] = confWeb.http_user1;
  1578. json["httpP1"] = confWeb.http_pass1;
  1579. json["httpU2"] = confWeb.http_user2;
  1580. json["httpP2"] = confWeb.http_pass2;
  1581. if (confWeb.enableConsole)
  1582. json["enableConsole"] = 1;
  1583. else
  1584. json["enableConsole"] = 0;
  1585. yield();
  1586. File configFile = SPIFFS.open(configFileName, "w");
  1587. if (!configFile)
  1588. {
  1589. Serial.print("Failed to open file '");
  1590. Serial.print(configFileName);
  1591. Serial.println("' for writing");
  1592. return false;
  1593. }
  1594. serializeJson(json, configFile);
  1595. return true;
  1596. } // saveConfigWeb
  1597. boolean saveConfigMqtt()
  1598. { // safeConfig
  1599. char configFileName[] = "/confMqtt.json";
  1600. DynamicJsonDocument json(1050);
  1601. if (confMqtt.mqtt_enable)
  1602. json["mqttEnable"] = 1;
  1603. else
  1604. json["mqttEnable"] = 0;
  1605. json["mqttHost"] = confMqtt.mqtt_server;
  1606. json["mqttPort"] = confMqtt.mqtt_port;
  1607. json["mqttUser"] = confMqtt.mqtt_user;
  1608. json["mqttPass"] = confMqtt.mqtt_pass;
  1609. json["inTop"] = confMqtt.mqtt_topic_in;
  1610. json["outTop"] = confMqtt.mqtt_topic_out;
  1611. if (confMqtt.mqtt_outRetain)
  1612. json["outRet"] = 1;
  1613. else
  1614. json["outRet"] = 0;
  1615. if (confMqtt.mqtt_outRetain_sensors)
  1616. json["outRetSens"] = 1;
  1617. else
  1618. json["outRetSens"] = 0;
  1619. json["outPubInt"] = confMqtt.mqtt_outPubInterval;
  1620. json["outPubIntSens"] = confMqtt.mqtt_outPubInterval_sensors;
  1621. json["willTop"] = confMqtt.mqtt_willTopic;
  1622. json["willQos"] = confMqtt.mqtt_willQos;
  1623. if (confMqtt.mqtt_willRetain)
  1624. json["willRet"] = 1;
  1625. else
  1626. json["willRet"] = 0;
  1627. json["willMsg"] = confMqtt.mqtt_willMsg;
  1628. json["connMsg"] = confMqtt.mqtt_connMsg;
  1629. if (confMqtt.mqtt_enable_heartbeat)
  1630. json["hbEnable"] = 1;
  1631. else
  1632. json["hbEnable"] = 0;
  1633. json["hbReconn"] = confMqtt.mqtt_heartbeat_maxage_reconnect / 60000;
  1634. json["hbReboot"] = confMqtt.mqtt_heartbeat_maxage_reboot / 60000;
  1635. yield();
  1636. File configFile = SPIFFS.open(configFileName, "w");
  1637. if (!configFile)
  1638. {
  1639. Serial.print("Failed to open file '");
  1640. Serial.print(configFileName);
  1641. Serial.println("' for writing");
  1642. return false;
  1643. }
  1644. serializeJson(json, configFile);
  1645. return true;
  1646. } // saveConfigMqtt
  1647. boolean saveConfigDevWiFi()
  1648. { // saveConfig
  1649. char configFileName[] = "/confDevWiFi.json";
  1650. DynamicJsonDocument json(1050);
  1651. json["devName"] = confDevWiFi.deviceName;
  1652. json["hostName"] = confDevWiFi.hostName;
  1653. json["SSID1"] = confDevWiFi.WiFiSSID1;
  1654. json["WPW1"] = confDevWiFi.WiFiPW1;
  1655. json["SSID2"] = confDevWiFi.WiFiSSID2;
  1656. json["WPW2"] = confDevWiFi.WiFiPW2;
  1657. json["WPWAP"] = confDevWiFi.WiFiAPModePassword;
  1658. json["WAPtout"] = confDevWiFi.WiFiAPModeTimeout;
  1659. json["WConnCheck"] = confDevWiFi.WiFiConnCheckInterval;
  1660. json["Wretry"] = confDevWiFi.WiFiRetryInterval;
  1661. json["Wreboot"] = confDevWiFi.WiFiRebootOnNoConnect;
  1662. yield();
  1663. File configFile = SPIFFS.open(configFileName, "w");
  1664. if (!configFile)
  1665. {
  1666. Serial.print("Failed to open file '");
  1667. Serial.print(configFileName);
  1668. Serial.println("' for writing");
  1669. return false;
  1670. }
  1671. serializeJson(json, configFile);
  1672. return true;
  1673. } // saveConfigDev
  1674. boolean saveConfigBas()
  1675. { // safeConfig
  1676. char configFileName[] = "/confBas.json";
  1677. DynamicJsonDocument json(1050);
  1678. if (confBas.autoSaveSetTemp)
  1679. json["autoSaveTemp"] = 1;
  1680. else
  1681. json["autoSaveTemp"] = 0;
  1682. if (confBas.autoSaveHeatingMode)
  1683. json["autoSaveMode"] = 1;
  1684. else
  1685. json["autoSaveMode"] = 0;
  1686. if (confBas.saveToMqttRetained)
  1687. json["saveToMqttRet"] = 1;
  1688. else
  1689. json["saveToMqttRet"] = 0;
  1690. json["tempMin"] = confBas.setTempMin;
  1691. json["tempMax"] = confBas.setTempMax;
  1692. json["measInt"] = confBas.measureInterval;
  1693. json["dispInt"] = confBas.displayInterval;
  1694. json["dispTout"] = confBas.displayTimeout;
  1695. if (confBas.PIR_enablesDisplay)
  1696. json["PIRenDisp"] = 1;
  1697. else
  1698. json["PIRenDisp"] = 0;
  1699. if (confBas.PIR_enablesDisplay_preset0only)
  1700. json["PIRenDispPs0"] = 1;
  1701. else
  1702. json["PIRenDispPs0"] = 0;
  1703. if (confBas.togglingTempHumAIDisplay)
  1704. json["togTHdisp"] = 1;
  1705. else
  1706. json["togTHdisp"] = 0;
  1707. yield();
  1708. File configFile = SPIFFS.open(configFileName, "w");
  1709. if (!configFile)
  1710. {
  1711. Serial.print("Failed to open file '");
  1712. Serial.print(configFileName);
  1713. Serial.println("' for writing");
  1714. return false;
  1715. }
  1716. serializeJson(json, configFile);
  1717. return true;
  1718. } // saveConfigBas
  1719. boolean saveConfigAdv()
  1720. { // safeConfig
  1721. char configFileName[] = "/confAdv.json";
  1722. DynamicJsonDocument json(1050);
  1723. json["hyst"] = confAdv.hysteresis;
  1724. json["minOffTime"] = confAdv.heatingMinOffTime;
  1725. json["tempCorr"] = confAdv.tempCorrVal;
  1726. json["humCorr"] = confAdv.humCorrVal;
  1727. json["tempDec"] = confAdv.setTempDecreaseVal;
  1728. json["offMsg"] = confAdv.offMessage;
  1729. json["iTempLab"] = confAdv.iTempLabel;
  1730. json["oTempLab"] = confAdv.oTempLabel;
  1731. json["modeName0"] = confAdv.modeName0;
  1732. json["modeName1"] = confAdv.modeName1;
  1733. json["psetName0"] = confAdv.psetName0;
  1734. json["psetName1"] = confAdv.psetName1;
  1735. json["psetName2"] = confAdv.psetName2;
  1736. yield();
  1737. File configFile = SPIFFS.open(configFileName, "w");
  1738. if (!configFile)
  1739. {
  1740. Serial.print("Failed to open file '");
  1741. Serial.print(configFileName);
  1742. Serial.println("' for writing");
  1743. return false;
  1744. }
  1745. serializeJson(json, configFile);
  1746. return true;
  1747. } // saveConfigAdv
  1748. boolean saveConfigAdd()
  1749. { // safeConfig
  1750. char configFileName[] = "/confAdd.json";
  1751. DynamicJsonDocument json(1050);
  1752. json["PIRTop"] = confAdd.mqtt_topic_pir;
  1753. json["PIROnPld"] = confAdd.mqtt_payload_pir_on;
  1754. json["PIROffPld"] = confAdd.mqtt_payload_pir_off;
  1755. json["outTempTop"] = confAdd.outTemp_topic_in;
  1756. json["outHumTop"] = confAdd.outHum_topic_in;
  1757. yield();
  1758. File configFile = SPIFFS.open(configFileName, "w");
  1759. if (!configFile)
  1760. {
  1761. Serial.print("Failed to open file '");
  1762. Serial.print(configFileName);
  1763. Serial.println("' for writing");
  1764. return false;
  1765. }
  1766. serializeJson(json, configFile);
  1767. return true;
  1768. } // saveConfigAdd
  1769. boolean saveConfigTime()
  1770. {
  1771. char configFileName[] = "/confTime.json";
  1772. DynamicJsonDocument json(1050);
  1773. if(confTime.ntpEnable) json["NTPEnable"] = 1;
  1774. else json["NTPEnable"] = 0;
  1775. json["NTPServer1"] = confTime.ntpServer1;
  1776. json["NTPServer2"] = confTime.ntpServer2;
  1777. json["NTPSyncInt"] = confTime.ntpSyncInterval;
  1778. json["TZstr"] = confTime.timeZoneStr;
  1779. yield();
  1780. File configFile = SPIFFS.open(configFileName, "w");
  1781. if (!configFile)
  1782. {
  1783. Serial.print("Failed to open file '");
  1784. Serial.print(configFileName);
  1785. Serial.println("' for writing");
  1786. return false;
  1787. }
  1788. serializeJson(json, configFile);
  1789. return true;
  1790. } // saveConfigTime
  1791. boolean saveConfigLog()
  1792. {
  1793. char configFileName[] = "/confLog.json";
  1794. DynamicJsonDocument json(1050);
  1795. //if(confTime.ntpEnable) json["NTPEnable"] = 1;
  1796. //else json["NTPEnable"] = 0;
  1797. json["logLevSer"] = confLog.logLevelSerial;
  1798. json["logLevWeb"] = confLog.logLevelWeb;
  1799. json["logLevMqtt"] = confLog.logLevelMqtt;
  1800. yield();
  1801. File configFile = SPIFFS.open(configFileName, "w");
  1802. if (!configFile)
  1803. {
  1804. Serial.print("Failed to open file '");
  1805. Serial.print(configFileName);
  1806. Serial.println("' for writing");
  1807. return false;
  1808. }
  1809. serializeJson(json, configFile);
  1810. return true;
  1811. } // saveConfigLog
  1812. boolean saveSetTemp()
  1813. { // saveSetTemp
  1814. File configFile = SPIFFS.open("/setTemp", "w");
  1815. if (!configFile)
  1816. {
  1817. Serial.println("Failed to open setTemp file for writing");
  1818. return false;
  1819. }
  1820. configFile.println(setTemp);
  1821. configFile.close();
  1822. setTempSaved = setTemp;
  1823. return true;
  1824. } // saveSetTemp
  1825. boolean saveSetTempLow()
  1826. { // saveSetTempLow
  1827. File configFile = SPIFFS.open("/setTempLow", "w");
  1828. if (!configFile)
  1829. {
  1830. Serial.println("Failed to open setTempLow file for writing");
  1831. return false;
  1832. }
  1833. configFile.println(setTempLow);
  1834. configFile.close();
  1835. setTempLowSaved = setTempLow;
  1836. return true;
  1837. } // saveSetTempLow
  1838. boolean saveSetTempLow2()
  1839. { // saveSetTempLow
  1840. File configFile = SPIFFS.open("/setTempLow2", "w");
  1841. if (!configFile)
  1842. {
  1843. Serial.println("Failed to open setTempLow2 file for writing");
  1844. return false;
  1845. }
  1846. configFile.println(setTempLow2);
  1847. configFile.close();
  1848. setTempLow2Saved = setTempLow2;
  1849. return true;
  1850. } // saveSetTempLow
  1851. boolean saveHeatingMode()
  1852. { // saveHeatingMode
  1853. File configFile = SPIFFS.open("/heatingMode", "w");
  1854. if (!configFile)
  1855. {
  1856. Serial.println("Failed to open heatingMode file for writing");
  1857. return false;
  1858. }
  1859. configFile.println(heatingMode);
  1860. configFile.close();
  1861. heatingModeSaved = heatingMode;
  1862. return true;
  1863. } // saveHeatingMode
  1864. boolean savePreset()
  1865. { // savePreset
  1866. File configFile = SPIFFS.open("/preset", "w");
  1867. if (!configFile)
  1868. {
  1869. Serial.println("Failed to open preset file for writing");
  1870. return false;
  1871. }
  1872. configFile.println(preset);
  1873. configFile.close();
  1874. presetSaved = preset;
  1875. return true;
  1876. } // savePreset
  1877. void deleteConfig()
  1878. {
  1879. Serial.println("deleting configuration");
  1880. SPIFFS_format();
  1881. delay(100);
  1882. ESP.restart();
  1883. }
  1884. void loadConf_all()
  1885. {
  1886. loadConfigDevWiFi();
  1887. loadConfigWeb();
  1888. loadConfigMqtt();
  1889. loadConfigBas();
  1890. loadConfigAdv();
  1891. loadConfigAdd();
  1892. loadConfigTime();
  1893. loadConfigLog();
  1894. }
  1895. void loadSavedValues()
  1896. {
  1897. loadSetTemp();
  1898. loadSetTempLow();
  1899. loadSetTempLow2();
  1900. loadHeatingMode();
  1901. loadPreset();
  1902. }
  1903. void SPIFFS_format()
  1904. {
  1905. Serial.println(F("formatting SPIFFS, please wait 30 secs"));
  1906. SPIFFS.format();
  1907. Serial.println(F("SPIFFS formatted"));
  1908. File f = SPIFFS.open("/formatted", "w");
  1909. if (!f)
  1910. {
  1911. Serial.println(F("creating file '/formatted' failed"));
  1912. }
  1913. else
  1914. {
  1915. f.println(F("Format Complete"));
  1916. }
  1917. f.close();
  1918. }
  1919. void SPIFFS_formatIfIsnt()
  1920. {
  1921. if (!SPIFFS.exists("/formatted"))
  1922. {
  1923. SPIFFS_format();
  1924. }
  1925. // else
  1926. //{
  1927. // if (serialdebug)
  1928. // Serial.println(F("SPIFFS is formatted. Moving along..."));
  1929. //}
  1930. }
  1931. void SPIFFS_listFiles()
  1932. {
  1933. Serial.println(F("files in SPIFFS:"));
  1934. Dir dir = SPIFFS.openDir("/");
  1935. while (dir.next())
  1936. {
  1937. Serial.print(dir.fileName());
  1938. File f = dir.openFile("r");
  1939. Serial.print(" ");
  1940. Serial.println(f.size());
  1941. f.close();
  1942. }
  1943. Serial.println(F("----"));
  1944. }
  1945. void loadConf_defaults()
  1946. {
  1947. // confDev
  1948. // strlcpy(deviceName, DEVICE_NAME, sizeof(deviceName));
  1949. strlcpy(confDevWiFi.hostName, HOST_NAME, sizeof(confDevWiFi.hostName));
  1950. strlcpy(confDevWiFi.WiFiAPModePassword, WIFI_APMODE_PASSWORD, sizeof(confDevWiFi.WiFiAPModePassword));
  1951. // confWeb
  1952. strlcpy(confWeb.http_token, HTTP_SET_TOKEN, sizeof(confWeb.http_token));
  1953. strlcpy(confWeb.http_user, DEFAULT_HTTP_USER, sizeof(confWeb.http_user));
  1954. strlcpy(confWeb.http_pass, DEFAULT_HTTP_PASS, sizeof(confWeb.http_pass));
  1955. confWeb.http_user_auth = DEFAULT_HTTP_USER_AUTH;
  1956. // confMqtt
  1957. confMqtt.mqtt_enable = MQTT_ENABLE;
  1958. strlcpy(confMqtt.mqtt_server, MQTT_SERVER, sizeof(confMqtt.mqtt_server));
  1959. confMqtt.mqtt_port = MQTT_PORT;
  1960. strlcpy(confMqtt.mqtt_user, MQTT_USER, sizeof(confMqtt.mqtt_user));
  1961. strlcpy(confMqtt.mqtt_pass, MQTT_PASS, sizeof(confMqtt.mqtt_pass));
  1962. strlcpy(confMqtt.mqtt_topic_in, MQTT_TOPIC_IN, sizeof(confMqtt.mqtt_topic_in));
  1963. strlcpy(confMqtt.mqtt_topic_out, MQTT_TOPIC_OUT, sizeof(confMqtt.mqtt_topic_out));
  1964. strlcpy(confMqtt.mqtt_willTopic, MQTT_WILLTOPIC, sizeof(confMqtt.mqtt_willTopic));
  1965. confMqtt.mqtt_willQos = MQTT_WILLQOS;
  1966. confMqtt.mqtt_willRetain = MQTT_WILLRETAIN;
  1967. strlcpy(confMqtt.mqtt_willMsg, MQTT_WILLMSG, sizeof(confMqtt.mqtt_willMsg));
  1968. strlcpy(confMqtt.mqtt_connMsg, MQTT_CONNMSG, sizeof(confMqtt.mqtt_connMsg));
  1969. confMqtt.mqtt_outRetain = MQTT_OUT_RETAIN;
  1970. confMqtt.mqtt_outRetain_sensors = MQTT_OUT_RETAIN_SENSORS;
  1971. confMqtt.mqtt_enable_heartbeat = MQTT_ENABLE_HEARTBEAT;
  1972. confMqtt.mqtt_heartbeat_maxage_reconnect = MQTT_HEARTBEAT_MAXAGE;
  1973. confMqtt.mqtt_heartbeat_maxage_reboot = MQTT_HEARTBEAT_MAXAGE_REBOOT;
  1974. // confBas
  1975. confBas.setTempMin = DEFAULT_SETTEMP_MIN;
  1976. confBas.setTempMax = DEFAULT_SETTEMP_MAX;
  1977. confBas.autoSaveSetTemp = AUTOSAVE_SETTEMP;
  1978. confBas.autoSaveHeatingMode = AUTOSAVE_SETMODE;
  1979. confBas.saveToMqttRetained = SAVE_TO_MQTT_RETAINED;
  1980. confBas.measureInterval = DEFAULT_MEASURE_INTERVAL;
  1981. confBas.displayInterval = DEFAULT_DISPLAY_INTERVAL;
  1982. confBas.displayTimeout = DEFAULT_DISPLAY_TIMEOUT;
  1983. confBas.PIR_enablesDisplay = DEFAULT_PIR_ENABLES_DISPLAY;
  1984. confBas.PIR_enablesDisplay_preset0only = DEFAULT_PIR_ENABLES_DISPLAY_PRESET0_ONLY;
  1985. confBas.togglingTempHumAIDisplay = DEFAULT_TOGGLING_I_O_TEMPHUM;
  1986. // confAdv
  1987. confAdv.hysteresis = DEFAULT_HYSTERESIS;
  1988. confAdv.heatingMinOffTime = DEFAULT_HEATING_MIN_OFFTIME;
  1989. confAdv.tempCorrVal = TEMPSENSOR_CORRECTION_VALUE;
  1990. confAdv.humCorrVal = HUMSENSOR_CORRECTION_VALUE;
  1991. confAdv.setTempDecreaseVal = SETTEMP_DECREASE_VALUE;
  1992. strlcpy(confAdv.offMessage, OFF_MESSAGE, sizeof(confAdv.offMessage));
  1993. strlcpy(confAdv.iTempLabel, INSIDE_TEMP_LABEL, sizeof(confAdv.iTempLabel));
  1994. strlcpy(confAdv.oTempLabel, OUTSIDE_TEMP_LABEL, sizeof(confAdv.oTempLabel));
  1995. strlcpy(confAdv.modeName0, MODE_NAME_0, sizeof(confAdv.modeName0));
  1996. strlcpy(confAdv.modeName1, MODE_NAME_1, sizeof(confAdv.modeName1));
  1997. strlcpy(confAdv.psetName0, PRESET_NAME_0, sizeof(confAdv.psetName0));
  1998. strlcpy(confAdv.psetName1, PRESET_NAME_1, sizeof(confAdv.psetName1));
  1999. strlcpy(confAdv.psetName2, PRESET_NAME_2, sizeof(confAdv.psetName2));
  2000. // confAdd
  2001. strlcpy(confAdd.mqtt_topic_pir, MQTT_TOPIC_PIR, sizeof(confAdd.mqtt_topic_pir));
  2002. strlcpy(confAdd.mqtt_payload_pir_on, MQTT_TOPIC_PIR_ON, sizeof(confAdd.mqtt_payload_pir_on));
  2003. strlcpy(confAdd.mqtt_payload_pir_off, MQTT_TOPIC_PIR_OFF, sizeof(confAdd.mqtt_payload_pir_off));
  2004. strlcpy(confAdd.outTemp_topic_in, OUTTEMP_TOPIC_IN, sizeof(confAdd.outTemp_topic_in));
  2005. strlcpy(confAdd.outHum_topic_in, OUTHUM_TOPIC_IN, sizeof(confAdd.outHum_topic_in));
  2006. // confTime
  2007. strlcpy(confTime.timeZoneStr, TIMEZONE, sizeof(confTime.timeZoneStr));
  2008. strlcpy(confTime.ntpServer1, NTP_SERVER, sizeof(confTime.ntpServer1));
  2009. confTime.ntpSyncInterval = NTP_SYNC_INTERVAL;
  2010. // confLog
  2011. confLog.logLevelSerial = DEFAULT_LOGLEVEL_SERIAL;
  2012. confLog.logLevelWeb = DEFAULT_LOGLEVEL_WEB;
  2013. confLog.logLevelMqtt = DEFAULT_LOGLEVEL_MQTT;
  2014. confLog.logLevelSyslog = DEFAULT_LOGLEVEL_SYSLOG;
  2015. }
  2016. void loadConf_restoreDefaultWhenMissing()
  2017. {
  2018. if (strlen(confDevWiFi.deviceName) < 4)
  2019. createDeviceName();
  2020. if (confAdv.modeName0[0] == '\0')
  2021. strlcpy(confAdv.modeName0, MODE_NAME_0, sizeof(confAdv.modeName0));
  2022. if (confAdv.modeName1[0] == '\0')
  2023. strlcpy(confAdv.modeName1, MODE_NAME_1, sizeof(confAdv.modeName1));
  2024. if (confAdv.psetName0[0] == '\0')
  2025. strlcpy(confAdv.psetName0, PRESET_NAME_0, sizeof(confAdv.psetName0));
  2026. if (confAdv.psetName1[0] == '\0')
  2027. strlcpy(confAdv.psetName1, PRESET_NAME_1, sizeof(confAdv.psetName1));
  2028. if (confAdv.psetName2[0] == '\0')
  2029. strlcpy(confAdv.psetName2, PRESET_NAME_2, sizeof(confAdv.psetName2));
  2030. if (confAdv.iTempLabel[0] == '\0')
  2031. strlcpy(confAdv.iTempLabel, INSIDE_TEMP_LABEL, sizeof(confAdv.iTempLabel));
  2032. if (confAdv.oTempLabel[0] == '\0')
  2033. strlcpy(confAdv.oTempLabel, OUTSIDE_TEMP_LABEL, sizeof(confAdv.oTempLabel));
  2034. if(confDevWiFi.WiFiConnCheckInterval == 0) confDevWiFi.WiFiConnCheckInterval = DEFAULT_WIFI_CONNCHECK_INTERVAL;
  2035. //NTP
  2036. if(strlen(confTime.ntpServer1) == 0) strlcpy(confTime.ntpServer1, NTP_SERVER, sizeof(confTime.ntpServer1));
  2037. }