fp_controller.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. #include <sys/cdefs.h>
  2. /**
  3. * @Author: 李建
  4. * @Date: 2025/3/25 15:23
  5. * Description: 空调控制器
  6. * Copyright: Copyright (©) 2025 永续绿建. All rights reserved.
  7. */
  8. #include <esp_log.h>
  9. #include "freertos/FreeRTOS.h"
  10. #include <freertos/task.h>
  11. #include <cJSON.h>
  12. #include <esp_timer.h>
  13. #include "fp_controller.h"
  14. #include "sub_device/command.h"
  15. #include "modbus_master.h"
  16. #include "system/miscellaneous_interface.h"
  17. #include "lvgl_port.h"
  18. #include "main.h"
  19. #include "esp_modbus_master.h"
  20. #include "mb_endianness_utils.h"
  21. #include "modbus_slave.h"
  22. #include "pwm0_10.h"
  23. #include "sht30.h"
  24. #include "relay.h"
  25. #include "gateway/access.h"
  26. #define FAN_RELAY 1
  27. // #define FAN_PWM 1
  28. static const char *TAG = "xf_controller";
  29. static uint8_t err_count = 0;// 通讯失败次数
  30. static SemaphoreHandle_t report_task_sem; // 上报任务信号量,用于实现操作完成上立即上报当前状态
  31. extern void set_ac_mode(lv_ui *ui, uint16_t mode);
  32. static TaskHandle_t cloud_report_handle;
  33. static TaskHandle_t report_trigger_handle;
  34. static TaskHandle_t status_task_handle;
  35. // 初始化空调参数
  36. ac_status_t ac_status = {
  37. .power= 0,
  38. .fan_speed=3,
  39. .mode=1,
  40. .set_temp = 16,
  41. .filter_used_time=0,
  42. .filter_life_remaining=100,
  43. .error_code=0,
  44. };
  45. xf_fault_t xf_fault[9] = {
  46. {
  47. .code="E1",
  48. .description="传感器故障",
  49. },
  50. {
  51. .code="E2",
  52. .description="高水位故障",
  53. },
  54. {
  55. .code="E3",
  56. .description="进水电磁阀故障",
  57. },
  58. {
  59. .code="E4",
  60. .description="送风风机故障",
  61. },
  62. {
  63. .code="E5",
  64. .description="排风风机故障",
  65. },
  66. {
  67. .code="E6",
  68. .description="排水泵故障",
  69. },
  70. {
  71. .code="E7",
  72. .description="通讯故障",
  73. },
  74. {
  75. .code="E8",
  76. .description="预留",
  77. }
  78. };
  79. void read_xf_status(system_setting_t *setting) {
  80. uint16_t *_power = nvs_get_uint16(NVS_POWER_CONTROLLER);
  81. uint16_t *_mode = nvs_get_uint16(NVS_MODEL_CONTROLLER);
  82. uint16_t *_fan_speed = nvs_get_uint16(NVS_FAN_SPEED_SET);
  83. uint16_t *_filter_used_time = nvs_get_uint16(NVS_FILTER_USED_TIME);
  84. uint16_t *_set_temp = nvs_get_uint16(NVS_AC_SET_TEMP_KEY);
  85. uint16_t *_filter_life_remaining = nvs_get_uint16(NVS_FILTER_USED_TIME);
  86. uint16_t *_tw_status = nvs_get_uint16(NVS_TW_STATUS);
  87. uint16_t *_xf_mode = nvs_get_uint16(NVS_AC_SET_TEMP_KEY);
  88. ac_status.power= _power == NULL ? 0 : *_power;
  89. ac_status.mode = _mode == NULL ? 1 : *_mode;
  90. ac_status.fan_speed = _fan_speed == NULL ? 3 : *_fan_speed;
  91. ac_status.set_temp = _set_temp == NULL ? 16 : *_set_temp;
  92. ac_status.filter_used_time = _filter_used_time == NULL ? 0 : *_filter_used_time;
  93. ac_status.filter_life_remaining=_filter_life_remaining == NULL ? 0 : *_filter_life_remaining;
  94. ac_status.tw_status=_tw_status == NULL ? 0 : *_tw_status;
  95. ac_status.xf_mode=_xf_mode == NULL ? 0 : *_xf_mode;
  96. }
  97. esp_err_t ac_set_temp(bool saved) {
  98. if (saved)
  99. nvs_set_uint16(ac_status.set_temp, NVS_AC_SET_TEMP_KEY);
  100. if (cloud_connected) {
  101. xSemaphoreGive(report_task_sem);
  102. }
  103. modbus_set_reg(SLAVE_SET_TEMP_REG_ADDRESS, ac_status.set_temp);
  104. return ESP_OK;
  105. }
  106. // 设置电源
  107. esp_err_t ac_set_power(bool saved) {
  108. esp_err_t err = ESP_OK;
  109. if(saved)
  110. nvs_set_uint16(ac_status.power, NVS_POWER_CONTROLLER);
  111. if (guider_ui.screen_main) {
  112. if(ac_status.power==0)
  113. {
  114. lvgl_port_lock(-1);
  115. // lv_obj_add_flag(guider_ui.screen_main_cont_humSet, LV_OBJ_FLAG_HIDDEN);
  116. lv_obj_add_flag(guider_ui.screen_main_cont_mode, LV_OBJ_FLAG_HIDDEN);
  117. lvgl_port_unlock();
  118. }else{
  119. lvgl_port_lock(-1);
  120. // lv_obj_clear_flag(guider_ui.screen_main_cont_humSet, LV_OBJ_FLAG_HIDDEN);
  121. lv_obj_clear_flag(guider_ui.screen_main_cont_mode, LV_OBJ_FLAG_HIDDEN);
  122. set_ac_mode(&guider_ui, ac_status.mode);
  123. lvgl_port_unlock();
  124. }
  125. }
  126. if (cloud_connected) {
  127. xSemaphoreGive(report_task_sem);
  128. }
  129. modbus_set_reg(SLAVE_POWER_REG_ADDRESS, ac_status.power);
  130. return err;
  131. }
  132. void esp_timer_cb()
  133. {
  134. if(ac_status.power==1)
  135. {
  136. ac_status.filter_used_time++;
  137. }else{
  138. }
  139. if(ac_status.filter_used_time>=system_setting.filter_life_time)
  140. {
  141. ac_status.filter_used_time=system_setting.filter_life_time;
  142. }
  143. xf_set_filter_life_remain(true);
  144. }
  145. esp_timer_handle_t esp_timer_handle = 0; //定时器句柄
  146. void timer_init_lx() {
  147. //定时器结构体初始化
  148. esp_timer_create_args_t fw_timer = {
  149. .callback = &esp_timer_cb, //定时器回调函数
  150. .arg = NULL, //传递给回调函数的参数
  151. .name = "esp_timer", //定时器名称
  152. };
  153. //创建定时器
  154. esp_timer_create(&fw_timer, &esp_timer_handle);
  155. //启动定时器,定时器周期为60*5秒
  156. esp_timer_start_periodic(esp_timer_handle, 5*60000 * 1000);
  157. // esp_timer_start_periodic(esp_timer_handle, 5000 * 1000);
  158. }
  159. //设置滤网剩余寿命
  160. void xf_set_filter_life_remain(bool saved) {
  161. esp_err_t str=ESP_OK;
  162. if(saved)
  163. nvs_set_uint16(ac_status.filter_used_time, NVS_FILTER_USED_TIME);
  164. }
  165. //
  166. uint16_t get_fan_gear_vol(uint16_t value) {
  167. switch (value) {
  168. case 1:
  169. return modbus_get_reg(AIR_FIRST_VOL_ADDRESS_REGISTER);
  170. case 2:
  171. return modbus_get_reg(AIR_SECOND_VOL_ADDRESS_REGISTER);
  172. case 3:
  173. return modbus_get_reg(AIR_THIRD_VOL_ADDRESS_REGISTER);
  174. default: ;
  175. }
  176. return 0;
  177. }
  178. //设置新风风速
  179. esp_err_t xf_set_fan_speed(bool saved) {
  180. esp_err_t err = ESP_OK;
  181. if(saved)
  182. nvs_set_uint16(ac_status.fan_speed, NVS_FAN_SPEED_SET);
  183. if (cloud_connected) {
  184. xSemaphoreGive(report_task_sem);
  185. }
  186. modbus_set_reg(SLAVE_FAN_LEVEL_REG_ADDRESS, ac_status.fan_speed);
  187. return err;
  188. }
  189. //设置手动新风
  190. esp_err_t ac_set_xf_mode(bool saved) {
  191. esp_err_t err = ESP_OK;
  192. if(saved)
  193. nvs_set_uint16(ac_status.xf_mode, NVS_XF_MODE_SET);
  194. if (cloud_connected) {
  195. xSemaphoreGive(report_task_sem);
  196. }
  197. modbus_set_reg(SLAVE_FRESH_MODE_ADDRESS_REGISTER, ac_status.xf_mode);
  198. return err;
  199. }
  200. // 设置模式
  201. esp_err_t xf_set_mode(bool saved) {
  202. esp_err_t err = ESP_OK;
  203. if(saved)
  204. nvs_set_uint16(ac_status.mode, NVS_MODEL_CONTROLLER);
  205. if (cloud_connected) {
  206. xSemaphoreGive(report_task_sem);
  207. }
  208. modbus_set_reg(SLAVE_WORK_MODE_REG_ADDRESS, ac_status.mode);
  209. return err;
  210. }
  211. static void update_power_ui(bool on_off) {
  212. // 同步更新 UI
  213. if (guider_ui.screen_main) {
  214. lvgl_port_lock(-1);
  215. lv_obj_set_state(guider_ui.screen_main_imgbtn_power, LV_IMAGEBUTTON_STATE_CHECKED_RELEASED, on_off);
  216. lvgl_port_unlock();
  217. }
  218. }
  219. // 云端: 设置上报时间间隔
  220. static void cloud_set_report_duration(char *params) {
  221. cJSON *data = cJSON_Parse(params);
  222. if (data != NULL) {
  223. cJSON *value = cJSON_GetObjectItemCaseSensitive(data, "value");
  224. if (cJSON_IsNumber(value)) {
  225. system_setting.report_data_duration = value->valueint;
  226. save_system_setting(&system_setting);
  227. }
  228. }
  229. }
  230. static void cloud_set_power(char *params) {
  231. cJSON *data = cJSON_Parse(params);
  232. if (data != NULL) {
  233. cJSON *value = cJSON_GetObjectItemCaseSensitive(data, "value");
  234. ac_status.power = value->valueint;
  235. ac_set_power(true);
  236. update_power_ui(ac_status.power);
  237. cJSON_Delete(data);
  238. }
  239. }
  240. static void cloud_set_mode(char *params) {
  241. cJSON *data = cJSON_Parse(params);
  242. if (data != NULL) {
  243. cJSON *value = cJSON_GetObjectItemCaseSensitive(data, "value");
  244. ac_status.mode = value->valueint;
  245. if (guider_ui.screen_main) {
  246. lvgl_port_lock(-1);
  247. set_ac_mode(&guider_ui, ac_status.mode);
  248. lvgl_port_unlock();
  249. }
  250. xf_set_mode(true);
  251. cJSON_Delete(data);
  252. }
  253. }
  254. static void cloud_set_temp(char *params) {
  255. cJSON *data = cJSON_Parse(params);
  256. if (data != NULL) {
  257. cJSON *value = cJSON_GetObjectItemCaseSensitive(data, "value");
  258. ac_status.set_temp = value->valueint;
  259. if (guider_ui.screen_main) {
  260. lvgl_port_lock(-1);
  261. lv_label_set_text_fmt(guider_ui.screen_main_label_temp_set, "%d",value->valueint);
  262. lv_arc_set_value(guider_ui.screen_main_arc_temp,value->valueint*10);
  263. lvgl_port_unlock();
  264. }
  265. ac_set_temp(true);
  266. cJSON_Delete(data);
  267. }
  268. }
  269. static void cloud_set_fan_level(char *params) {
  270. cJSON *data = cJSON_Parse(params);
  271. if (data != NULL) {
  272. cJSON *value = cJSON_GetObjectItemCaseSensitive(data, "value");
  273. ac_status.fan_speed = value->valueint;
  274. if (guider_ui.screen_main) {
  275. lvgl_port_lock(-1);
  276. set_fan_level(&guider_ui, ac_status.fan_speed);
  277. lvgl_port_unlock();
  278. }
  279. xf_set_fan_speed(true);
  280. cJSON_Delete(data);
  281. }
  282. }
  283. static void cloud_set_xf_mode(char *params) {
  284. cJSON *data = cJSON_Parse(params);
  285. if (data != NULL) {
  286. cJSON *value = cJSON_GetObjectItemCaseSensitive(data, "value");
  287. ac_status.xf_mode = value->valueint;
  288. if (system_setting.xf_have==1) {
  289. if (guider_ui.screen_main) {
  290. lvgl_port_lock(-1);
  291. // if (ac_status.xf_mode==2) {
  292. // lv_obj_remove_flag(guider_ui.screen_main_lab_new_fan_mode, LV_OBJ_FLAG_HIDDEN);
  293. // }else {
  294. // lv_obj_add_flag(guider_ui.screen_main_lab_new_fan_mode, LV_OBJ_FLAG_HIDDEN);
  295. // }
  296. lvgl_port_unlock();
  297. }
  298. ac_set_xf_mode(true);
  299. }
  300. cJSON_Delete(data);
  301. }
  302. }
  303. esp_err_t set_fan_vol(uint8_t gear, uint16_t *value)
  304. {
  305. uint16_t addr = SLAVE_FAV_FIRST_VOL;
  306. switch (gear) {
  307. case 1:
  308. addr = SLAVE_FAV_FIRST_VOL;
  309. break;
  310. case 2:
  311. addr = SLAVE_FAN_SECOND_VOL;
  312. break;
  313. case 3:
  314. addr = SLAVE_FAN_THIRD_VOL;
  315. break;
  316. default:
  317. break;
  318. }
  319. modbus_set_reg(addr,*value);
  320. return ESP_OK;
  321. }
  322. //设置电压档位
  323. static void cloud_set_fan_vol(char *params) {
  324. cJSON *data = cJSON_Parse(params);
  325. if (data != NULL) {
  326. cJSON *value = cJSON_GetObjectItemCaseSensitive(data, "value");
  327. cJSON *gear = cJSON_GetObjectItemCaseSensitive(data, "gear");
  328. set_fan_vol(gear->valueint, (uint16_t *) &value->valueint);
  329. cJSON_Delete(data);
  330. }
  331. }
  332. static void cloud_set_filter_life(char *params) {
  333. cJSON *data = cJSON_Parse(params);
  334. if (data != NULL) {
  335. cJSON *value = cJSON_GetObjectItemCaseSensitive(data, "value");
  336. system_setting.filter_life_time = value->valueint;
  337. save_system_setting(&system_setting);
  338. cJSON_Delete(data);
  339. }
  340. }
  341. static void cloud_reset_filter_life_remain(char *params) {
  342. cJSON *data = cJSON_Parse(params);
  343. if (data != NULL) {
  344. ac_status.filter_used_time=0;
  345. xf_set_filter_life_remain(true);
  346. cJSON_Delete(data);
  347. }
  348. }
  349. static void cloud_set_min_hum(char *params) {
  350. }
  351. //注册云端指令s
  352. void register_sparrow_commands(void) {
  353. sparrow_command set_power_cmd = {
  354. .name = "setPower",
  355. .unpack = &cloud_set_power
  356. };
  357. register_sparrow_command(set_power_cmd);
  358. // setMode
  359. sparrow_command set_mode_cmd = {
  360. .name = "setMode",
  361. .unpack = &cloud_set_mode
  362. };
  363. register_sparrow_command(set_mode_cmd);
  364. // setFanLevel
  365. sparrow_command set_fan_level_cmd = {
  366. .name = "setFanLevel",
  367. .unpack = &cloud_set_fan_level,
  368. };
  369. register_sparrow_command(set_fan_level_cmd);
  370. // setNewFan
  371. sparrow_command set_filter_life_cmd = {
  372. .name = "setFilterLife",
  373. .unpack = &cloud_set_filter_life,
  374. };
  375. register_sparrow_command(set_filter_life_cmd);
  376. // setFanVoltage
  377. sparrow_command set_min_hum_cmd = {
  378. .name = "setMinHumCmd",
  379. .unpack = &cloud_set_min_hum,
  380. };
  381. register_sparrow_command(set_min_hum_cmd);
  382. sparrow_command set_duration = {
  383. .name = "setReportDuration",
  384. .unpack = &cloud_set_report_duration
  385. };
  386. register_sparrow_command(set_duration);
  387. sparrow_command reset_filter_life_remain = {
  388. .name = "setReportDuration",
  389. .unpack = &cloud_reset_filter_life_remain
  390. };
  391. register_sparrow_command(reset_filter_life_remain);
  392. sparrow_command set_fan_vol = {
  393. .name = "setFanVoltage",
  394. .unpack = &cloud_set_fan_vol
  395. };
  396. register_sparrow_command(set_fan_vol);
  397. sparrow_command set_xf_mode = {
  398. .name = "setNewFan",
  399. .unpack = &cloud_set_xf_mode
  400. };
  401. register_sparrow_command(set_xf_mode);
  402. sparrow_command set_temp = {
  403. .name = "setTemp",
  404. .unpack = &cloud_set_temp
  405. };
  406. register_sparrow_command(set_temp);
  407. }
  408. LV_IMAGE_DECLARE(_power_open_RGB565A8_36x36);
  409. LV_IMAGE_DECLARE(_liang_RGB565A8_30x30);
  410. LV_IMAGE_DECLARE(_cha_RGB565A8_30x30);
  411. /**
  412. * TODO:处理风故障信息
  413. */
  414. void handle_err_code()
  415. {
  416. uint8_t error_code[2] = {0};
  417. esp_err_t err = ESP_OK;
  418. //err = mm_get_param(CID_ERROR_CODE, error_code);
  419. if (err == ESP_OK)
  420. {
  421. // ESP_LOGE(TAG, "error_code1:%d",*(uint16_t *)error_code);
  422. if (guider_ui.screen_main)
  423. {
  424. if((*(uint16_t *)error_code&0x0ff)==0)
  425. {
  426. lvgl_port_lock(-1);
  427. lv_obj_add_flag(guider_ui.screen_main_lab_err, LV_OBJ_FLAG_HIDDEN);
  428. lvgl_port_unlock();
  429. } else{
  430. lvgl_port_lock(-1);
  431. lv_obj_clear_flag(guider_ui.screen_main_lab_err, LV_OBJ_FLAG_HIDDEN);
  432. lvgl_port_unlock();
  433. }
  434. }
  435. ac_status.error_code=(uint8_t)(*(uint16_t *)error_code&0x0ff);
  436. // ESP_LOGE(TAG, "error_code:%d",ac_status.error_code);
  437. }
  438. }
  439. void Refresh_UI()
  440. {
  441. //ac_status.filter_life_remaining=(100-100*ac_status.filter_used_time/system_setting.filter_life_time);
  442. modbus_set_reg(SLAVE_ENV_TEMP_REG_ADDRESS,sht30Data.temperature);
  443. modbus_set_reg(SLAVE_ENV_HUMIDITY_REG_ADDRESS,sht30Data.humidity);
  444. if (guider_ui.screen_main) {
  445. lvgl_port_lock(-1);
  446. // if (ac_status.xf_mode==2) {
  447. // lv_obj_remove_flag(guider_ui.screen_main_lab_new_fan_mode, LV_OBJ_FLAG_HIDDEN);
  448. // }else {
  449. // lv_obj_add_flag(guider_ui.screen_main_lab_new_fan_mode, LV_OBJ_FLAG_HIDDEN);
  450. // }
  451. // if(ac_status.filter_life_remaining<=10)
  452. // {
  453. // lv_obj_remove_flag(guider_ui.screen_main_label_filter_error, LV_OBJ_FLAG_HIDDEN);
  454. // }else{
  455. // lv_obj_add_flag(guider_ui.screen_main_label_filter_error, LV_OBJ_FLAG_HIDDEN);
  456. // }
  457. // lv_label_set_text_fmt(guider_ui.screen_main_label_lvxin, "%d%%", ac_status.filter_life_remaining);
  458. lvgl_port_unlock();
  459. }
  460. }
  461. void set_fan_speed(uint16_t value) {
  462. #ifdef FAN_RELAY
  463. set_fan_relay( value);
  464. #endif
  465. #ifdef FAN_PWM
  466. pwm0_10_set_val(get_fan_gear_vol());
  467. pwm0_10_start();
  468. #endif
  469. }
  470. void user_main_control() {
  471. uint16_t set_temp=0;
  472. uint16_t env_temp=0;
  473. set_temp=modbus_get_reg(SLAVE_SET_TEMP_REG_ADDRESS);
  474. env_temp=modbus_get_reg(SLAVE_ENV_TEMP_REG_ADDRESS);
  475. ESP_LOGE(TAG, "mode:%d.\n",modbus_get_reg(SLAVE_WORK_MODE_REG_ADDRESS));
  476. if (modbus_get_reg(SLAVE_POWER_REG_ADDRESS)==1) {
  477. set_fan_speed(modbus_get_reg(SLAVE_FAN_LEVEL_REG_ADDRESS));
  478. switch (modbus_get_reg(SLAVE_WORK_MODE_REG_ADDRESS)) {
  479. case COLD:
  480. if (env_temp-set_temp>=1) {
  481. tw_valve_open();
  482. }else if(env_temp-set_temp<-1){
  483. tw_valve_close();
  484. }else {
  485. }
  486. break;
  487. case HEAT:
  488. if (env_temp-set_temp<-1) {
  489. //ESP_LOGE(TAG, "HEAT env_temp-set_temp<-1).\n");
  490. tw_valve_open();
  491. }else if(env_temp-set_temp>=1) {
  492. //ESP_LOGE(TAG, " HEAT env_temp-set_temp>=1.\n");
  493. tw_valve_close();
  494. }else {
  495. }
  496. break;
  497. case TF:
  498. tw_valve_close();
  499. break;
  500. default: ;
  501. }
  502. }else {
  503. tw_valve_close();
  504. set_fan_speed(0);
  505. pwm0_10_set_val(0);
  506. pwm0_10_stop();
  507. }
  508. }
  509. #define SLAVE_POWER_REG_ADDRESS (0) // 电源
  510. #define SLAVE_WORK_MODE_REG_ADDRESS (1) // 工作模式
  511. #define SLAVE_FRESH_MODE_ADDRESS_REGISTER (2) // 新风模式寄存器
  512. #define SLAVE_FAN_LEVEL_REG_ADDRESS (4) // 风速档位
  513. #define SLAVE_TW_VALVE_STAT_ADDRESS (5) // 二通阀状态
  514. #define SLAVE_FAV_FIRST_VOL (0x15) // 风机一档电压
  515. #define SLAVE_FAN_SECOND_VOL (0x16) // 风机二档电压
  516. #define SLAVE_FAN_THIRD_VOL (0x17) // 风机三档电压
  517. #define SLAVE_SET_TEMP_REG_ADDRESS (0x0E) // 设置温度
  518. #define SLAVE_ENV_TEMP_REG_ADDRESS (0x1B) // 环境温度
  519. #define SLAVE_ENV_HUMIDITY_REG_ADDRESS (0x1C) // 环境湿度
  520. #define SLAVE_COMMUNICATION_STATUS_REG_ADDRESS (8) // 通讯状态
  521. /**
  522. * 状态同步任务
  523. * @param arg
  524. */
  525. _Noreturn static void status_sync_task(void *arg) {
  526. esp_err_t err = ESP_OK;
  527. modbus_set_reg(SLAVE_POWER_REG_ADDRESS,ac_status.power);
  528. modbus_set_reg(SLAVE_WORK_MODE_REG_ADDRESS,ac_status.mode);
  529. modbus_set_reg(SLAVE_FRESH_MODE_ADDRESS_REGISTER,ac_status.xf_mode);
  530. modbus_set_reg(SLAVE_FAN_LEVEL_REG_ADDRESS,ac_status.fan_speed);
  531. modbus_set_reg(SLAVE_TW_VALVE_STAT_ADDRESS,ac_status.tw_status);
  532. modbus_set_reg(SLAVE_FAV_FIRST_VOL,system_setting.fan_first_vol);
  533. modbus_set_reg(SLAVE_FAN_SECOND_VOL,system_setting.fan_second_vol);
  534. modbus_set_reg(SLAVE_FAN_THIRD_VOL,system_setting.fan_third_vol);
  535. modbus_set_reg(SLAVE_SET_TEMP_REG_ADDRESS,ac_status.set_temp);
  536. for (;;) {
  537. user_main_control();
  538. Refresh_UI();
  539. //ESP_LOGE(TAG, "status_sync_task.\n");
  540. //handle_err_code();
  541. vTaskDelay(3000 / portTICK_PERIOD_MS);
  542. }
  543. }
  544. /**
  545. * 云端上报任务
  546. * @param arg
  547. */
  548. _Noreturn static void cloud_report_task(void *arg) {
  549. for (;;) {
  550. if (xSemaphoreTake(report_task_sem, portMAX_DELAY) == pdTRUE) {
  551. ESP_LOGD(TAG, "cloud report");
  552. cJSON *data = cJSON_CreateObject();
  553. cJSON_AddNumberToObject(data, "power", ac_status.power);
  554. cJSON_AddNumberToObject(data, "temperature", (int) (sht30Data.temperature));
  555. cJSON_AddNumberToObject(data, "humidity", (int) (sht30Data.humidity));
  556. cJSON_AddNumberToObject(data, "mode", ac_status.mode);
  557. cJSON_AddNumberToObject(data, "fan_speed", ac_status.fan_speed);
  558. cJSON_AddNumberToObject(data, "set_temp", ac_status.set_temp);//设置温度
  559. cJSON_AddNumberToObject(data, "tw_status", ac_status.tw_status);//二通阀状态
  560. cJSON_AddNumberToObject(data, "xf_have", system_setting.xf_have);//是否有新风模块
  561. cJSON_AddNumberToObject(data, "xf_mode", ac_status.xf_mode);//手动新风
  562. cJSON_AddNumberToObject(data, "filter_life_remaining", ac_status.filter_life_remaining);
  563. cJSON_AddNumberToObject(data, "set_filter_life_time", system_setting.filter_life_time);
  564. cJSON_AddNumberToObject(data, "air_quality", (int)sht30Data.air_quality);
  565. cJSON_AddNumberToObject(data, "co2", (int)sht30Data.co2);
  566. cJSON_AddNumberToObject(data, "timer_status", system_setting.timer_status);
  567. cJSON_AddNumberToObject(data, "duration", system_setting.duration);
  568. cJSON *root = cJSON_CreateObject();
  569. cJSON_AddStringToObject(root, "cmd", "status");
  570. cJSON_AddItemToObject(root, "params", data);
  571. publish_message_t msg = {
  572. .topic = "status",
  573. .data = root,
  574. };
  575. sparrow_publish_status(msg);
  576. }
  577. }
  578. //
  579. }
  580. _Noreturn static void report_trigger_task(void *arg) {
  581. for (;;) {
  582. if (cloud_connected) {
  583. xSemaphoreGive(report_task_sem);
  584. }
  585. vTaskDelay(pdTICKS_TO_MS(system_setting.report_data_duration * 1000));
  586. }
  587. }
  588. /**
  589. * 云端上报任务
  590. * @param arg
  591. */
  592. _Noreturn static void cloud_fault_report_task(void *arg) {
  593. for (;;) {
  594. if (cloud_connected) {
  595. if (xSemaphoreTake(report_task_sem, portMAX_DELAY) == pdFALSE) {
  596. ESP_LOGD(TAG, "cloud report");
  597. cJSON *data = cJSON_CreateArray();
  598. cJSON *fault = cJSON_CreateObject();
  599. for (int i = 0; i < 8; i++) {
  600. if (ac_status.error_code & (1 << i)) {
  601. cJSON_AddStringToObject(fault, "code", (const char *) xf_fault[i].code);
  602. cJSON_AddStringToObject(fault, "desc", (const char *) xf_fault[i].description);
  603. cJSON_AddItemToArray(data, fault);
  604. }
  605. }
  606. cJSON *root = cJSON_CreateObject();
  607. cJSON_AddStringToObject(root, "cmd", "status");
  608. cJSON_AddItemToObject(root, "params", data);
  609. publish_message_t msg = {
  610. .topic = "status",
  611. .data = root,
  612. };
  613. sparrow_publish_status(msg);
  614. }
  615. vTaskDelay(60*1000 / portTICK_PERIOD_MS);
  616. }
  617. }
  618. }
  619. void ac_controller_init(system_setting_t *setting) {
  620. register_sparrow_commands(); // 注册云端指令
  621. report_task_sem = xSemaphoreCreateBinary();
  622. // timer_init_lx();
  623. // 启动状态同步任务
  624. xTaskCreate(status_sync_task, "status_sync_task", 4 * 1024, NULL, 5, &status_task_handle);
  625. // 启动云端上报任务,受信号量控制,无信号时任务不作操作,只有本地有操作或定时上报任务触发时才会上报。
  626. xTaskCreate(cloud_report_task, "report_task", 6 * 1024, NULL, 5, &cloud_report_handle);
  627. xTaskCreate(report_trigger_task, "trigger_task", 2 * 1024, NULL, 5, &report_trigger_handle);
  628. //故障上报
  629. // xTaskCreate(cloud_fault_report_task, "report_task", 6 * 1024, NULL, 5, &cloud_report_handle);
  630. }
  631. void stop_xf_controller() {
  632. vTaskDelete(status_task_handle);
  633. vTaskDelete(cloud_report_handle);
  634. vTaskDelete(report_trigger_handle);
  635. // 停止modbus 协议 stack
  636. modbus_master_destroy();
  637. }