完善牧安云哨-后端
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class MqttTopic:
|
||||
"""
|
||||
封装 MQTT topic,根据规则:
|
||||
project/domain/deviceType/deviceId/resource
|
||||
"""
|
||||
|
||||
LEVELS = 5
|
||||
|
||||
def __init__(self, topic: str):
|
||||
self.raw = str(topic)
|
||||
parts = self.raw.split("/")
|
||||
|
||||
# 不足的层级用 None 补齐,避免属性缺失
|
||||
parts += [None] * (self.LEVELS - len(parts))
|
||||
|
||||
self.project: Optional[str] = parts[0]
|
||||
self.domain: Optional[str] = parts[1]
|
||||
self.device_type: Optional[str] = parts[2]
|
||||
self.device_id: Optional[str] = parts[3]
|
||||
self.resource: Optional[str] = parts[4]
|
||||
|
||||
@classmethod
|
||||
def from_parts(
|
||||
cls,
|
||||
project: Optional[str] = None,
|
||||
domain: Optional[str] = None,
|
||||
device_type: Optional[str] = None,
|
||||
device_id: Optional[str] = None,
|
||||
resource: Optional[str] = None,
|
||||
) -> "MqttTopic":
|
||||
"""
|
||||
通过结构化参数构造 topic
|
||||
None -> '+'
|
||||
"""
|
||||
|
||||
def _v(v: Optional[str]) -> str:
|
||||
return "+" if v is None else str(v)
|
||||
|
||||
topic = "/".join(
|
||||
map(
|
||||
_v,
|
||||
[
|
||||
project,
|
||||
domain,
|
||||
device_type,
|
||||
device_id,
|
||||
resource,
|
||||
],
|
||||
)
|
||||
)
|
||||
return cls(topic)
|
||||
|
||||
def to_topic(self) -> str:
|
||||
"""
|
||||
根据当前字段生成 topic(允许 '+')
|
||||
"""
|
||||
|
||||
def _v(v: Optional[str]) -> str:
|
||||
return "+" if v is None else v
|
||||
|
||||
return "/".join(
|
||||
map(
|
||||
_v,
|
||||
[
|
||||
self.project,
|
||||
self.domain,
|
||||
self.device_type,
|
||||
self.device_id,
|
||||
self.resource,
|
||||
],
|
||||
)
|
||||
)
|
||||
|
||||
def build(self) -> str:
|
||||
"""
|
||||
生成严格 topic(不允许 None / '+')
|
||||
用于 publish 场景
|
||||
"""
|
||||
parts = [
|
||||
self.project,
|
||||
self.domain,
|
||||
self.device_type,
|
||||
self.device_id,
|
||||
self.resource,
|
||||
]
|
||||
|
||||
if any(p in (None, "+") for p in parts):
|
||||
raise ValueError(
|
||||
f"Cannot build strict topic, wildcard exists: {self.to_topic()}"
|
||||
)
|
||||
|
||||
return "/".join(parts)
|
||||
|
||||
def is_wildcard(self) -> bool:
|
||||
return "+" in self.to_topic() or "#" in self.to_topic()
|
||||
|
||||
def __repr__(self):
|
||||
return f"<MqttTopic {self.to_topic()}>"
|
||||
|
||||
def is_status(self) -> bool:
|
||||
return self.domain == "status"
|
||||
|
||||
def is_cmd(self) -> bool:
|
||||
return self.domain == "cmd"
|
||||
Reference in New Issue
Block a user