
智能空气质量监测系统 - PM2.5检测与通风建议系统一、实际应用场景描述某高校实验室配备了一台智能空气质量检测仪用于实时监测室内PM2.5浓度。环境科学专业的学生需要在实验过程中持续关注空气质量变化并根据检测结果决定是否开窗通风。传统方式是人工查看数值后凭经验判断存在以下问题- 无法快速识别空气质量等级- 缺乏自动化的通风建议- 数据记录和分析不便本系统旨在解决这些问题实现自动化检测、分级显示和智能通风建议功能。二、引入痛点1. 判断标准不统一不同人对PM2.5浓度的健康影响认知不一2. 决策效率低需要手动查阅标准表再决定开窗时机3. 缺乏历史追溯无法记录空气质量变化趋势4. 用户体验差纯数字显示不够直观三、核心逻辑讲解3.1 PM2.5分级标准中国标准等级 PM2.5浓度(μg/m³) 空气质量 建议优 0-35 绿色 正常活动良 36-75 黄色 可开窗通风轻度污染 76-115 橙色 减少户外活动建议通风中度污染 116-150 红色 关闭门窗开启净化器重度污染 151-250 紫色 避免外出加强净化严重污染 250 褐红色 停止户外活动紧急措施3.2 核心算法流程传感器数据采集 → PM2.5值解析 → 空气质量分级 → 显示结果 → 生成通风建议四、代码模块化实现项目结构air_quality_monitor/├── main.py # 主程序入口├── sensor_simulator.py # 传感器模拟模块├── air_quality_analyzer.py # 空气质量分析模块├── display_module.py # 显示模块├── recommendation_engine.py # 建议引擎模块├── data_logger.py # 数据记录模块└── README.md # 项目说明文档4.1 传感器模拟模块 (sensor_simulator.py)智能空气质量仪传感器模拟模块功能模拟PM2.5传感器的数据采集过程作者全栈开发工程师版本1.0import randomimport timeclass PM25Sensor:PM2.5传感器类模拟真实传感器的数据采集行为def __init__(self, sensor_idAQI_SENSOR_001, location实验室):初始化传感器参数参数:sensor_id: 传感器唯一标识location: 安装位置self.sensor_id sensor_idself.location locationself.is_connected Falseself.calibration_factor 1.0 # 校准因子def connect(self):建立传感器连接print(f[传感器 {self.sensor_id}] 正在连接...)time.sleep(0.5) # 模拟连接延迟self.is_connected Trueprint(f[传感器 {self.sensor_id}] 连接成功位置{self.location})return Truedef disconnect(self):断开传感器连接self.is_connected Falseprint(f[传感器 {self.sensor_id}] 已断开连接)def read_pm25(self):读取PM2.5浓度值返回:float: PM2.5浓度值(μg/m³)异常:ConnectionError: 传感器未连接时抛出if not self.is_connected:raise ConnectionError(传感器未连接请先调用connect()方法)# 模拟真实环境中的PM2.5读数# 基础值 随机波动 可能的峰值base_value random.uniform(20, 80)fluctuation random.gauss(0, 10) # 正态分布波动peak_effect random.choice([0, 0, 0, 30, 50]) # 偶尔出现峰值raw_value base_value fluctuation peak_effectcalibrated_value raw_value * self.calibration_factor# 确保值在合理范围内return max(0, min(500, round(calibrated_value, 1)))def calibrate(self, reference_value):传感器校准参数:reference_value: 标准参考值current_reading self.read_pm25()self.calibration_factor reference_value / current_readingprint(f[传感器 {self.sensor_id}] 校准完成校准因子{self.calibration_factor:.4f})# 测试代码if __name__ __main__:sensor PM25Sensor(sensor_idTEST_001, location办公室)sensor.connect()for i in range(5):value sensor.read_pm25()print(f第{i1}次读取PM2.5 {value} μg/m³)time.sleep(1)sensor.disconnect()4.2 空气质量分析模块 (air_quality_analyzer.py)空气质量分析模块功能根据PM2.5浓度值进行空气质量分级作者全栈开发工程师版本1.0from enum import Enumfrom dataclasses import dataclassfrom typing import Tupleclass AirQualityLevel(Enum):空气质量等级枚举类根据中国《环境空气质量指数(AQI)技术规定》划分EXCELLENT (优, green, 0, 35)GOOD (良, yellow, 36, 75)LIGHTLY_POLLUTED (轻度污染, orange, 76, 115)MODERATELY_POLLUTED (中度污染, red, 116, 150)HEAVILY_POLLUTED (重度污染, purple, 151, 250)SEVERELY_POLLUTED (严重污染, maroon, 251, float(inf))def __init__(self, chinese_name, color_code, min_value, max_value):self.chinese_name chinese_nameself.color_code color_codeself.min_value min_valueself.max_value max_valuedataclassclass AnalysisResult:分析结果数据类存储完整的空气质量分析结果pm25_value: float # PM2.5浓度值air_quality_level: AirQualityLevel # 空气质量等级aqi_score: int # 对应的AQI分数health_impact: str # 健康影响描述timestamp: str # 检测时间戳class AirQualityAnalyzer:空气质量分析器类核心功能将PM2.5数值转换为空气质量等级和健康建议# AQI与PM2.5的换算系数基于中国标准AQI_CONVERSION_FACTOR 100 / 35 # PM2.535时AQI100# 各等级健康影响描述HEALTH_IMPACTS {AirQualityLevel.EXCELLENT: 空气质量令人满意基本无空气污染各类人群可正常活动。,AirQualityLevel.GOOD: 空气质量可接受但某些污染物可能对极少数异常敏感人群健康有较弱影响。,AirQualityLevel.LIGHTLY_POLLUTED: 易感人群症状有轻度加剧健康人群出现刺激症状。建议儿童、老年人及心脏病、呼吸系统疾病患者应减少长时间、高强度的户外锻炼。,AirQualityLevel.MODERATELY_POLLUTED: 进一步加剧易感人群症状可能对健康人群心脏、呼吸系统有影响。建议疾病患者避免长时间、高强度的户外锻练一般人群适量减少户外运动。,AirQualityLevel.HEAVILY_POLLUTED: 心脏病和肺病患者症状显著加剧运动耐受力降低健康人群普遍出现症状。建议儿童、老年人和心脏病、肺病患者应停留在室内停止户外运动一般人群减少户外运动。,AirQualityLevel.SEVERELY_POLLUTED: 健康人群运动耐受力降低有明显强烈症状提前出现某些疾病。建议儿童、老年人和病人应当留在室内避免体力消耗一般人群应避免户外活动。}def __init__(self):初始化分析器passdef analyze(self, pm25_value: float) - AnalysisResult:分析PM2.5浓度值返回完整分析结果参数:pm25_value: PM2.5浓度值(μg/m³)返回:AnalysisResult: 包含完整分析结果的命名元组# 确定空气质量等级level self._determine_level(pm25_value)# 计算AQI分数aqi self._calculate_aqi(pm25_value)# 获取健康影响描述health_impact self.HEALTH_IMPACTS.get(level, 未知影响)# 生成时间戳from datetime import datetimetimestamp datetime.now().strftime(%Y-%m-%d %H:%M:%S)return AnalysisResult(pm25_valuepm25_value,air_quality_levellevel,aqi_scoreaqi,health_impacthealth_impact,timestamptimestamp)def _determine_level(self, pm25_value: float) - AirQualityLevel:根据PM2.5值确定空气质量等级私有方法参数:pm25_value: PM2.5浓度值返回:AirQualityLevel: 对应的空气质量等级枚举for level in AirQualityLevel:if level.min_value pm25_value level.max_value:return levelreturn AirQualityLevel.SEVERELY_POLLUTED # 超出范围默认为严重污染def _calculate_aqi(self, pm25_value: float) - int:根据PM2.5值计算AQI分数私有方法参数:pm25_value: PM2.5浓度值返回:int: AQI分数取整if pm25_value 35:# 线性插值PM2.50时AQI0PM2.535时AQI100return int(pm25_value * self.AQI_CONVERSION_FACTOR)elif pm25_value 75:# PM2.575时AQI200return int(100 (pm25_value - 35) * (100 / 40))elif pm25_value 115:# PM2.5115时AQI300return int(200 (pm25_value - 75) * (100 / 40))else:# 超过115按更高等级计算return int(300 (pm25_value - 115) * (200 / 135))def get_color_code(self, level: AirQualityLevel) - str:获取等级对应的颜色代码用于终端彩色显示参数:level: 空气质量等级返回:str: ANSI颜色代码color_map {green: \033[92m, # 绿色yellow: \033[93m, # 黄色orange: \033[33m, # 橙色red: \033[91m, # 红色purple: \033[95m, # 紫色maroon: \033[31m # 褐红色}return color_map.get(level.color_code, \033[0m)# 测试代码if __name__ __main__:analyzer AirQualityAnalyzer()test_values [15, 50, 90, 130, 200, 300]print( * 60)print(PM2.5空气质量分析测试)print( * 60)for value in test_values:result analyzer.analyze(value)print(f\nPM2.5 {value} μg/m³)print(f空气质量{result.air_quality_level.chinese_name})print(fAQI分数{result.aqi_score})print(f健康影响{result.health_impact[:50]}...)4.3 显示模块 (display_module.py)显示模块功能负责所有可视化输出包括控制台彩色显示和简单图表作者全栈开发工程师版本1.0import osfrom typing import Listfrom air_quality_analyzer import AnalysisResult, AirQualityLevelclass DisplayModule:显示模块类提供多种方式的空气质量信息展示# 终端颜色代码COLORS {reset: \033[0m,bold: \033[1m,green: \033[92m,yellow: \033[93m,orange: \033[33m,red: \033[91m,purple: \033[95m,maroon: \033[31m,cyan: \033[96m,gray: \033[90m}# 空气质量等级对应的emoji图标LEVEL_EMOJIS {优: ,良: ,轻度污染: ,中度污染: ,重度污染: ⚠️,严重污染: }def __init__(self, enable_colorTrue):初始化显示模块参数:enable_color: 是否启用彩色输出self.enable_color enable_color and self._check_color_support()def _check_color_support(self) - bool:检查终端是否支持颜色输出# Windows系统需要特殊处理if os.name nt:try:import ctypeskernel32 ctypes.windll.kernel32kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)return Trueexcept:return Falsereturn Truedef _colorize(self, text: str, color: str) - str:为文本添加颜色如果启用if self.enable_color and color in self.COLORS:return f{self.COLORS[color]}{text}{self.COLORS[reset]}return textdef clear_screen(self):清屏os.system(cls if os.name nt else clear)def display_single_result(self, result: AnalysisResult):显示单次检测结果核心显示函数参数:result: 分析结果对象level result.air_quality_levelemoji self.LEVEL_EMOJIS.get(level.chinese_name, )# 构建显示框border * 50title f ️ 智能空气质量监测报告 ️ print(\n self._colorize(border, cyan))print(self._colorize(title.center(48), bold))print(self._colorize(border, cyan))# PM2.5数值显示pm25_text f PM2.5 浓度{result.pm25_value} μg/m³print(self._colorize(pm25_text, bold))# 空气质量等级level_color level.color_codelevel_text f 空气质量{emoji} {level.chinese_name}print(self._colorize(level_text, level_color))# AQI分数aqi_text f AQI 指数{result.aqi_score}print(self._colorize(aqi_text, cyan))# 时间戳time_text f 检测时间{result.timestamp}print(self._colorize(time_text, gray))print(self._colorize(border, cyan))# 健康影响impact_title 健康影响评估print(self._colorize(impact_title, bold))print(f {result.health_impact})print(self._colorize(border, cyan))def display_ventilation_advice(self, result: AnalysisResult) - str:显示通风建议核心功能参数:result: 分析结果对象返回:str: 通风建议文本level result.air_quality_leveladvice self._generate_advice(level)print(\n self._colorize( 通风建议, bold))print(self._colorize(- * 40, gray))print(advice)print(self._colorize(- * 40, gray))return advicedef _generate_advice(self, level: AirQualityLevel) - str:根据空气质量等级生成通风建议私有方法参数:level: 空气质量等级返回:str: 详细通风建议advice_map {AirQualityLevel.EXCELLENT: (✅ 【优】空气质量极佳\n • 可以放心开窗通风保持空气流通\n • 适合进行各类室内外活动\n • 建议保持现有通风状态),AirQualityLevel.GOOD: ( 【良】空气质量良好\n • 建议适当开窗通风每次15-30分钟\n • 早晚时段通风效果更佳\n • 可正常进行日常活动),AirQualityLevel.LIGHTLY_POLLUTED: (⚠️ 【轻度污染】需要注意\n • 建议短时间开窗通风10-15分钟\n • 避开交通高峰期通风\n • 敏感人群减少户外活动\n • 考虑开启空气净化器辅助),AirQualityLevel.MODERATELY_POLLUTED: ( 【中度污染】建议谨慎\n • 减少开窗时间可选择午后短暂通风\n • 优先开启空气净化器\n • 外出归来及时更换衣物\n • 敏感人群避免户外活动),AirQualityLevel.HEAVILY_POLLUTED: ( 【重度污染】不建议开窗\n • 关闭门窗防止室外污染进入\n • 开启高效空气净化器\n • 使用湿抹布清洁减少扬尘\n • 必须外出时佩戴N95口罩),AirQualityLevel.SEVERELY_POLLUTED: ( 【严重污染】禁止开窗\n • 立即关闭所有门窗\n • 启动最强档空气净化器\n • 暂停一切户外活动\n • 多喝水注意呼吸道防护\n • 必要时联系相关部门)}return advice_map.get(level, 未知等级请参考官方建议)def display_history_chart(self, history: List[AnalysisResult], max_width: int 40):显示历史数据趋势图简化版ASCII图表参数:history: 历史记录列表max_width: 图表最大宽度if not history:print(暂无历史数据)returnprint(\n self._colorize( 最近检测趋势, bold))print(self._colorize(- * 50, gray))# 提取PM2.5值和时间标签values [r.pm25_value for r in history[-max_width:]]labels [r.timestamp.split()[1][:5] for r in history[-max_width:]] # 只取时间部分# 归一化到图表高度max_val max(values) if values else 1chart_height 8# 绘制图表for row in range(chart_height, 0, -1):threshold (row / chart_height) * max_valline |for val in values:if val threshold:line █else:line print(line)# 绘制X轴print( - * (len(values) * 2))# 绘制时间标签简化显示if len(labels) 10:label_line for label in labels:label_line f{label} print(label_line)else:# 只显示首尾和中间几个标签step len(labels) // 5label_line for i in range(0, len(labels), step):label_line f{labels[i]} print(label_line)print(self._colorize(- * 50, gray))print(f 最大值{max(values):.1f} 最小值{min(values):.1f} 平均值{sum(values)/len(values):.1f})def display_welcome_banner(self):显示欢迎横幅banner ╔════════════════════════════════════════════════════════════╗║ ║║ ️ 智能空气质量监测系统 v1.0 ️ ║║ ║║ 实时PM2.5检测 · 智能分级 · 通风建议 ║║ ║╚════════════════════════════════════════════════════════════╝print(self._colorize(banner, cyan))# 测试代码if __name__ __main__:from air_quality_analyzer import AirQualityAnalyzerfrom sensor_simulator import PM25Sensor# 创建测试数据sensor PM25Sensor()sensor.connect()analyzer AirQualityAnalyzer()display DisplayModule()# 显示欢迎横幅display.display_welcome_banner()# 模拟多次检测并显示history []for i in range(5):pm25 sensor.read_pm25()result analyzer.analyze(pm25)history.append(result)display.display_single_result(result)display.display_ventilation_advice(result)print(\n)# 显示趋势图display.display_history_chart(history)sensor.disconnect()4.4 建议引擎模块 (recommendation_engine.py)建议引擎模块功能基于空气质量分析结果生成综合建议扩展功能作者全栈开发工程师版本1.0from dataclasses import dataclass, fieldfrom typing import List, Dict, Optionalfrom datetime import datetime, timefrom air_quality_analyzer import AnalysisResult, AirQualityLeveldataclassclass VentilationPlan:通风计划数据类包含详细的通风时间安排建议is_recommended: bool # 是否建议通风duration_minutes: int # 建议通风时长分钟best_time_range: str # 最佳通风时间段frequency_per_day: int # 每日建议通风次数precautions: List[str] # 注意事项列表alternative_actions: List[str] # 替代行动方案dataclassclass ComprehensiveAdvice:综合建议数据类包含所有类型的建议ventilation_plan: VentilationPlan # 通风计划health_tips: List[str] # 健康小贴士equipment_suggestions: List[str] # 设备使用建议activity_recommendations: Dict[str, str] # 活动建议class RecommendationEngine:建议引擎类基于多维度的输入生成个性化建议# 时间段空气质量特征可根据实际情况调整TIME_PERIOD_PROFILE {morning: {name: 早晨(6:00-9:00), pollution_risk: medium, humidity: high},midday: {name: 中午(11:00-14:00), pollution_risk: low, humidity: low},afternoon: {name: 下午(15:00-17:00), pollution_risk: low, humidity: medium},evening: {name: 傍晚(18:00-20:00), pollution_risk: high, humidity: medium},night: {name: 夜间(21:00-5:00), pollution_risk: medium, humidity: high}}# 活动类型与空气质量要求的映射ACTIVITY_REQUIREMENTS {normal: {max_pm25: 75, description: 日常活动},exercise: {max_pm25: 50, description: 体育锻炼},sensitive: {max_pm25: 35, description: 敏感人群活动},child_play: {max_pm25: 35, description: 儿童玩耍},elderly_rest: {max_pm25: 50, description: 老人休憩}}def __init__(self, user_profile: Optional[Dict] None):初始化建议引擎参数:user_profile: 用户档案可包含年龄、健康状况等信息self.user_profile user_profile or {}self.current_time datetime.now().time()def generate_comprehensive_advice(self, result: AnalysisResult) - ComprehensiveAdvice:生成综合建议核心方法参数:result: 空气质量分析结果返回:ComprehensiveAdvice: 综合建议对象# 生成通风计划ventilation_plan self._create_ventilation_plan(result)# 生成健康贴士health_tips self._generate_health_tips(result)# 生成设备建议equipment_suggestions self._suggest_equipment(result)# 生成活动建议activity_recommendations self._recommend_activities(result)return ComprehensiveAdvice(ventilation_planventilation_plan,health_tipshealth_tips,equipment_suggestionsequipment_suggestions,activity_recommendationsactivity_recommendations)def _create_ventilation_plan(self, result: AnalysisResult) - VentilationPlan:创建通风计划私有方法level result.air_quality_levelcurrent_hour self.current_time.hour# 根据等级确定基础参数if level AirQualityLevel.EXCELLENT:plan VentilationPlan(is_recommendedTrue,duration_minutes30,best_time_range全天适宜,frequency_per_day3,precautions[保持窗户微开即可保证空气流通],利用AI解决实际问题如果你觉得这个工具好用欢迎关注长安牧笛