Files
tdEngine_mqtt_mock/mqtt_sender.py
wsy182 d5d1cb0b7d feat(config): 添加配置管理和MQTT模拟服务功能
- 实现了应用配置的数据类结构(MqttConfig, TmsConfig, AppConfig)
- 创建了配置加载和解析功能,支持从YAML文件读取配置
- 添加了TDengine数据库配置和连接池管理
- 实现了MQTT客户端依赖注入和服务构建
- 创建了钻孔实时数据的ORM映射和SQL构建功能
- 实现了TDengine Writer用于数据写入超级表
- 添加了MQTT模拟服务,支持发布、订阅和数据转发功能
- 创建了随机数据发送器用于测试
- 实现了消息持久化到本地文件功能
- 配置了数据库连接池和SQL执行功能
2026-03-12 09:58:00 +08:00

194 lines
5.2 KiB
Python

import argparse
import json
import random
import time
from datetime import datetime
from urllib.parse import urlparse
import paho.mqtt.client as mqtt
from config.dependencies import build_sender_dependencies
DATA_KEYS = [
"ts",
"wellid",
"stknum",
"recid",
"seqid",
"actual_date",
"actual_time",
"actcod",
"deptbitm",
"deptbitv",
"deptmeas",
"deptvert",
"blkpos",
"ropa",
"hkla",
"hklx",
"woba",
"wobx",
"torqa",
"torqx",
"rpma",
"sppa",
"chkp",
"spm1",
"spm2",
"spm3",
"tvolact",
"tvolcact",
"mfop",
"mfoa",
"mfia",
"mdoa",
"mdia",
"mtoa",
"mtia",
"mcoa",
"mcia",
"stkc",
"lagstks",
"deptretm",
"gasa",
"space1",
"space2",
"space3",
"space4",
"space5",
]
def parse_broker(broker):
if not broker:
raise ValueError("broker is required")
if "://" not in broker:
broker = "tcp://" + broker
parsed = urlparse(broker)
host = parsed.hostname or "localhost"
port = parsed.port or 1883
scheme = (parsed.scheme or "tcp").lower()
return scheme, host, port
def rand_int(a, b):
return random.randint(a, b)
def build_random_payload(equipment_code):
data = {key: 0 for key in DATA_KEYS}
data["ts"] = int(time.time() * 1000)
data["wellid"] = random.choice(["", f"WELL-{rand_int(1, 9999):04d}"])
data["stknum"] = rand_int(0, 500)
data["recid"] = rand_int(0, 100000)
data["seqid"] = rand_int(0, 100000)
data["actual_date"] = int(datetime.utcnow().strftime("%Y%m%d"))
data["actual_time"] = int(datetime.utcnow().strftime("%H%M%S"))
data["actcod"] = rand_int(0, 9)
data["deptbitm"] = rand_int(0, 5000)
data["deptbitv"] = rand_int(0, 5000)
data["deptmeas"] = rand_int(0, 5000)
data["deptvert"] = rand_int(0, 5000)
data["blkpos"] = rand_int(0, 100)
data["ropa"] = rand_int(0, 200)
data["hkla"] = rand_int(0, 500)
data["hklx"] = rand_int(0, 500)
data["woba"] = rand_int(0, 200)
data["wobx"] = rand_int(0, 200)
data["torqa"] = rand_int(0, 200)
data["torqx"] = rand_int(0, 200)
data["rpma"] = rand_int(0, 300)
data["sppa"] = rand_int(0, 5000)
data["chkp"] = rand_int(0, 5000)
data["spm1"] = rand_int(0, 200)
data["spm2"] = rand_int(0, 200)
data["spm3"] = rand_int(0, 200)
data["tvolact"] = rand_int(0, 20000)
data["tvolcact"] = rand_int(0, 20000)
data["mfop"] = rand_int(0, 1000)
data["mfoa"] = rand_int(0, 1000)
data["mfia"] = rand_int(0, 1000)
data["mdoa"] = rand_int(0, 1000)
data["mdia"] = rand_int(0, 1000)
data["mtoa"] = rand_int(0, 1000)
data["mtia"] = rand_int(0, 1000)
data["mcoa"] = rand_int(0, 1000)
data["mcia"] = rand_int(0, 1000)
data["stkc"] = rand_int(0, 200)
data["lagstks"] = rand_int(0, 200)
data["deptretm"] = rand_int(0, 5000)
data["gasa"] = rand_int(0, 100)
data["space1"] = rand_int(0, 10)
data["space2"] = rand_int(0, 10)
data["space3"] = rand_int(0, 10)
data["space4"] = rand_int(0, 10)
data["space5"] = rand_int(0, 10)
return {
"meta": {
"equipment_code": equipment_code,
"equipment_sn": equipment_code,
},
"data": data,
}
def run_sender(args, deps):
mqtt_config = deps.config.mqtt
tms_config = deps.config.tms
scheme, host, port = parse_broker(mqtt_config.broker)
print("MQTT sender config:")
print(f" broker: {scheme}://{host}:{port}")
print(f" client-id: {mqtt_config.sender_client_id}")
print(f" pub-topic: {mqtt_config.pub_topic}")
print(f" interval: {args.interval}s")
client = mqtt.Client(client_id=mqtt_config.sender_client_id, clean_session=True)
if mqtt_config.username is not None:
client.username_pw_set(mqtt_config.username, mqtt_config.password)
if scheme in ("ssl", "tls", "mqtts"):
client.tls_set()
def on_disconnect(c, userdata, rc):
print(f"Disconnected callback rc={rc}")
client.on_disconnect = on_disconnect
client.connect(host, port, keepalive=tms_config.keepalive)
client.loop_start()
try:
if not mqtt_config.pub_topic:
print("pub-topic is empty; nothing to publish")
return
seq = 0
while True:
seq += 1
payload = build_random_payload(tms_config.device_code)
client.publish(mqtt_config.pub_topic, json.dumps(payload, ensure_ascii=True))
print(f"TX {mqtt_config.pub_topic}: {payload}")
if args.count and seq >= args.count:
break
time.sleep(args.interval)
except KeyboardInterrupt:
pass
finally:
client.loop_stop()
client.disconnect()
print("Disconnected")
def main():
ap = argparse.ArgumentParser(description="MQTT random data sender")
ap.add_argument("--config", default="config.yaml", help="Path to config yaml")
ap.add_argument("--interval", type=float, default=3.0, help="Publish interval (seconds)")
ap.add_argument("--count", type=int, default=0, help="Publish count (0 = forever)")
args = ap.parse_args()
deps = build_sender_dependencies(args.config)
run_sender(args, deps)
if __name__ == "__main__":
main()