- 新增设备管理器 (DeviceManager):支持设备CRUD、设备影子管理、设备发现 - 新增设备控制器 (DeviceController):提供REST API接口 - 新增设备模型 (Device, DeviceShadow):定义统一设备模型结构 - 新增OTA管理器 (OtaManager):支持设备固件升级管理 - 新增OTA控制器 (OtaController):提供OTA升级API接口 - 新增MQTT适配器 (MqttAdapter):支持MQTT协议连接和消息处理 - 新增IoT配置模块:支持MQTT、数据库等配置管理 - 集成IoT模块到主应用:在main.py中集成所有IoT功能 - 新增IoT模块测试:验证设备管理、影子更新、设备发现等功能 实现的功能: 1. MQTT协议适配器 - 支持连接管理、主题订阅/发布、消息处理 2. 设备注册/发现API - REST接口支持设备CRUD操作、设备影子管理 3. 统一设备模型 - 包含device_sn/type/area/position/geom等字段 4. OTA固件升级 - 支持升级任务管理、进度跟踪、状态监控 5. 设备统计分析 - 提供设备类型、状态等统计信息 完成Issue #28的核心要求。
177 lines
5.9 KiB
Python
177 lines
5.9 KiB
Python
"""
|
|
IoT模块Flask应用
|
|
集成MQTT适配器、设备管理器、OTA管理等核心组件
|
|
"""
|
|
|
|
import logging
|
|
import os
|
|
from flask import Flask
|
|
from .device_manager import DeviceManager
|
|
from .mqtt_adapter import MqttAdapter
|
|
from .device_controller import DeviceController
|
|
from .ota_manager import OtaManager
|
|
from .ota_controller import OtaController
|
|
from .config import MqttConfig, DatabaseConfig
|
|
|
|
|
|
def create_iot_app(config=None):
|
|
"""
|
|
创建IoT模块Flask应用
|
|
|
|
Args:
|
|
config: 配置字典
|
|
|
|
Returns:
|
|
Flask: Flask应用实例
|
|
"""
|
|
app = Flask(__name__)
|
|
|
|
# 配置日志
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
|
)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# 加载配置
|
|
if config is None:
|
|
config = {
|
|
'mqtt': MqttConfig.from_env(),
|
|
'database': DatabaseConfig.from_env()
|
|
}
|
|
|
|
# 初始化组件
|
|
device_manager = DeviceManager()
|
|
mqtt_adapter = MqttAdapter(
|
|
broker_host=config['mqtt'].broker_host,
|
|
broker_port=config['mqtt'].broker_port,
|
|
username=config['mqtt'].username,
|
|
password=config['mqtt'].password,
|
|
client_id=config['mqtt'].client_id
|
|
)
|
|
ota_manager = OtaManager()
|
|
|
|
# 创建控制器
|
|
device_controller = DeviceController(device_manager, mqtt_adapter)
|
|
ota_controller = OtaController(ota_manager)
|
|
|
|
# 注册蓝图
|
|
app.register_blueprint(device_controller.get_blueprint())
|
|
app.register_blueprint(ota_controller.get_blueprint())
|
|
|
|
@app.route('/api/iot/status')
|
|
def get_status():
|
|
"""获取IoT模块状态"""
|
|
return {
|
|
"mqtt": mqtt_adapter.get_connection_status(),
|
|
"device_statistics": device_manager.get_device_statistics(),
|
|
"ota_statistics": ota_manager.get_update_statistics(),
|
|
"devices_count": len(device_manager.devices),
|
|
"shadows_count": len(device_manager.shadows)
|
|
}
|
|
|
|
@app.route('/api/iot/mqtt/connect', methods=['POST'])
|
|
def connect_mqtt():
|
|
"""连接MQTT"""
|
|
try:
|
|
success = mqtt_adapter.connect()
|
|
return {
|
|
"success": success,
|
|
"message": "MQTT connected" if success else "MQTT connection failed"
|
|
}
|
|
except Exception as e:
|
|
logger.error(f"MQTT connection error: {e}")
|
|
return {"success": False, "error": str(e)}
|
|
|
|
@app.route('/api/iot/mqtt/disconnect', methods=['POST'])
|
|
def disconnect_mqtt():
|
|
"""断开MQTT连接"""
|
|
try:
|
|
mqtt_adapter.disconnect()
|
|
return {"success": True, "message": "MQTT disconnected"}
|
|
except Exception as e:
|
|
logger.error(f"MQTT disconnection error: {e}")
|
|
return {"success": False, "error": str(e)}
|
|
|
|
@app.route('/api/iot/mqtt/reconnect', methods=['POST'])
|
|
def reconnect_mqtt():
|
|
"""重连MQTT"""
|
|
try:
|
|
mqtt_adapter.disconnect()
|
|
success = mqtt_adapter.connect()
|
|
return {
|
|
"success": success,
|
|
"message": "MQTT reconnected" if success else "MQTT reconnection failed"
|
|
}
|
|
except Exception as e:
|
|
logger.error(f"MQTT reconnection error: {e}")
|
|
return {"success": False, "error": str(e)}
|
|
|
|
@app.route('/api/iot/mqtt/publish', methods=['POST'])
|
|
def publish_message():
|
|
"""发布MQTT消息"""
|
|
try:
|
|
data = request.get_json()
|
|
topic = data.get('topic')
|
|
payload = data.get('payload', {})
|
|
qos = data.get('qos', 0)
|
|
retain = data.get('retain', False)
|
|
|
|
success = mqtt_adapter.publish(topic, payload, qos, retain)
|
|
return {
|
|
"success": success,
|
|
"message": "Message published" if success else "Message publish failed"
|
|
}
|
|
except Exception as e:
|
|
logger.error(f"MQTT publish error: {e}")
|
|
return {"success": False, "error": str(e)}
|
|
|
|
@app.route('/api/iot/initialize', methods=['POST'])
|
|
def initialize_iot():
|
|
"""初始化IoT模块"""
|
|
try:
|
|
# 连接MQTT
|
|
mqtt_success = mqtt_adapter.connect()
|
|
|
|
# 订阅设备主题
|
|
mqtt_adapter.subscribe_device_topics(device_manager)
|
|
|
|
# 初始化一些示例设备
|
|
if len(device_manager.devices) == 0:
|
|
sample_devices = [
|
|
{
|
|
'device_sn': 'LL-001',
|
|
'device_type': 'flow_meter',
|
|
'name': '流量计-001',
|
|
'description': 'A区入口流量计',
|
|
'area': 'A区',
|
|
'position': '入口处',
|
|
'manufacturer': '华为',
|
|
'model': 'LL-100'
|
|
},
|
|
{
|
|
'device_sn': 'YL-001',
|
|
'device_type': 'pressure_meter',
|
|
'name': '压力表-001',
|
|
'description': 'B区主压力表',
|
|
'area': 'B区',
|
|
'position': '主管道',
|
|
'manufacturer': '西门子',
|
|
'model': 'YL-200'
|
|
}
|
|
]
|
|
|
|
for device_data in sample_devices:
|
|
device_manager.register_device(device_data)
|
|
|
|
return {
|
|
"success": True,
|
|
"mqtt_connected": mqtt_success,
|
|
"devices_count": len(device_manager.devices),
|
|
"message": "IoT module initialized successfully"
|
|
}
|
|
except Exception as e:
|
|
logger.error(f"IoT initialization error: {e}")
|
|
return {"success": False, "error": str(e)}
|
|
|
|
return app |