refactor(config): 重构配置模块并优化应用依赖注入

- 将配置相关类移动到model模块
- 实现依赖注入容器管理各组件依赖关系
- 重构配置加载逻辑支持多层级键值查找
- 更新主应用入口支持命令行参数解析
- 统一日志输出格式替换原有打印语句
- 引入钻井实时数据模型简化数据处理
- 移除硬编码字段映射改用动态配置方式
- 优化数据库写入逻辑基于新的数据模型
This commit is contained in:
2026-03-12 10:41:26 +08:00
parent 6d13da4cc2
commit 6557479a2f
16 changed files with 783 additions and 589 deletions

View File

@@ -1,129 +1,24 @@
from dataclasses import dataclass
import yaml
@dataclass(frozen=True)
class MqttConfig:
broker: str
client_id: str
mock_client_id: str
sender_client_id: str
subscriber_client_id: str
username: str | None
password: str | None
pub_topic: str | None
sub_topic: str | None
ack_topic: str | None
data_file: str
@dataclass(frozen=True)
class TmsConfig:
device_code: str
equipment_sn: str
timeout: int
keepalive: int
server_ip: str | None
server_port: int | None
@dataclass(frozen=True)
class WitsConfig:
host: str
port: int
timeout: int
source_file: str
@dataclass(frozen=True)
class AppConfig:
mqtt: MqttConfig
tms: TmsConfig
wits: WitsConfig
raw: dict
def load_raw_config(path):
with open(path, "r", encoding="utf-8") as f:
return yaml.safe_load(f) or {}
def get_value(cfg, *paths, default=None):
for path in paths:
current = cfg
found = True
for key in path:
if not isinstance(current, dict) or key not in current:
found = False
break
current = current[key]
if found and current is not None:
return current
return default
def load_app_config(path):
raw = load_raw_config(path)
base_client_id = get_value(raw, ("mqtt", "client-id"), ("client-id",), default="mqtt")
device_code = get_value(
raw,
("tms", "device-code"),
("tms", "equipment-sn"),
("device-code",),
("equipment-sn",),
default="GJ-304-0088",
)
equipment_sn = get_value(
raw,
("tms", "equipment-sn"),
("tms", "device-code"),
("equipment-sn",),
("device-code",),
default=device_code,
)
return AppConfig(
mqtt=MqttConfig(
broker=get_value(raw, ("mqtt", "broker"), ("broker",), default=""),
client_id=base_client_id,
mock_client_id=get_value(raw, ("mqtt", "mock-client-id"), ("mock-client-id",), default=f"{base_client_id}-mock"),
sender_client_id=get_value(raw, ("mqtt", "sender-client-id"), ("sender-client-id",), default=f"{base_client_id}-sender"),
subscriber_client_id=get_value(raw, ("mqtt", "subscriber-client-id"), ("subscriber-client-id",), default=f"{base_client_id}-subscriber"),
username=get_value(raw, ("mqtt", "username"), ("username",)),
password=get_value(raw, ("mqtt", "password"), ("password",)),
pub_topic=get_value(raw, ("mqtt", "pub-topic"), ("pub-topic",)),
sub_topic=get_value(raw, ("mqtt", "sub-topic"), ("sub-topic",)),
ack_topic=get_value(raw, ("mqtt", "ack-topic"), ("ack-topic",)),
data_file=get_value(raw, ("mqtt", "data-file"), ("data-file",), default=""),
),
tms=TmsConfig(
device_code=device_code,
equipment_sn=equipment_sn,
timeout=int(get_value(raw, ("tms", "timeout"), ("timeout",), default=10)),
keepalive=int(get_value(raw, ("tms", "keepalive"), ("keepalive",), default=20)),
server_ip=get_value(raw, ("tms", "server-ip"), ("server-ip",)),
server_port=get_value(raw, ("tms", "server-port"), ("server-port",)),
),
wits=WitsConfig(
host=get_value(raw, ("wits", "host"), ("tms", "server-ip"), ("server-ip",), default=""),
port=int(get_value(raw, ("wits", "port"), ("tms", "server-port"), ("server-port",), default=0)),
timeout=int(get_value(raw, ("wits", "timeout"), ("tms", "timeout"), ("timeout",), default=10)),
source_file=get_value(raw, ("wits", "source-file"), default=""),
),
raw=raw,
)
load_config = load_app_config
from config.config import get_value, load
from config.dependencies import (
MockDependencies,
SenderDependencies,
SubscriberDependencies,
WitsSenderDependencies,
build_mock_dependencies,
build_sender_dependencies,
build_subscriber_dependencies,
build_wits_sender_dependencies,
)
__all__ = [
"AppConfig",
"MqttConfig",
"TmsConfig",
"WitsConfig",
"MockDependencies",
"SenderDependencies",
"SubscriberDependencies",
"WitsSenderDependencies",
"build_mock_dependencies",
"build_sender_dependencies",
"build_subscriber_dependencies",
"build_wits_sender_dependencies",
"get_value",
"load_app_config",
"load_config",
"load_raw_config",
"load",
]

View File

@@ -1,18 +1,83 @@
import yaml
from config.model import *
from model import AppConfig, MqttConfig, TdengineConfig, TmsConfig, WitsConfig
def load(path: str) -> "Config":
def get_value(cfg, *paths, default=None):
for path in paths:
current = cfg
found = True
for key in path:
if not isinstance(current, dict) or key not in current:
found = False
break
current = current[key]
if found and current is not None:
return current
return default
def load(path: str) -> AppConfig:
with open(path, "r", encoding="utf-8") as f:
data = yaml.safe_load(f)
raw = yaml.safe_load(f) or {}
mqtt_cfg = MqttConfig(**data["mqtt"])
tms_cfg = TmsConfig(**data["tms"])
tdengine_cfg = TdengineConfig(**data["tdengine"])
return Config(
mqtt=mqtt_cfg,
tms=tms_cfg,
tdengine=tdengine_cfg
base_client_id = get_value(raw, ("mqtt", "client-id"), ("client-id",), default="mqtt")
device_code = get_value(
raw,
("tms", "device-code"),
("tms", "equipment-sn"),
("device-code",),
("equipment-sn",),
default="GJ-304-0088",
)
equipment_sn = get_value(
raw,
("tms", "equipment-sn"),
("tms", "device-code"),
("equipment-sn",),
("device-code",),
default=device_code,
)
td_url = get_value(raw, ("tdengine", "url"), ("tdengine-url",), default="")
td_database = get_value(raw, ("tdengine", "database"), ("tdengine-database",), default="")
return AppConfig(
mqtt=MqttConfig(
broker=get_value(raw, ("mqtt", "broker"), ("broker",), default=""),
client_id=base_client_id,
mock_client_id=get_value(raw, ("mqtt", "mock-client-id"), ("mock-client-id",), default=f"{base_client_id}-mock"),
sender_client_id=get_value(raw, ("mqtt", "sender-client-id"), ("sender-client-id",), default=f"{base_client_id}-sender"),
subscriber_client_id=get_value(raw, ("mqtt", "subscriber-client-id"), ("subscriber-client-id",), default=f"{base_client_id}-subscriber"),
username=get_value(raw, ("mqtt", "username"), ("username",)),
password=get_value(raw, ("mqtt", "password"), ("password",)),
pub_topic=get_value(raw, ("mqtt", "pub-topic"), ("pub-topic",)),
sub_topic=get_value(raw, ("mqtt", "sub-topic"), ("sub-topic",)),
ack_topic=get_value(raw, ("mqtt", "ack-topic"), ("ack-topic",)),
data_file=get_value(raw, ("mqtt", "data-file"), ("data-file",), default=""),
),
tms=TmsConfig(
device_code=device_code,
equipment_sn=equipment_sn,
timeout=int(get_value(raw, ("tms", "timeout"), ("timeout",), default=10)),
keepalive=int(get_value(raw, ("tms", "keepalive"), ("keepalive",), default=20)),
server_ip=get_value(raw, ("tms", "server-ip"), ("server-ip",)),
server_port=get_value(raw, ("tms", "server-port"), ("server-port",)),
),
wits=WitsConfig(
host=get_value(raw, ("wits", "host"), ("tms", "server-ip"), ("server-ip",), default=""),
port=int(get_value(raw, ("wits", "port"), ("tms", "server-port"), ("server-port",), default=0)),
timeout=int(get_value(raw, ("wits", "timeout"), ("tms", "timeout"), ("timeout",), default=10)),
source_file=get_value(raw, ("wits", "source-file"), default=""),
),
tdengine=TdengineConfig(
url=td_url,
username=get_value(raw, ("tdengine", "username"), ("tdengine-username",), default=""),
password=get_value(raw, ("tdengine", "password"), ("tdengine-password",), default=""),
database=td_database,
stable=get_value(raw, ("tdengine", "stable"), ("tdengine-stable",), default="drilling_realtime_st"),
device_code=get_value(raw, ("tdengine", "device-code"), ("tdengine", "equipment-sn"), default=device_code),
pool_size=int(get_value(raw, ("tdengine", "pool-size"), ("tdengine-pool-size",), default=2)),
timeout=int(get_value(raw, ("tdengine", "timeout"), ("tdengine-timeout",), default=10)),
),
raw=raw,
)

51
config/dependencies.py Normal file
View File

@@ -0,0 +1,51 @@
from dataclasses import dataclass
from config.config import load
from db import TDengineWriter, load_tdengine_config
from model import AppConfig
@dataclass(frozen=True)
class SenderDependencies:
config: AppConfig
@dataclass(frozen=True)
class SubscriberDependencies:
config: AppConfig
@dataclass(frozen=True)
class WitsSenderDependencies:
config: AppConfig
@dataclass(frozen=True)
class MockDependencies:
config: AppConfig
tdengine_config: object
tdengine_writer: object
data_file: str
def build_sender_dependencies(config_path):
return SenderDependencies(config=load(config_path))
def build_subscriber_dependencies(config_path):
return SubscriberDependencies(config=load(config_path))
def build_wits_sender_dependencies(config_path):
return WitsSenderDependencies(config=load(config_path))
def build_mock_dependencies(config_path, data_file_override=""):
app_config = load(config_path)
tdengine_config = load_tdengine_config(app_config, default_device_code=app_config.tms.device_code)
return MockDependencies(
config=app_config,
tdengine_config=tdengine_config,
tdengine_writer=TDengineWriter(tdengine_config),
data_file=data_file_override or app_config.mqtt.data_file,
)

View File

@@ -1,40 +1,12 @@
from dataclasses import dataclass
from model import AppConfig, MqttConfig, TdengineConfig, TmsConfig, WitsConfig
Config = AppConfig
@dataclass
class MqttConfig:
broker: str
client_id: str
mock_client_id: str
sender_client_id: str
subscriber_client_id: str
username: str
password: str
pub_topic: str
@dataclass
class TmsConfig:
device_code: str
equipment_sn: str
timeout: int
keepalive: int
server_ip: str
server_port: int
@dataclass
class TdengineConfig:
url: str
username: str
password: str
database: str
stable: str
device_code: str
@dataclass
class Config:
mqtt: MqttConfig
tms: TmsConfig
tdengine: TdengineConfig
__all__ = [
"Config",
"AppConfig",
"MqttConfig",
"TdengineConfig",
"TmsConfig",
"WitsConfig",
]