123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664 |
- #include <sys/cdefs.h>
- /**
- * @Author: 李建
- * @Date: 2025/3/25 15:23
- * Description: 空调控制器
- * Copyright: Copyright (©) 2025 永续绿建. All rights reserved.
- */
- #include <esp_log.h>
- #include "freertos/FreeRTOS.h"
- #include <freertos/task.h>
- #include <cJSON.h>
- #include <esp_timer.h>
- #include "xf_controller.h"
- #include "sub_device/command.h"
- #include "modbus_master.h"
- #include "system/miscellaneous_interface.h"
- #include "lvgl_port.h"
- #include "main.h"
- #include "esp_modbus_master.h"
- #include "mb_endianness_utils.h"
- #include "sht30.h"
- #include "gateway/access.h"
- static const char *TAG = "xf_controller";
- static uint8_t err_count = 0;// 通讯失败次数
- static SemaphoreHandle_t report_task_sem; // 上报任务信号量,用于实现操作完成上立即上报当前状态
- extern void set_xf_mode(lv_ui *ui, uint16_t mode);
- static TaskHandle_t cloud_report_handle;
- static TaskHandle_t report_trigger_handle;
- static TaskHandle_t status_task_handle;
- // 初始化空调参数
- xf_status_t xf_status = {
- .power= 0,
- .fan_speed=3,
- .mode=1,
- .filter_used_time=0,
- .set_max_hum=70,
- .filter_life_remaining=100,
- .error_code=0,
- };
- xf_fault_t xf_fault[9] = {
- {
- .code="E1",
- .description="传感器故障",
- },
- {
- .code="E2",
- .description="高水位故障",
- },
- {
- .code="E3",
- .description="进水电磁阀故障",
- },
- {
- .code="E4",
- .description="送风风机故障",
- },
- {
- .code="E5",
- .description="排风风机故障",
- },
- {
- .code="E6",
- .description="排水泵故障",
- },
- {
- .code="E7",
- .description="通讯故障",
- },
- {
- .code="E8",
- .description="预留",
- }
- };
- void read_xf_status(system_setting_t *setting) {
- uint16_t *_power = nvs_get_uint16(NVS_POWER_CONTROLLER);
- uint16_t *_mode = nvs_get_uint16(NVS_MODEL_CONTROLLER);
- uint16_t *_fan_speed = nvs_get_uint16(NVS_FAN_SPEED_SET);
- uint16_t *_filter_used_time = nvs_get_uint16(NVS_FILTER_USED_TIME);
- uint16_t *_set_hum_max = nvs_get_uint16(NVS_MAX_HUM_SET);
- // uint16_t *_set_hum_min = nvs_get_uint16(NVS_MIN_HUM_SET);
- xf_status.power= _power == NULL ? 0 : *_power;
- xf_status.mode = _mode == NULL ? 1 : *_mode;
- xf_status.fan_speed = _fan_speed == NULL ? 3 : *_fan_speed;
- xf_status.filter_used_time = _filter_used_time == NULL ? 0 : *_filter_used_time;
- xf_status.set_max_hum = _set_hum_max == NULL ? 70 : *_set_hum_max;
- }
- // 设置电源
- esp_err_t xf_set_power(bool saved) {
- esp_err_t err = ESP_OK;
- if(saved)
- nvs_set_uint16(xf_status.power, NVS_POWER_CONTROLLER);
- if (guider_ui.screen_main) {
- if(xf_status.power==0)
- {
- lvgl_port_lock(-1);
- lv_obj_add_flag(guider_ui.screen_main_cont_speedset, LV_OBJ_FLAG_HIDDEN);
- lv_obj_add_flag(guider_ui.screen_main_cont_humSet, LV_OBJ_FLAG_HIDDEN);
- lv_obj_add_flag(guider_ui.screen_main_cont_mode, LV_OBJ_FLAG_HIDDEN);
- lvgl_port_unlock();
- }else{
- lvgl_port_lock(-1);
- lv_obj_clear_flag(guider_ui.screen_main_cont_speedset, LV_OBJ_FLAG_HIDDEN);
- lv_obj_clear_flag(guider_ui.screen_main_cont_humSet, LV_OBJ_FLAG_HIDDEN);
- lv_obj_clear_flag(guider_ui.screen_main_cont_mode, LV_OBJ_FLAG_HIDDEN);
- lv_label_set_text_fmt(guider_ui.screen_main_label_humSet_vul, "%d%%", xf_status.set_max_hum);
- lv_slider_set_value(guider_ui.screen_main_slider_speedSet_sign, xf_status.fan_speed*20, LV_ANIM_ON);
- lv_label_set_text_fmt(guider_ui.screen_main_label_spedSet_vul, "%d档",xf_status.fan_speed);
- lv_slider_set_value(guider_ui.screen_main_slider_humSet_sign, xf_status.set_max_hum, LV_ANIM_ON);
- set_xf_mode(&guider_ui, xf_status.mode);
- lvgl_port_unlock();
- }
- }
- if (cloud_connected) {
- xSemaphoreGive(report_task_sem);
- }
- return err;
- }
- void esp_timer_cb()
- {
- if(xf_status.power==1)
- {
- xf_status.filter_used_time++;
- }else{
- }
- if(xf_status.filter_used_time>=system_setting.filter_life_time)
- {
- xf_status.filter_used_time=system_setting.filter_life_time;
- }
- xf_set_filter_life_remain(true);
- }
- esp_timer_handle_t esp_timer_handle = 0; //定时器句柄
- void timer_init_lx() {
- //定时器结构体初始化
- esp_timer_create_args_t fw_timer = {
- .callback = &esp_timer_cb, //定时器回调函数
- .arg = NULL, //传递给回调函数的参数
- .name = "esp_timer", //定时器名称
- };
- //创建定时器
- esp_timer_create(&fw_timer, &esp_timer_handle);
- //启动定时器,定时器周期为60*5秒
- esp_timer_start_periodic(esp_timer_handle, 5*60000 * 1000);
- // esp_timer_start_periodic(esp_timer_handle, 5000 * 1000);
- }
- // 设置最大湿度
- esp_err_t xf_set_max_hum(bool saved) {
- esp_err_t err = ESP_OK;
- if(saved)
- nvs_set_uint16(xf_status.set_max_hum, NVS_MAX_HUM_SET);
- if (cloud_connected) {
- xSemaphoreGive(report_task_sem);
- }
- return err;
- }
- // 设置最小湿度
- //esp_err_t xf_set_min_hum(bool saved) {
- // if(saved)
- // nvs_set_uint16(xf_status.set_min_hum, NVS_MIN_HUM_SET);
- // return mm_set_param(CID_MIN_HUMIDITY, (uint8_t *)&xf_status.set_min_hum);
- //}
- //设置滤网剩余寿命
- void xf_set_filter_life_remain(bool saved) {
- esp_err_t str=ESP_OK;
- if(saved)
- nvs_set_uint16(xf_status.filter_used_time, NVS_FILTER_USED_TIME);
- }
- //设置新风风速
- esp_err_t xf_set_fan_speed(bool saved) {
- esp_err_t err = ESP_OK;
- if(saved)
- nvs_set_uint16(xf_status.fan_speed, NVS_FAN_SPEED_SET);
- if (cloud_connected) {
- xSemaphoreGive(report_task_sem);
- }
- return err;
- }
- // 设置模式
- esp_err_t xf_set_mode(bool saved) {
- esp_err_t err = ESP_OK;
- if(saved)
- nvs_set_uint16(xf_status.mode, NVS_MODEL_CONTROLLER);
- if (cloud_connected) {
- xSemaphoreGive(report_task_sem);
- }
- return err;
- }
- static void update_power_ui(bool on_off) {
- // 同步更新 UI
- if (guider_ui.screen_main) {
- lvgl_port_lock(-1);
- lv_obj_set_state(guider_ui.screen_main_imgbtn_power, LV_IMAGEBUTTON_STATE_CHECKED_RELEASED, on_off);
- lvgl_port_unlock();
- }
- }
- esp_err_t set_exhaust_fan_vol(uint8_t gear, uint8_t *value)
- {
- uint16_t addr = CID_AIR_EXHAUST_FIRST_VOL;
- switch (gear) {
- case 1:
- addr = CID_AIR_EXHAUST_FIRST_VOL;
- break;
- case 2:
- addr = CID_AIR_EXHAUST_SECOND_VOL;
- break;
- case 3:
- addr = CID_AIR_EXHAUST_THIRD_VOL;
- break;
- case 4:
- addr = CID_AIR_EXHAUST_FOURTH_VOL;
- break;
- case 5:
- addr = CID_AIR_EXHAUST_FIFTH_VOL;
- break;
- default:
- break;
- }
- return mm_set_param(addr, value);
- }
- esp_err_t set_supply_fan_vol(uint8_t gear, uint8_t *value)
- {
- uint16_t addr = CID_AIR_SUPPLY_FIRST_VOL;
- switch (gear) {
- case 1:
- addr = CID_AIR_SUPPLY_FIRST_VOL;
- break;
- case 2:
- addr = CID_AIR_SUPPLY_SECOND_VOL;
- break;
- case 3:
- addr = CID_AIR_SUPPLY_THIRD_VOL;
- break;
- case 4:
- addr = CID_AIR_SUPPLY_FOURTH_VOL;
- break;
- case 5:
- addr = CID_AIR_SUPPLY_FIFTH_VOL;
- break;
- default:
- break;
- }
- return mm_set_param(addr, value);
- }
- // 云端: 设置上报时间间隔
- static void cloud_set_report_duration(char *params) {
- cJSON *data = cJSON_Parse(params);
- if (data != NULL) {
- cJSON *value = cJSON_GetObjectItemCaseSensitive(data, "value");
- if (cJSON_IsNumber(value)) {
- system_setting.report_data_duration = value->valueint;
- save_system_setting(&system_setting);
- }
- }
- }
- static void cloud_set_power(char *params) {
- cJSON *data = cJSON_Parse(params);
- if (data != NULL) {
- cJSON *value = cJSON_GetObjectItemCaseSensitive(data, "value");
- xf_status.power = value->valueint;
- xf_set_power(true);
- update_power_ui(xf_status.power);
- cJSON_Delete(data);
- }
- }
- static void cloud_set_max_hum(char *params) {
- cJSON *data = cJSON_Parse(params);
- if (data != NULL) {
- cJSON *value = cJSON_GetObjectItemCaseSensitive(data, "value");
- if((value->valueint<=70)&&(value->valueint>=system_setting.set_min_hum))
- {
- xf_status.set_max_hum = value->valueint;
- if (guider_ui.screen_main) {
- lvgl_port_lock(-1);
- lv_label_set_text_fmt(guider_ui.screen_main_label_humSet_vul, "%d%%", xf_status.set_max_hum);
- lv_slider_set_value(guider_ui.screen_main_slider_humSet_sign, xf_status.set_max_hum,LV_ANIM_OFF);
- lvgl_port_unlock();
- }
- xf_set_max_hum(true);
- }
- cJSON_Delete(data);
- }
- }
- static void cloud_set_mode(char *params) {
- cJSON *data = cJSON_Parse(params);
- if (data != NULL) {
- cJSON *value = cJSON_GetObjectItemCaseSensitive(data, "value");
- xf_status.mode = value->valueint;
- if (guider_ui.screen_main) {
- lvgl_port_lock(-1);
- set_xf_mode(&guider_ui, xf_status.mode);
- lvgl_port_unlock();
- }
- xf_set_mode(true);
- cJSON_Delete(data);
- }
- }
- static void cloud_set_fan_level(char *params) {
- cJSON *data = cJSON_Parse(params);
- if (data != NULL) {
- cJSON *value = cJSON_GetObjectItemCaseSensitive(data, "value");
- xf_status.fan_speed = value->valueint;
- if (guider_ui.screen_main) {
- lvgl_port_lock(-1);
- lv_slider_set_value(guider_ui.screen_main_slider_speedSet_sign, xf_status.fan_speed*20, LV_ANIM_ON);
- lv_label_set_text_fmt(guider_ui.screen_main_label_spedSet_vul, "%d档",xf_status.fan_speed);
- lvgl_port_unlock();
- }
- xf_set_fan_speed(true);
- cJSON_Delete(data);
- }
- }
- static void cloud_set_filter_life(char *params) {
- cJSON *data = cJSON_Parse(params);
- if (data != NULL) {
- cJSON *value = cJSON_GetObjectItemCaseSensitive(data, "value");
- system_setting.filter_life_time = value->valueint;
- save_system_setting(&system_setting);
- cJSON_Delete(data);
- }
- }
- static void cloud_reset_filter_life_remain(char *params) {
- cJSON *data = cJSON_Parse(params);
- if (data != NULL) {
- xf_status.filter_used_time=0;
- xf_set_filter_life_remain(true);
- cJSON_Delete(data);
- }
- }
- static void cloud_set_exhaust_fan_vol(char *params) {
- cJSON *data = cJSON_Parse(params);
- if (data != NULL) {
- cJSON *value = cJSON_GetObjectItemCaseSensitive(data, "value");
- cJSON *gear = cJSON_GetObjectItemCaseSensitive(data, "gear");
- set_exhaust_fan_vol(gear->valueint, (uint8_t *) &value->valueint);
- cJSON_Delete(data);
- }
- }
- static void cloud_set_supply_fan_vol(char *params) {
- cJSON *data = cJSON_Parse(params);
- if (data != NULL) {
- cJSON *value = cJSON_GetObjectItemCaseSensitive(data, "value");
- cJSON *gear = cJSON_GetObjectItemCaseSensitive(data, "gear");
- set_supply_fan_vol(gear->valueint, (uint8_t *) &value->valueint);
- cJSON_Delete(data);
- }
- }
- static void cloud_set_min_hum(char *params) {
- }
- //注册云端指令s
- void register_sparrow_commands(void) {
- sparrow_command set_power_cmd = {
- .name = "setPower",
- .unpack = &cloud_set_power
- };
- register_sparrow_command(set_power_cmd);
- sparrow_command set_max_hum_cmd = {
- .name = "setMaxHum",
- .unpack = &cloud_set_max_hum
- };
- register_sparrow_command(set_max_hum_cmd);
- // setMode
- sparrow_command set_mode_cmd = {
- .name = "setMode",
- .unpack = &cloud_set_mode
- };
- register_sparrow_command(set_mode_cmd);
- // setFanLevel
- sparrow_command set_fan_level_cmd = {
- .name = "setFanLevel",
- .unpack = &cloud_set_fan_level,
- };
- register_sparrow_command(set_fan_level_cmd);
- // setNewFan
- sparrow_command set_filter_life_cmd = {
- .name = "setFilterLife",
- .unpack = &cloud_set_filter_life,
- };
- register_sparrow_command(set_filter_life_cmd);
- // setFanVoltage
- sparrow_command set_min_hum_cmd = {
- .name = "setMinHumCmd",
- .unpack = &cloud_set_min_hum,
- };
- register_sparrow_command(set_min_hum_cmd);
- sparrow_command set_duration = {
- .name = "setReportDuration",
- .unpack = &cloud_set_report_duration
- };
- register_sparrow_command(set_duration);
- sparrow_command reset_filter_life_remain = {
- .name = "setReportDuration",
- .unpack = &cloud_reset_filter_life_remain
- };
- register_sparrow_command(reset_filter_life_remain);
- sparrow_command set_exhaust_fan_vol = {
- .name = "setexhaustFanVoltage",
- .unpack = &cloud_set_exhaust_fan_vol
- };
- register_sparrow_command(set_exhaust_fan_vol);
- sparrow_command set_supply_fan_vol = {
- .name = "setsupplyFanVoltage",
- .unpack = &cloud_set_supply_fan_vol
- };
- register_sparrow_command(set_supply_fan_vol);
- }
- LV_IMAGE_DECLARE(_power_open_RGB565A8_36x36);
- LV_IMAGE_DECLARE(_liang_RGB565A8_30x30);
- LV_IMAGE_DECLARE(_cha_RGB565A8_30x30);
- /**
- * TODO:处理风故障信息
- */
- void handle_err_code()
- {
- uint8_t error_code[2] = {0};
- esp_err_t err = ESP_OK;
- err = mm_get_param(CID_ERROR_CODE, error_code);
- if (err == ESP_OK)
- {
- // ESP_LOGE(TAG, "error_code1:%d",*(uint16_t *)error_code);
- if (guider_ui.screen_main)
- {
- if((*(uint16_t *)error_code&0x0ff)==0)
- {
- lvgl_port_lock(-1);
- lv_obj_add_flag(guider_ui.screen_main_lab_err, LV_OBJ_FLAG_HIDDEN);
- lvgl_port_unlock();
- } else{
- lvgl_port_lock(-1);
- lv_obj_clear_flag(guider_ui.screen_main_lab_err, LV_OBJ_FLAG_HIDDEN);
- lvgl_port_unlock();
- }
- }
- xf_status.error_code=(uint8_t)(*(uint16_t *)error_code&0x0ff);
- // ESP_LOGE(TAG, "error_code:%d",xf_status.error_code);
- }
- }
- void Refresh_UI()
- {
- uint8_t type = PARAM_TYPE_U16;
- uint8_t temp_data[2] = {0}; // temporary buffer to hold maximum CID size
- uint16_t temp_data_u16 = 500;
- esp_err_t err = ESP_OK;
- const mb_parameter_descriptor_t *param_descriptor = NULL;
- err = mm_get_param(CID_RETURN_AIR_PM25, temp_data);
- if (err == ESP_OK) {
- sht30Data.air_quality=*(uint16_t *)temp_data;
- if (guider_ui.screen_main) {
- lvgl_port_lock(-1);
- lv_arc_set_value(guider_ui.screen_main_arc_AIQ, 500);
- if (*(uint16_t *) temp_data < 50) {
- // lv_arc_set_value(guider_ui.screen_main_arc_AIQ, *(uint16_t *) temp_data);
- lv_obj_set_style_bg_image_src(guider_ui.screen_main_label_AIQ_sign, &_you_RGB565A8_30x30,
- LV_PART_MAIN | LV_STATE_DEFAULT);
- lv_obj_set_style_arc_color(guider_ui.screen_main_arc_AIQ, lv_color_hex(0x2FDA64),
- LV_PART_INDICATOR | LV_STATE_DEFAULT);
- } else if (*(uint16_t *) temp_data < 150) {
- // lv_arc_set_value(guider_ui.screen_main_arc_AIQ, *(uint16_t *) temp_data);
- lv_obj_set_style_bg_image_src(guider_ui.screen_main_label_AIQ_sign, &_liang_RGB565A8_30x30,
- LV_PART_MAIN | LV_STATE_DEFAULT);
- lv_obj_set_style_arc_color(guider_ui.screen_main_arc_AIQ, lv_color_hex(0xFFF502),
- LV_PART_INDICATOR | LV_STATE_DEFAULT);
- } else if (*(uint16_t *) temp_data <= 500) {
- // lv_arc_set_value(guider_ui.screen_main_arc_AIQ, *(uint16_t *) temp_data);
- lv_obj_set_style_bg_image_src(guider_ui.screen_main_label_AIQ_sign, &_cha_RGB565A8_30x30,
- LV_PART_MAIN | LV_STATE_DEFAULT);
- lv_obj_set_style_arc_color(guider_ui.screen_main_arc_AIQ, lv_color_hex(0xd81e06),
- LV_PART_INDICATOR | LV_STATE_DEFAULT);
- } else if (*(uint16_t *) temp_data > 500) {
- // lv_arc_set_value(guider_ui.screen_main_arc_AIQ, temp_data_u16);
- lv_obj_set_style_bg_image_src(guider_ui.screen_main_label_AIQ_sign, &_cha_RGB565A8_30x30,
- LV_PART_MAIN | LV_STATE_DEFAULT);
- lv_obj_set_style_arc_color(guider_ui.screen_main_arc_AIQ, lv_color_hex(0xd81e06),
- LV_PART_INDICATOR | LV_STATE_DEFAULT);
- } else {
- }
- lv_label_set_text_fmt(guider_ui.screen_main_label_AIQ_vul, "%d", *(uint16_t *) temp_data);
- lvgl_port_unlock();
- }
- }
- err = mm_get_param(CID_RETURN_AIR_CO2, temp_data);
- if (err == ESP_OK) {
- err_count = 0;
- sht30Data.co2=*(uint16_t *)temp_data;
- if (guider_ui.screen_main) {
- lvgl_port_lock(-1);
- lv_label_set_text_fmt(guider_ui.screen_main_label_co2, "%d", *(uint16_t *) temp_data);
- lv_obj_add_flag(guider_ui.screen_main_lab_485_err, LV_OBJ_FLAG_HIDDEN);
- lvgl_port_unlock();
- }
- } else {
- err_count++;
- if (err_count >= 254)
- err_count = 30;
- }
- if (err_count >= 30) {
- if (guider_ui.screen_main) {
- lvgl_port_lock(-1);
- lv_obj_remove_flag(guider_ui.screen_main_lab_485_err, LV_OBJ_FLAG_HIDDEN);
- lvgl_port_unlock();
- }
- }
- xf_status.filter_life_remaining=(100-100*xf_status.filter_used_time/system_setting.filter_life_time);
- // ESP_LOGE(TAG, "filter_life_remaining%d",xf_status.filter_life_remaining);
- if (guider_ui.screen_main) {
- lvgl_port_lock(-1);
- if(xf_status.filter_life_remaining<=10)
- {
- lv_obj_remove_flag(guider_ui.screen_main_label_filter_error, LV_OBJ_FLAG_HIDDEN);
- }else{
- lv_obj_add_flag(guider_ui.screen_main_label_filter_error, LV_OBJ_FLAG_HIDDEN);
- }
- lv_label_set_text_fmt(guider_ui.screen_main_label_lvxin, "%d%%", xf_status.filter_life_remaining);
- lvgl_port_unlock();
- }
- }
- /**
- * 状态同步任务,主要用于与分风箱主控同步当前用户的参数,并处理通讯故障
- * @param arg
- */
- _Noreturn static void status_sync_task(void *arg) {
- esp_err_t err = ESP_OK;
- for (;;) {
- mm_set_param(CID_POWER, (uint8_t *)&xf_status.power);
- vTaskDelay(pdTICKS_TO_MS(500));
- mm_set_param(CID_MODE, (uint8_t *)&xf_status.mode);
- vTaskDelay(pdTICKS_TO_MS(500));
- mm_set_param(CID_FAN_SPEED, (uint8_t *)&xf_status.fan_speed);
- vTaskDelay(pdTICKS_TO_MS(500));
- mm_set_param(CID_MAX_HUMIDITY, (uint8_t *)&xf_status.set_max_hum);
- vTaskDelay(pdTICKS_TO_MS(500));
- //
- // err = xf_set_power(false);
- // err = xf_set_mode(true);
- // err = xf_set_fan_speed(true);
- // err =xf_set_max_hum(true);
- // err =xf_set_min_hum(true);
- Refresh_UI();
- handle_err_code();
- vTaskDelay(5000 / portTICK_PERIOD_MS);
- }
- }
- /**
- * 云端上报任务
- * @param arg
- */
- _Noreturn static void cloud_report_task(void *arg) {
- for (;;) {
- if (xSemaphoreTake(report_task_sem, portMAX_DELAY) == pdTRUE) {
- ESP_LOGD(TAG, "cloud report");
- cJSON *data = cJSON_CreateObject();
- cJSON_AddNumberToObject(data, "power", xf_status.power);
- cJSON_AddNumberToObject(data, "set_max_hum", xf_status.set_max_hum);
- cJSON_AddNumberToObject(data, "filter_life_remaining", xf_status.filter_life_remaining);
- cJSON_AddNumberToObject(data, "set_filter_life_time", system_setting.filter_life_time);
- cJSON_AddNumberToObject(data, "mode", xf_status.mode);
- cJSON_AddNumberToObject(data, "temperature", (int) (sht30Data.temperature));
- cJSON_AddNumberToObject(data, "humidity", (int) (sht30Data.humidity));
- cJSON_AddNumberToObject(data, "air_quality", (int)sht30Data.air_quality);
- cJSON_AddNumberToObject(data, "co2", (int)sht30Data.co2);
- cJSON_AddNumberToObject(data, "fan_speed", xf_status.fan_speed);
- cJSON_AddNumberToObject(data, "timer_status", system_setting.timer_status);
- cJSON_AddNumberToObject(data, "duration", system_setting.duration);
- cJSON *root = cJSON_CreateObject();
- cJSON_AddStringToObject(root, "cmd", "status");
- cJSON_AddItemToObject(root, "params", data);
- publish_message_t msg = {
- .topic = "status",
- .data = root,
- };
- sparrow_publish_status(msg);
- }
- }
- //
- }
- _Noreturn static void report_trigger_task(void *arg) {
- for (;;) {
- if (cloud_connected) {
- xSemaphoreGive(report_task_sem);
- }
- vTaskDelay(pdTICKS_TO_MS(system_setting.report_data_duration * 1000));
- }
- }
- /**
- * 云端上报任务
- * @param arg
- */
- _Noreturn static void cloud_fault_report_task(void *arg) {
- for (;;) {
- if (cloud_connected) {
- if (xSemaphoreTake(report_task_sem, portMAX_DELAY) == pdFALSE) {
- ESP_LOGD(TAG, "cloud report");
- cJSON *data = cJSON_CreateArray();
- cJSON *fault = cJSON_CreateObject();
- for (int i = 0; i < 8; i++) {
- if (xf_status.error_code & (1 << i)) {
- cJSON_AddStringToObject(fault, "code", (const char *) xf_fault[i].code);
- cJSON_AddStringToObject(fault, "desc", (const char *) xf_fault[i].description);
- cJSON_AddItemToArray(data, fault);
- }
- }
- cJSON *root = cJSON_CreateObject();
- cJSON_AddStringToObject(root, "cmd", "status");
- cJSON_AddItemToObject(root, "params", data);
- publish_message_t msg = {
- .topic = "status",
- .data = root,
- };
- sparrow_publish_status(msg);
- }
- vTaskDelay(60*1000 / portTICK_PERIOD_MS);
- }
- }
- }
- void xf_controller_init(system_setting_t *setting) {
- register_sparrow_commands(); // 注册云端指令
- report_task_sem = xSemaphoreCreateBinary();
- // timer_init_lx();
- // 启动状态同步任务
- xTaskCreate(status_sync_task, "status_sync_task", 4 * 1024, NULL, 5, &status_task_handle);
- // 启动云端上报任务,受信号量控制,无信号时任务不作操作,只有本地有操作或定时上报任务触发时才会上报。
- xTaskCreate(cloud_report_task, "report_task", 6 * 1024, NULL, 5, &cloud_report_handle);
- xTaskCreate(report_trigger_task, "trigger_task", 2 * 1024, NULL, 5, &report_trigger_handle);
- //故障上报
- // xTaskCreate(cloud_fault_report_task, "report_task", 6 * 1024, NULL, 5, &cloud_report_handle);
- }
- void stop_xf_controller() {
- vTaskDelete(status_task_handle);
- vTaskDelete(cloud_report_handle);
- vTaskDelete(report_trigger_handle);
- // 停止modbus 协议 stack
- modbus_master_destroy();
- }
|