#ifndef CORE_H #define CORE_H #include #include // 包含所有必要的模块头文件 #include "DHT11control.h" #include "RTC_Module.h" #include "LunarCalendarAndHolidayJudge.h" #include "audio_model_esp32.h" #include "microphone.h" // 核心判断结果枚举 typedef enum { JUDGE_NO_ACTION = 0, // 无需操作 JUDGE_TURN_ON_COOLING = 1, // 开启制冷 JUDGE_TURN_ON_HEATING = 2, // 开启制暖 JUDGE_TURN_OFF_AC = 3, // 关闭空调 JUDGE_ADJUST_TEMP = 4, // 除湿 JUDGE_ERROR = -1 // 错误状态 } JudgeResult; // 环境数据结构 typedef struct { float temperature; // 当前温度 float humidity; // 当前湿度 int year; // 当前年份 int month; // 当前月份 int day; // 当前日期 int hour; // 当前小时 int minute; // 当前分钟 int second; // 当前秒数 bool is_holiday; // 是否为节假日 AudioClassType audio_class; // AI音频识别结果 float audio_confidence; // 音频识别置信度 bool data_valid; // 数据是否有效 } EnvironmentData; // 全局麦克风对象 static INMP441Microphone microphone(14, 15, 32, 16000, 1024); // 初始化核心模块 bool initializeCore() { Serial.println("正在初始化核心模块..."); // 初始化音频模型 if (audio_model_init() != 0) { Serial.println("音频模型初始化失败!"); return false; } // 初始化麦克风 if (!microphone.begin()) { Serial.println("麦克风初始化失败!"); return false; } Serial.println("核心模块初始化完成"); return true; } // 获取环境数据 bool getEnvironmentData(EnvironmentData* env_data) { if (env_data == NULL) { return false; } // 初始化数据结构 memset(env_data, 0, sizeof(EnvironmentData)); env_data->data_valid = false; // 获取温湿度数据 float* temp_humidity = getTempAndHumidity(); if (temp_humidity[0] == -999 || temp_humidity[1] == -999) { Serial.println("温湿度传感器读取失败!"); return false; } env_data->temperature = temp_humidity[0]; env_data->humidity = temp_humidity[1]; // 获取RTC时间 RtcDateTime current_time = getRTCTime(); if (!current_time.IsValid()) { Serial.println("RTC时间读取失败!"); return false; } env_data->year = current_time.Year(); env_data->month = current_time.Month(); env_data->day = current_time.Day(); env_data->hour = current_time.Hour(); env_data->minute = current_time.Minute(); env_data->second = current_time.Second(); // 判断是否为节假日 env_data->is_holiday = LunarCalendar::isHoliday(env_data->year, env_data->month, env_data->day); env_data->data_valid = true; return true; } // 执行AI音频识别 bool performAudioRecognition(EnvironmentData* env_data) { if (env_data == NULL) { return false; } Serial.println("开始音频识别..."); // 分配音频缓冲区 (2秒 * 16000Hz = 32000 samples) const size_t audio_buffer_size = 32000; int16_t* audio_buffer = (int16_t*)malloc(audio_buffer_size * sizeof(int16_t)); if (audio_buffer == NULL) { Serial.println("音频缓冲区分配失败!"); return false; } // 采集2秒音频数据 size_t samples_read = 0; unsigned long start_time = millis(); while (samples_read < audio_buffer_size && (millis() - start_time) < 2100) { size_t chunk_size = microphone.readAudioData( audio_buffer + samples_read, min(1024, (int)(audio_buffer_size - samples_read)) ); samples_read += chunk_size; delay(1); // 短暂延时避免过度占用CPU } Serial.printf("采集到 %d 个音频样本\n", samples_read); // 执行AI预测 AudioPredictionResult prediction_result; int predict_status = audio_model_predict(audio_buffer, samples_read, &prediction_result); // 释放音频缓冲区 free(audio_buffer); if (predict_status != 0 || !prediction_result.is_valid) { Serial.println("音频预测失败!"); env_data->audio_class = AUDIO_CLASS_PERSON_ABSENT; env_data->audio_confidence = 0.0f; return false; } env_data->audio_class = prediction_result.predicted_class; env_data->audio_confidence = prediction_result.confidence; Serial.printf("音频识别结果: %s (置信度: %.2f)\n", get_class_name_cn(env_data->audio_class), env_data->audio_confidence); return true; } // 核心判断函数 int judge() { Serial.println("=== 开始核心判断流程 ==="); // 获取环境数据 EnvironmentData env_data; if (!getEnvironmentData(&env_data)) { Serial.println("环境数据获取失败!"); return JUDGE_ERROR; } // 执行音频识别 if (!performAudioRecognition(&env_data)) { Serial.println("音频识别失败,使用默认值"); // 继续执行,但音频数据可能不准确 } // 打印当前环境状态 Serial.println("=== 当前环境状态 ==="); Serial.printf("时间: %04d-%02d-%02d %02d:%02d:%02d\n", env_data.year, env_data.month, env_data.day, env_data.hour, env_data.minute, env_data.second); Serial.printf("温度: %.1f°C, 湿度: %.1f%%\n", env_data.temperature, env_data.humidity); Serial.printf("节假日: %s\n", env_data.is_holiday ? "是" : "否"); Serial.printf("音频识别: %s (置信度: %.2f)\n", get_class_name_cn(env_data.audio_class), env_data.audio_confidence); // 核心判断逻辑 JudgeResult result = JUDGE_NO_ACTION; // 获取用户设置的温度范围 (从Preferences读取) Preferences prefs; prefs.begin("DACSC", true); // 只读模式 float min_temp = prefs.getFloat("min_temp", 10.0); // 默认最低温度10°C float max_temp = prefs.getFloat("max_temp", 28.0); // 默认最高温度28°C prefs.end(); // 打印当前使用的温度设置 Serial.printf("当前温度设置 - 最低: %.1f°C, 最高: %.1f°C\n", min_temp, max_temp); // 判断逻辑:基于节假日、音频识别、时间、温度和湿度的智能控制 // 规则1:节假日规则(优先级最高) if (env_data.is_holiday) { result = JUDGE_NO_ACTION; Serial.println("判断结果: 节假日,系统不进行任何操作"); } // 规则2-9:非节假日规则 else { // 检查是否有人在室内(包括"室内有人"和"有人进门") bool person_present = (env_data.audio_class == AUDIO_CLASS_PERSON_PRESENT || env_data.audio_class == AUDIO_CLASS_KEY_JINGLING) && env_data.audio_confidence > 0.6; // 检查是否无人在室内(包括"室内无人"和"有人出门") bool person_absent = (env_data.audio_class == AUDIO_CLASS_PERSON_ABSENT || env_data.audio_class == AUDIO_CLASS_DOOR_CLOSING) && env_data.audio_confidence > 0.6; // 检查是否为白天时间(8:00-22:00) bool is_daytime = (env_data.hour >= 8 && env_data.hour <= 22); if (person_absent) { // 规则10:无人时关闭空调(优先级高) result = JUDGE_TURN_OFF_AC; Serial.println("判断结果: 检测到无人或有人出门,关闭空调以节能"); } else if (person_present) { if (is_daytime) { // 白天有人的规则(规则2-5) if (env_data.temperature < min_temp) { result = JUDGE_TURN_ON_HEATING; Serial.println("判断结果: 白天有人且温度过低,开启制热"); } else if (env_data.temperature > max_temp) { result = JUDGE_TURN_ON_COOLING; Serial.println("判断结果: 白天有人且温度过高,开启制冷"); } else if (env_data.humidity > 70.0) { result = JUDGE_ADJUST_TEMP; Serial.println("判断结果: 白天有人、温度舒适但湿度过高,开启除湿"); } else { result = JUDGE_NO_ACTION; Serial.println("判断结果: 白天有人、温度舒适且湿度正常,无需操作"); } } else { // 晚上有人的规则(规则6-9) if (env_data.temperature < min_temp) { result = JUDGE_TURN_ON_HEATING; Serial.println("判断结果: 晚上有人但温度过低,开启制热"); } else if (env_data.temperature > max_temp) { result = JUDGE_TURN_ON_COOLING; Serial.println("判断结果: 晚上有人但温度过高,开启制冷"); } else if (env_data.humidity > 70.0) { result = JUDGE_ADJUST_TEMP; Serial.println("判断结果: 晚上有人、温度舒适但湿度过高,开启除湿"); } else { result = JUDGE_NO_ACTION; Serial.println("判断结果: 晚上有人、温度舒适且湿度正常,无需操作以节能"); } } } else { // 音频识别不确定或置信度不够时的默认处理 result = JUDGE_NO_ACTION; Serial.println("判断结果: 音频识别不确定,保持当前状态"); } } Serial.printf("=== 判断完成,返回值: %d ===\n", result); return result; } // 清理核心模块资源 void cleanupCore() { Serial.println("清理核心模块资源..."); microphone.end(); audio_model_cleanup(); Serial.println("核心模块资源清理完成"); } #endif // CORE_H