-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmodels.py
More file actions
142 lines (111 loc) · 3.81 KB
/
models.py
File metadata and controls
142 lines (111 loc) · 3.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
"""Data models - Compatible with Go types"""
from __future__ import annotations
import time
from dataclasses import dataclass, field
from enum import Enum
from typing import Any
class DeviceState(Enum):
"""Device connection state
States:
DISCONNECTED: Device is not connected
CONNECTING: Device is attempting to connect
CONNECTED: Device is connected and operational
RECONNECTING: Device is attempting to reconnect after disconnection
ERROR: Device encountered an error
"""
DISCONNECTED = "disconnected"
CONNECTING = "connecting"
CONNECTED = "connected"
RECONNECTING = "reconnecting"
ERROR = "error"
@dataclass
class TagValue:
"""Individual tag value - Compatible with Go's TagValue
Attributes:
name: Tag name (required)
quality: Data quality (GOOD, BAD, UNCERTAIN)
number: Numeric value (float)
text: String value
flag: Boolean value
unit: Unit (e.g., °C, %, mm/s)
"""
name: str
quality: str = "GOOD"
number: float | None = None
text: str | None = None
flag: bool | None = None
unit: str = ""
def to_dict(self) -> dict[str, Any]:
"""Convert to dictionary for JSON serialization - exclude None values"""
result: dict[str, Any] = {"name": self.name, "quality": self.quality}
if self.number is not None:
result["number"] = self.number
if self.text is not None:
result["text"] = self.text
if self.flag is not None:
result["flag"] = self.flag
if self.unit:
result["unit"] = self.unit
return result
@dataclass
class AssetData:
"""Asset data - Compatible with Go's AssetData
Attributes:
asset_id: Asset identifier
timestamp: Timestamp (milliseconds, epoch)
values: List of tag values
metadata: Additional metadata
"""
asset_id: str
values: list[TagValue]
timestamp: int = field(default_factory=lambda: int(time.time() * 1000))
metadata: dict[str, str] | None = None
def to_dict(self) -> dict[str, Any]:
"""Convert to dictionary for JSON serialization"""
result: dict[str, Any] = {
"asset_id": self.asset_id,
"timestamp": self.timestamp,
"values": [v.to_dict() for v in self.values],
}
if self.metadata:
result["metadata"] = self.metadata
return result
class RelationType:
"""Relation types - Compatible with Go's RelationType constants
Maps to semantic web vocabularies:
- PART_OF: ssn:isPartOf (hierarchical relationship)
- CONNECTED_TO: sosa:isHostedBy (peer/network connection)
- LOCATED_IN: schema:containedInPlace (spatial containment)
"""
PART_OF = "partOf"
CONNECTED_TO = "connectedTo"
LOCATED_IN = "locatedIn"
@dataclass
class AssetRelation:
"""Asset relation - Compatible with Go's AssetRelation
Attributes:
id: Relation identifier
source_asset_id: Source asset ID
target_asset_id: Target asset ID
relation_type: Type of relation (partOf, connectedTo, locatedIn)
created_at: Timestamp (milliseconds, epoch)
metadata: Additional metadata
"""
id: str
source_asset_id: str
target_asset_id: str
relation_type: str
created_at: int
metadata: dict[str, str] | None = None
def to_dict(self) -> dict[str, Any]:
"""Convert to dictionary for JSON serialization"""
result: dict[str, Any] = {
"id": self.id,
"source_asset_id": self.source_asset_id,
"target_asset_id": self.target_asset_id,
"relation_type": self.relation_type,
"created_at": self.created_at,
}
if self.metadata:
result["metadata"] = self.metadata
return result