From 22630c02be52108b93265636e4b2409aed52eab3 Mon Sep 17 00:00:00 2001 From: fxxian Date: Sun, 24 Mar 2024 11:25:31 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20mqtt=20=E5=85=A5=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0027_auto_20240323_2250.py | 18 ++++ apps/mosquito/models.py | 2 +- apps/mosquito/mqtt.py | 39 -------- apps/mosquito/mqtt_task.py | 97 +++++++++++++++++++ 4 files changed, 116 insertions(+), 40 deletions(-) create mode 100644 apps/mosquito/migrations/0027_auto_20240323_2250.py delete mode 100644 apps/mosquito/mqtt.py create mode 100644 apps/mosquito/mqtt_task.py diff --git a/apps/mosquito/migrations/0027_auto_20240323_2250.py b/apps/mosquito/migrations/0027_auto_20240323_2250.py new file mode 100644 index 0000000..21d28c1 --- /dev/null +++ b/apps/mosquito/migrations/0027_auto_20240323_2250.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.4 on 2024-03-23 14:50 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('mosquito', '0026_auto_20240314_1545'), + ] + + operations = [ + migrations.AlterField( + model_name='mosqpost', + name='device_id', + field=models.CharField(max_length=100, verbose_name='设备ID'), + ), + ] diff --git a/apps/mosquito/models.py b/apps/mosquito/models.py index 51ec200..5bfc54b 100644 --- a/apps/mosquito/models.py +++ b/apps/mosquito/models.py @@ -3,7 +3,7 @@ from smart.models import SmartModule, SmartPush class MosqPost(models.Model): - device_id = models.CharField(max_length=100, unique=True, verbose_name='设备ID') + device_id = models.CharField(max_length=100, verbose_name='设备ID') count = models.PositiveIntegerField(verbose_name="灭蚊数量") load = models.CharField(max_length=100, blank=True, null=True, verbose_name='负载电压电流功率') storage_battery = models.CharField(max_length=100, blank=True, null=True, verbose_name='电池电压电流功率') diff --git a/apps/mosquito/mqtt.py b/apps/mosquito/mqtt.py deleted file mode 100644 index e40dc57..0000000 --- a/apps/mosquito/mqtt.py +++ /dev/null @@ -1,39 +0,0 @@ -import paho.mqtt.client as mqtt -from mosquito.models import LO - -# MQTT 配置 -MQTT_BROKER = "8.217.112.255" -MQTT_PORT = 1883 - - -# 当我们从MQTT服务器接收到消息时调用此函数 -def on_message(client, userdata, message): - # 提取消息的主题 - topic = message.topic - print(f"Message received on topic: {topic}") - - # 从主题中解析 device_id - # 假定主题格式为: "solarmosquitolamp/devices/{device_id}/data" 或 "state" - topic_parts = topic.split('/') - device_id = topic_parts[2] - - # 将消息打印到控制台(或处理数据,例如存入数据库) - print(f"Device ID: {device_id}") - payload = message.payload.decode('utf-8') - print(f"Message Payload: {payload}") - - # 根据device_id和payload处理数据库的记录... - - -# 初始化MQTT客户端 -client = mqtt.Client() -client.on_message = on_message - -client.connect(MQTT_BROKER, MQTT_PORT, 60) - -# 订阅所有设备的主题 -client.subscribe("solarmosquitolamp/devices/+/data") -client.subscribe("solarmosquitolamp/devices/+/state") - -# 开始MQTT客户端 -client.loop_forever() diff --git a/apps/mosquito/mqtt_task.py b/apps/mosquito/mqtt_task.py new file mode 100644 index 0000000..bc06820 --- /dev/null +++ b/apps/mosquito/mqtt_task.py @@ -0,0 +1,97 @@ +import json +import os +import django +from typing import Dict +from enum import Enum +import paho.mqtt.client as mqtt + + +pwd = os.path.dirname(os.path.realpath(__file__)) +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mosqkiller.settings") +django.setup() + +from mosquito.models import MosqPost, DeviceInfo + +# MQTT 配置 +MQTT_BROKER = "8.217.112.255" +MQTT_PORT = 1883 +DATA_TOPIC = 'solarmosquitolamp/devices/+/data' +STATE_TOPIC = 'solarmosquitolamp/devices/+/state' + + +class PowerType(Enum): + Load = 'Load' + StorageBattery = 'StorageBattery' + SolarPanels = 'SolarPanels' + ACPower = 'AC Power' + DCPower = 'DC Power' + + +# 当我们从MQTT服务器接收到消息时调用此函数 +def on_message(client, userdata, message): + # 提取消息的主题 + topic = message.topic + print(f"Message received on topic: {topic}") + + # 从主题中解析 device_id + topic_parts = topic.split('/') + device_id = topic_parts[2] + + # 将消息打印到控制台(或处理数据,例如存入数据库) + print(f"Device: {device_id} update & create post") + payload = message.payload.decode('utf-8') + # print(f"Message Payload: {payload}") + + # update and create + post_data = json.loads(payload) + update_device_info(device_id, post_data=post_data) + create_mosq_post(device_id, post_data=post_data) + + +def update_device_info(device_id: str, post_data: Dict): + device = DeviceInfo.objects.filter(device_id=device_id).first() + if device: + device.load = to_string(post_data, power_type=PowerType.Load) + device.storage_battery = to_string(post_data, power_type=PowerType.StorageBattery) + device.solar_panels = to_string(post_data, power_type=PowerType.SolarPanels) + device.ac_power = to_string(post_data, power_type=PowerType.ACPower) + device.dc_power = to_string(post_data, power_type=PowerType.DCPower) + device.save() + + +def create_mosq_post(device_id: str, post_data: Dict): + load = to_string(post_data, power_type=PowerType.Load) + storage_battery = to_string(post_data, power_type=PowerType.StorageBattery) + solar_panels = to_string(post_data, power_type=PowerType.SolarPanels) + ac_power = to_string(post_data, power_type=PowerType.ACPower) + dc_power = to_string(post_data, power_type=PowerType.DCPower) + count = post_data['count'] + MosqPost.objects.create(device_id=device_id, + count=count, + load=load, + storage_battery=storage_battery, + solar_panels=solar_panels, + ac_power=ac_power, + dc_power=dc_power) + + +def to_string(post_data: Dict, power_type: PowerType) -> str: + _type = power_type.value + load_v = post_data[_type]['voltage'] + load_c = post_data[_type]['current'] + load_p = post_data[_type]['power'] + return ",".join([str(load_v), str(load_c), str(load_p)]) + + +# 初始化MQTT客户端 +client = mqtt.Client() +client.on_message = on_message + +client.connect(MQTT_BROKER, MQTT_PORT, 60) + +# 订阅所有设备的主题 +client.subscribe(DATA_TOPIC) +# client.subscribe(STATE_TOPIC) + +# 开始MQTT客户端 +client.loop_forever()