智能家居这个词现在几乎被用烂了随便一个能连WiFi的插座都敢叫自己智能家居。但真正动手做过一套完整系统的人都知道从能远程开关灯到住起来真的舒服中间隔着的不是一两个传感器而是一整套数据采集、逻辑判断、执行反馈的闭环设计。我用Python和AI相关技术折腾智能家居系统前后大概两年多从最早拿树莓派点个LED灯到后来能根据室内外温差、人员活动规律自动调节空调和照明踩过的坑比写过的代码还多。这篇文章就把整套思路和实操过程完整拆开讲一遍适合有Python基础、想自己动手做一套真正能用起来的智能家居系统的朋友也适合正在做物联网相关毕业设计、需要完整技术方案参考的同学。核心会围绕Flask做服务端、传感器数据采集、AI决策逻辑、前端可视化这几个模块展开代码和配置都会给到能直接跑的程度。1. 先想清楚你的智能家居到底要解决什么问题1.1 别一上来就买一堆传感器我见过太多人做智能家居的第一步是打开购物网站把温湿度传感器、人体红外、烟雾报警器、水浸传感器各买五个然后东西到了发现根本不知道怎么接。这个顺序是反的。正确的做法是先定义场景再倒推需要什么硬件。举个我自己的例子。我最初的需求很简单冬天回家之前空调能提前开好进门就是暖的。这个需求拆解下来需要什么一个能远程控制空调的红外发射模块、一个能获取室外温度的途径直接调天气API就行不用自己装室外传感器、一个判断我快到家了的逻辑手机定位或者定时都行。你看三个东西就够了根本不需要买一堆传感器。后来需求升级了变成根据室内外温差和人在不在家自动决定空调开不开、开多久。这时候才需要室内温度传感器、人体存在传感器。硬件是跟着需求走的不是反过来。1.2 把需求翻译成技术语言这一步是很多人卡住的地方。你脑子里想的是家里没人就关灯但代码不认识没人这个概念。你得把它翻译成人体红外传感器在连续15分钟内没有检测到移动信号且当前时间在日出之后日落之前则关闭指定区域的灯光继电器。这个翻译过程有三个关键要素触发条件什么信号触发了判断、判断逻辑满足什么条件才执行、执行动作具体操作什么设备。我习惯用一张表格把每个场景都写清楚写代码的时候直接照着表格实现就行。场景名称触发条件判断逻辑执行动作回家预冷手机连接家庭WiFi室外温度30度开启空调制冷26度无人关灯人体传感器持续无信号15分钟光照传感器数值200关闭对应区域灯光睡前模式手动触发或定时23:00所有房间无人活动关闭公共区域灯光保留夜灯异常报警烟雾传感器触发无推送通知开启排风扇这张表看起来简单但它能帮你避免一个巨大的坑逻辑混乱。我早期没做这个表直接写代码结果出现了人还在客厅坐着灯突然关了的尴尬情况原因就是人体传感器的触发逻辑和灯光控制逻辑耦合在一起改一个地方另一个就出问题。1.3 技术选型的核心考量Python做智能家居服务端几乎是默认选择生态太全了。但具体用什么框架、什么通信协议这里面有讲究。Flask vs Django vs FastAPI智能家居的服务端通常不需要复杂的用户权限体系也不需要后台管理界面Flask的轻量级特性刚好合适。Django太重了FastAPI虽然性能好但如果你要快速出原型Flask的文档和社区案例更多遇到问题好查。我最终选的是Flask后面会详细讲怎么组织代码。通信协议怎么选WiFi、蓝牙、Zigbee、MQTT各有适用场景。我的建议是如果你只是自己家里用设备数量在20个以内WiFiMQTT的组合最省事。WiFi模块便宜好买MQTT协议轻量、支持发布订阅模式特别适合传感器数据上报和设备控制指令下发。Zigbee虽然省电、组网能力强但需要额外的网关调试成本高新手不建议一上来就搞。AI用在什么地方这是很多人困惑的点。不是所有智能家居都需要AI。简单的if-else逻辑能解决的问题硬套AI反而增加复杂度。AI真正有价值的场景是模式识别比如从用电数据判断家里是否有人、预测比如根据历史数据预测你几点到家、自然语言交互比如语音控制。我目前的系统里AI主要用在两个地方一是用简单的机器学习模型分析传感器数据判断正常和异常状态二是接入大模型API做语音指令的语义理解。2. 硬件层传感器选型和接线最容易翻车的地方2.1 传感器选型的三个硬指标买传感器不能只看价格有三个参数必须确认清楚否则买回来要么读不出数据要么读出来的数据没法用。第一个是输出信号类型。传感器输出分数字量和模拟量两种。数字量输出就是高电平或低电平比如人体红外传感器检测到人输出3.3V没人输出0V这种接GPIO口直接读就行。模拟量输出是一个连续变化的电压值比如光敏电阻模块需要接ADC模数转换器才能读。我早期买过一个土壤湿度传感器没注意是模拟量输出直接接树莓派的GPIO读出来的值永远是0或1完全没法用。后来换了一个带ADC芯片的模块才解决。第二个是工作电压。树莓派的GPIO是3.3V逻辑电平Arduino Uno是5V。如果你把5V的传感器直接接到树莓派的GPIO上轻则读数不准重则烧掉引脚。我烧过一个树莓派Zero W的GPIO口就是因为接了一个5V的继电器模块。后来学乖了所有外接模块都先确认电压5V的要么加电平转换模块要么用光耦隔离。第三个是通信接口。常见的接口有GPIO、I2C、SPI、UART。温湿度传感器DHT11用的是单总线协议类似GPIOBMP280气压传感器用的是I2CRFID读卡器常用SPI。选型的时候尽量统一接口类型比如都用I2C接线简单一根SDA一根SCL就能挂多个设备。我现在系统里I2C设备挂了四个温湿度、气压、光照、OLED显示屏总共就用了两根信号线。2.2 接线实操从面包板到成品板面包板适合调试阶段但长期运行必须焊接到洞洞板或者打PCB。我经历过面包板接触不良导致传感器数据跳变的问题排查了一整天才发现是某根杜邦线松了。如果你打算让系统7x24小时运行焊接是必须的。接线的时候有几个经验电源线单独走传感器供电和信号线不要捆在一起尤其是模拟传感器电源线的干扰会直接影响读数。我现在的做法是电源走板子一侧信号线走另一侧。加滤波电容每个传感器的电源引脚旁边并一个0.1uF的陶瓷电容能有效滤掉高频噪声。这个成本几乎为零但效果立竿见影。我加电容之前温度读数波动在±0.5度加了之后稳定在±0.1度。上拉电阻别忘I2C总线的SDA和SCL需要上拉电阻一般是4.7K到10K。很多传感器模块自带上拉但如果你挂多个设备可能需要额外加。我挂到第四个I2C设备的时候通信开始不稳定加了一对4.7K上拉电阻就好了。2.3 执行器控制继电器和红外发射的坑控制灯光用继电器最简单但继电器有机械寿命和触点粘连的问题。我最早用的那种蓝色继电器模块用了大概三个月控制客厅灯的那个继电器就出现了触点粘连灯关不掉了。后来换了固态继电器SSR虽然贵一点但没有机械触点寿命长很多而且切换时没有咔嗒声晚上不会吵到人。红外发射模块用来控制空调和电视最大的坑是码库不全。你家的空调品牌如果比较小众可能找不到现成的红外码。我的做法是用红外接收模块先录下遥控器的码然后自己整理成码库。这个过程比较繁琐但一次录好之后就能一直用。录码的时候注意空调遥控器一个按键可能对应多组码因为要发送温度、模式、风速等完整状态需要把整个状态序列都录下来。提示红外发射管的有效距离一般只有5到8米而且有方向性。如果你的空调在房间角落建议把发射管用延长线引到空调正对面或者用多个发射管并联覆盖不同角度。3. Flask服务端从接收数据到下发指令的完整链路3.1 项目结构设计Flask项目最容易写乱的地方就是所有代码堆在一个app.py里。我现在的项目结构是这样的smart_home/ ├── app.py # 主入口路由定义 ├── config.py # 配置文件 ├── models/ │ ├── sensor.py # 传感器数据模型 │ └── device.py # 设备状态模型 ├── services/ │ ├── mqtt_client.py # MQTT通信 │ ├── ai_engine.py # AI决策逻辑 │ └── scheduler.py # 定时任务 ├── utils/ │ ├── logger.py # 日志 │ └── helpers.py # 工具函数 ├── static/ # 前端静态文件 └── templates/ # HTML模板这个结构的好处是职责清晰。传感器数据采集、AI决策、设备控制各自独立改一个模块不会影响其他模块。我早期把所有逻辑写在一起后来想加一个根据天气预报提前关窗的功能发现要改的地方太多了重构花了整整一个周末。3.2 MQTT通信层的实现MQTT是智能家居里最常用的通信协议核心概念就三个Broker消息中转站、Topic消息主题、Client客户端。传感器往特定Topic发消息服务端订阅这个Topic就能收到数据。我用的Broker是Mosquitto装在树莓派上。配置很简单默认端口1883如果要做认证就加用户名密码。服务端用paho-mqtt这个Python库来收发消息。import paho.mqtt.client as mqtt import json class MQTTClient: def __init__(self, broker, port, client_id): self.client mqtt.Client(client_id) self.client.on_connect self.on_connect self.client.on_message self.on_message self.broker broker self.port port self.callbacks {} def on_connect(self, client, userdata, flags, rc): print(fConnected with result code {rc}) # 订阅所有传感器主题 client.subscribe(home/sensor/#) def on_message(self, client, userdata, msg): topic msg.topic payload json.loads(msg.payload.decode()) # 根据topic分发到不同的处理函数 if topic in self.callbacks: self.callbacks[topic](payload) def register_callback(self, topic, func): self.callbacks[topic] func def publish(self, topic, payload): self.client.publish(topic, json.dumps(payload)) def start(self): self.client.connect(self.broker, self.port, 60) self.client.loop_start()这段代码的关键点是回调注册机制。不同传感器的数据处理逻辑不一样如果全写在on_message里会非常臃肿。用回调注册的方式每个传感器模块自己注册处理函数主循环只负责分发。Topic的设计也有讲究。我用的格式是home/sensor/{房间}/{设备类型}比如home/sensor/livingroom/temperature。这样订阅home/sensor/#就能收到所有传感器数据订阅home/sensor/livingroom/#就只看客厅的。设备控制指令用home/device/{房间}/{设备名}/set状态反馈用home/device/{房间}/{设备名}/state。3.3 数据存储SQLite够不够用很多人纠结智能家居的数据存哪里。我的经验是个人自用SQLite完全够。数据量不大一天最多几万条记录SQLite读写毫无压力。而且SQLite不需要额外装数据库服务一个文件搞定备份就是复制文件。表结构设计上我建议分两张表一张存原始传感器数据一张存设备状态变更记录。原始数据表按时间索引方便做趋势分析。设备状态表记录每次状态变更的时间、触发条件、执行结果方便排查问题。import sqlite3 from datetime import datetime def init_db(): conn sqlite3.connect(smart_home.db) c conn.cursor() c.execute(CREATE TABLE IF NOT EXISTS sensor_data (id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp DATETIME, room TEXT, sensor_type TEXT, value REAL)) c.execute(CREATE TABLE IF NOT EXISTS device_log (id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp DATETIME, device_name TEXT, action TEXT, trigger_reason TEXT, result TEXT)) conn.commit() conn.close() def save_sensor_data(room, sensor_type, value): conn sqlite3.connect(smart_home.db) c conn.cursor() c.execute(INSERT INTO sensor_data (timestamp, room, sensor_type, value) VALUES (?, ?, ?, ?), (datetime.now(), room, sensor_type, value)) conn.commit() conn.close()注意SQLite的并发写入能力有限如果你的传感器上报频率很高比如每秒一次建议加一个内存队列缓冲批量写入。我现在的做法是每10秒批量写一次既减少了IO次数又不会丢数据。3.4 Flask路由设计API和页面的分离Flask的路由分两类一类是给前端页面用的返回HTML一类是给设备或AJAX调用的返回JSON。我习惯把API路由统一放在/api/前缀下页面路由放在根路径。from flask import Flask, render_template, jsonify, request app Flask(__name__) # 页面路由 app.route(/) def index(): return render_template(dashboard.html) # API路由 app.route(/api/sensors, methods[GET]) def get_sensors(): room request.args.get(room) # 从数据库查询最新传感器数据 data query_latest_sensors(room) return jsonify(data) app.route(/api/device/control, methods[POST]) def control_device(): data request.json device data.get(device) action data.get(action) # 下发控制指令 result send_control_command(device, action) return jsonify({status: ok, result: result})这里有个细节获取客户端传来的变量类型。Flask的request.json会自动解析JSON但如果客户端发的是表单数据就要用request.form。我踩过一个坑前端用fetch发JSON但没设置Content-Type: application/json结果request.json返回None。后来在代码里加了兼容处理data request.get_json(silentTrue) or request.form.to_dict()这样无论客户端发JSON还是表单都能正确获取。4. AI决策引擎让系统从自动化变成智能化4.1 规则引擎和AI的分界线在哪里不是所有决策都需要AI。我的原则是能用明确规则解决的问题不要用AI。比如温度高于28度开空调这是明确的规则用if-else就行用AI反而增加不确定性和调试难度。AI真正发挥作用的地方是规则难以穷举的场景。举个例子判断家里是否有人。你可以用人体红外传感器但人坐着不动的时候红外检测不到。你可以用WiFi连接状态但手机可能自动断开。你可以用用电功率但有些电器一直开着。单独任何一个信号都不够可靠但把多个信号综合起来判断就需要AI了。我用的是一个简单的加权评分模型每个信号给一个置信度分数加权求和超过阈值就判定为有人。权重是通过历史数据训练出来的。这个模型很简单但效果比任何单一传感器都好。class PresenceDetector: def __init__(self): # 权重通过历史数据训练得到 self.weights { motion: 0.4, wifi: 0.3, power: 0.2, sound: 0.1 } self.threshold 0.5 def detect(self, signals): score 0 for signal, value in signals.items(): if signal in self.weights: score self.weights[signal] * value return score self.threshold4.2 用机器学习做异常检测智能家居系统里异常检测比预测更有实用价值。比如水管漏水、电器异常耗电、门窗异常开启这些情况用规则很难覆盖全但用异常检测模型就能发现。我用的方法是基于统计的异常检测对每个传感器的历史数据计算均值和标准差实时数据偏离均值超过3个标准差就标记为异常。这个方法简单但有效而且不需要标注数据。import numpy as np class AnomalyDetector: def __init__(self, window_size100): self.window_size window_size self.history {} def update(self, sensor_id, value): if sensor_id not in self.history: self.history[sensor_id] [] self.history[sensor_id].append(value) if len(self.history[sensor_id]) self.window_size: self.history[sensor_id].pop(0) def is_anomaly(self, sensor_id, value): if sensor_id not in self.history or len(self.history[sensor_id]) 30: return False data np.array(self.history[sensor_id]) mean np.mean(data) std np.std(data) if std 0: return False z_score abs(value - mean) / std return z_score 3这个检测器我主要用在用水量监测上。正常用水模式是早上和晚上各一个高峰如果凌晨出现持续水流基本可以判定是漏水。实测下来这个简单模型能发现90%以上的异常情况误报率也很低。4.3 接入大模型做语音指令理解语音控制是智能家居的刚需但传统的语音助手需要预先定义指令模板说开灯能识别说把客厅的灯打开一下可能就识别不了。接入大模型API做语义理解就能解决这个问题。我的做法是语音转文字之后把文字发给大模型让大模型输出结构化的控制指令。Prompt的设计很关键需要明确告诉模型输出格式。import requests def parse_voice_command(text): prompt f你是一个智能家居指令解析器。用户说了一句话你需要解析出设备名称和操作。 可用设备客厅灯、卧室灯、空调、窗帘、加湿器 可用操作开、关、调高、调低、设置温度 用户说{text} 请以JSON格式输出格式为{{device: 设备名, action: 操作, value: 数值如有}} 只输出JSON不要其他内容。 response requests.post( https://api.example.com/v1/chat/completions, headers{Authorization: Bearer YOUR_API_KEY}, json{ model: gpt-3.5-turbo, messages: [{role: user, content: prompt}], temperature: 0 } ) result response.json() return result[choices][0][message][content]这里有个经验temperature设为0保证输出稳定。另外大模型偶尔会输出多余的解释文字需要在代码里做容错处理比如用正则提取JSON部分。提示大模型API调用有延迟一般1到3秒。如果对响应速度要求高可以在本地部署一个小模型做意图分类只把复杂指令发给大模型。我现在的方案是本地模型处理80%的常见指令大模型处理剩下的20%。5. 前端可视化Flask模板和实时数据展示5.1 用Flask模板快速搭建控制面板前端不需要太复杂一个能看数据、能控制设备的页面就够了。Flask自带的Jinja2模板引擎足够用配合Bootstrap框架半天就能搭出一个像样的控制面板。!-- templates/dashboard.html -- !DOCTYPE html html head title智能家居控制面板/title link hrefhttps://cdn.jsdelivr.net/npm/bootstrap5.1.3/dist/css/bootstrap.min.css relstylesheet /head body div classcontainer mt-4 h1智能家居控制面板/h1 div classrow idsensor-cards !-- 传感器卡片由JS动态生成 -- /div div classrow mt-4 iddevice-controls !-- 设备控制按钮 -- /div /div script src/static/js/dashboard.js/script /body /html5.2 实时数据更新轮询还是WebSocket实时数据展示有两种方案轮询和WebSocket。轮询是前端每隔几秒发一次请求WebSocket是服务端主动推送。对于智能家居这种数据更新频率不高的场景传感器一般几秒到几十秒上报一次轮询完全够用而且实现简单。我用的方案是每5秒轮询一次API更新页面数据。// static/js/dashboard.js function updateSensors() { fetch(/api/sensors) .then(response response.json()) .then(data { // 更新页面上的传感器数值 for (const [key, value] of Object.entries(data)) { const element document.getElementById(sensor-${key}); if (element) { element.textContent value; } } }); } // 每5秒更新一次 setInterval(updateSensors, 5000); updateSensors();如果要做图表展示历史数据可以用Chart.js或者ECharts。我用的ECharts因为它的时间轴处理比较方便而且中文文档全。5.3 移动端适配响应式布局的要点智能家居控制面板大概率会在手机上用所以响应式布局是必须的。Bootstrap的栅格系统能解决大部分问题但有几个细节要注意按钮大小手机上的按钮至少44x44像素否则容易误触。我早期做的控制按钮太小手机上经常点错。数据刷新频率手机浏览器在后台时会暂停JS执行回到前台时需要立即刷新一次数据。可以在visibilitychange事件里处理。深色模式晚上看控制面板白色背景太刺眼。加一个深色模式切换用CSS变量实现很简单。:root { --bg-color: #ffffff; --text-color: #333333; } [data-themedark] { --bg-color: #1a1a1a; --text-color: #e0e0e0; } body { background-color: var(--bg-color); color: var(--text-color); }6. 部署和长期运行那些只有跑起来才会遇到的问题6.1 用systemd管理服务开发的时候用python app.py启动没问题但长期运行必须用systemd或者supervisor管理。我用的是systemd配置简单开机自启崩溃自动重启。# /etc/systemd/system/smart-home.service [Unit] DescriptionSmart Home Service Afternetwork.target mosquitto.service [Service] Typesimple Userpi WorkingDirectory/home/pi/smart_home ExecStart/usr/bin/python3 app.py Restartalways RestartSec10 [Install] WantedBymulti-user.target配置好之后systemctl enable smart-home和systemctl start smart-home就行。Restartalways保证程序崩溃后自动重启RestartSec10是重启间隔避免频繁重启。6.2 日志管理别让日志文件撑爆存储Flask默认的日志是输出到控制台的用systemd管理后日志会进journal。但如果你自己写日志文件一定要做轮转否则几个月后日志文件可能几个G。import logging from logging.handlers import RotatingFileHandler handler RotatingFileHandler( smart_home.log, maxBytes10*1024*1024, # 10MB backupCount5 ) handler.setFormatter(logging.Formatter( %(asctime)s - %(name)s - %(levelname)s - %(message)s )) app.logger.addHandler(handler)这个配置是每个日志文件最大10MB保留5个备份总共最多占50MB。对于智能家居系统来说完全够用。6.3 网络断线重连MQTT的自动恢复家庭网络偶尔会断MQTT客户端需要能自动重连。paho-mqtt自带重连机制但需要正确配置。client mqtt.Client(client_id) client.reconnect_delay_set(min_delay1, max_delay120)min_delay是首次重连等待时间max_delay是最大等待时间。这样网络恢复后客户端会自动重新连接不需要手动干预。另外服务端在MQTT断线期间产生的控制指令需要缓存等重连后补发。我的做法是用一个内存队列存待发指令重连成功后批量发送。6.4 数据备份别等硬盘坏了才后悔SQLite数据库文件要定期备份。我的方案是每天凌晨3点自动备份一次保留最近30天的备份。#!/bin/bash # backup.sh DATE$(date %Y%m%d) cp /home/pi/smart_home/smart_home.db /home/pi/backups/smart_home_$DATE.db # 删除30天前的备份 find /home/pi/backups -name smart_home_*.db -mtime 30 -delete然后用crontab定时执行0 3 * * * /home/pi/backup.sh。注意备份之前最好先执行sqlite3 smart_home.db .backup backup.db而不是直接复制文件。直接复制可能在写入过程中导致备份文件损坏。SQLite的.backup命令是原子操作安全得多。7. 几个让我印象深刻的踩坑记录7.1 传感器数据跳变电源噪声的排查过程有一段时间客厅的温度传感器读数每隔几分钟就会跳变一次从25度突然跳到30度又跳回来。我一开始以为是传感器坏了换了一个新的还是一样。后来用万用表测电源电压发现树莓派的5V输出在WiFi模块工作时会有明显的波动波动幅度大概0.3V。排查过程是这样的先排除传感器本身问题换新传感器再排除接线问题重新插拔杜邦线最后用示波器看电源波形才定位到是WiFi模块工作时拉低了电源电压。解决方案是给传感器单独供电用一个LM1117稳压芯片从12V降到3.3V和树莓派共用电源但独立稳压。改完之后数据就稳定了。这个坑给我的教训是智能家居系统里电源质量比传感器精度更重要。再好的传感器电源不稳也白搭。7.2 Flask的调试模式在生产环境的坑开发的时候用app.run(debugTrue)很方便代码改了自动重启。但部署到生产环境如果忘了关debug模式会有两个问题一是性能下降二是安全风险debug模式会暴露代码和堆栈信息。我犯过这个错误系统跑了一周才发现。后来在代码里加了环境判断import os if __name__ __main__: debug os.environ.get(FLASK_DEBUG, false).lower() true app.run(host0.0.0.0, port5000, debugdebug)生产环境用gunicorn启动gunicorn -w 2 -b 0.0.0.0:5000 app:app。-w 2是两个worker进程对于家庭规模的并发完全够用。7.3 定时任务的时区问题我用APScheduler做定时任务比如每天晚上11点执行睡前模式。结果发现任务在凌晨3点执行了排查发现是时区问题。树莓派默认时区是UTC而APScheduler默认也用UTC。解决方案是在初始化调度器的时候指定时区from apscheduler.schedulers.background import BackgroundScheduler import pytz scheduler BackgroundScheduler(timezonepytz.timezone(Asia/Shanghai))同时把树莓派的系统时区也改过来sudo raspi-config里设置本地时区。两个地方都改才能保证定时任务在正确的时间执行。7.4 红外码录制的完整流程红外码录制是智能家居里比较繁琐的一步但掌握了方法就不难。我用的是IRremoteESP8266库配合ESP8266开发板做录制。流程是这样的先把红外接收模块接到ESP8266上烧录一个简单的接收程序串口会打印接收到的红外码。然后拿遥控器对着接收模块按按键串口就会输出码值。把码值记录下来整理成码库。需要注意的是空调遥控器发送的是完整状态按一次温度实际上发送的是当前模式当前风速新温度的完整编码。所以录制的时候要从一个已知状态开始比如先按开机再按温度记录完整的码序列。// ESP8266红外接收示例 #include IRremoteESP8266.h #include IRrecv.h #include IRutils.h const uint16_t kRecvPin 14; IRrecv irrecv(kRecvPin); decode_results results; void setup() { Serial.begin(115200); irrecv.enableIRIn(); } void loop() { if (irrecv.decode(results)) { Serial.println(resultToHumanReadableBasic(results)); irrecv.resume(); } delay(100); }录好的码存到数据库或者JSON文件里控制的时候直接发送对应的码序列就行。8. 系统跑起来之后我实际用下来的感受整套系统从最初的想法到稳定运行前后迭代了大概七八个版本。现在家里大概有20多个传感器和执行器覆盖了照明、空调、窗帘、加湿、安防几个场景。每天自动执行的决策大概有几十次大部分时候我甚至感觉不到系统的存在只有偶尔看日志的时候才发现它一直在工作。有几个体会比较深。第一稳定性比功能多更重要。我早期追求功能全什么设备都想接进来结果系统经常出问题。后来做减法只保留真正高频使用的场景稳定性大幅提升。第二日志和监控是必须的。没有日志出了问题根本不知道从哪里查。我现在每天早上会花一分钟看一眼昨天的设备日志确认没有异常。第三AI不是万能的但用对地方确实能提升体验。我的系统里AI只用在人员存在判断和语音指令解析两个地方其他都是简单规则但这两个地方恰好是规则最难覆盖的AI的加入让整体体验上了一个台阶。如果你也在做类似的项目我的建议是从一个最小的场景开始比如只做温度控制空调这一个功能跑通整个链路之后再逐步扩展。不要一上来就追求大而全那样大概率会在调试阶段就放弃。先把一个场景做稳定后面的扩展就是复制粘贴加微调的事情。