oshconnect 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
oshconnect/__init__.py ADDED
@@ -0,0 +1,9 @@
1
+ # ==============================================================================
2
+ # Copyright (c) 2024 Botts Innovative Research, Inc.
3
+ # Date: 2024/5/28
4
+ # Author: Ian Patterson
5
+ # Contact Email: ian@botts-inc.com
6
+ # ==============================================================================
7
+
8
+ class Example:
9
+ pass
oshconnect/control.py ADDED
@@ -0,0 +1,65 @@
1
+ # ==============================================================================
2
+ # Copyright (c) 2024 Botts Innovative Research, Inc.
3
+ # Date: 2024/7/1
4
+ # Author: Ian Patterson
5
+ # Contact Email: ian@botts-inc.com
6
+ # ==============================================================================
7
+ import websockets
8
+ from conSys4Py.comm.mqtt import MQTTCommClient
9
+ from conSys4Py.datamodels.commands import CommandJSON
10
+ from conSys4Py.datamodels.control_streams import ControlStreamJSONSchema
11
+
12
+ from oshconnect.osh_connect_datamodels import System
13
+
14
+
15
+ class ControlSchema:
16
+ schema: dict = None
17
+
18
+
19
+ class ControlStream:
20
+ name: str = None
21
+ _parent_systems: System = None
22
+ _strategy: str = "mqtt"
23
+ _resource_endpoint = None
24
+ # _auth: str = None
25
+ _websocket: websockets.WebSocketServerProtocol = None
26
+ _schema: ControlStreamJSONSchema = None
27
+ _mqtt_client: MQTTCommClient = None
28
+
29
+ def __init__(self, parent_system: System, resource_endpoint: str, name=None, strategy="mqtt"):
30
+ self._parent_systems = parent_system
31
+ self.name = name
32
+ self._strategy = strategy
33
+ self._resource_endpoint = resource_endpoint
34
+
35
+ def set_schema(self, schema: ControlStreamJSONSchema):
36
+ self._schema = schema
37
+
38
+ def connect(self):
39
+ pass
40
+
41
+ def subscribe(self):
42
+ if self._strategy == "mqtt" and self._mqtt_client is not None:
43
+ self._mqtt_client.subscribe(f'{self._resource_endpoint}/commands')
44
+ elif self._strategy == "mqtt" and self._mqtt_client is None:
45
+ raise ValueError("No MQTT Client found.")
46
+ elif self._strategy == "websocket":
47
+ pass
48
+
49
+ def publish(self, payload: CommandJSON):
50
+ if self._strategy == "mqtt" and self._mqtt_client is not None:
51
+ self._mqtt_client.publish(f'{self._resource_endpoint}/status', payload=payload, qos=1)
52
+ elif self._strategy == "mqtt" and self._mqtt_client is None:
53
+ raise ValueError("No MQTT Client found.")
54
+ elif self._strategy == "websocket":
55
+ pass
56
+
57
+ def disconnect(self):
58
+ pass
59
+
60
+ def unsubscribe(self):
61
+ self._mqtt_client.unsubscribe(f'{self._resource_endpoint}/commands')
62
+
63
+
64
+ class Command:
65
+ pass
@@ -0,0 +1,160 @@
1
+ # ==============================================================================
2
+ # Copyright (c) 2024 Botts Innovative Research, Inc.
3
+ # Date: 2024/6/26
4
+ # Author: Ian Patterson
5
+ # Contact Email: ian@botts-inc.com
6
+ # ==============================================================================
7
+ from __future__ import annotations
8
+
9
+ from typing import List
10
+
11
+ from conSys4Py.datamodels.swe_components import Geometry
12
+ from conSys4Py.datamodels.datastreams import DatastreamSchema
13
+ from conSys4Py.datamodels.api_utils import Link
14
+ from pydantic import BaseModel, ConfigDict, Field, SerializeAsAny
15
+ from shapely import Point
16
+
17
+ from oshconnect.timemanagement import DateTimeSchema, TimePeriod
18
+
19
+
20
+ class BoundingBox(BaseModel):
21
+ model_config = ConfigDict(arbitrary_types_allowed=True)
22
+
23
+ lower_left_corner: Point = Field(..., description="The lower left corner of the bounding box.")
24
+ upper_right_corner: Point = Field(..., description="The upper right corner of the bounding box.")
25
+ min_value: float = Field(None, description="The minimum value of the bounding box.")
26
+ max_value: float = Field(None, description="The maximum value of the bounding box.")
27
+
28
+ # @model_validator(mode='before')
29
+ # def validate_minmax(self) -> Self:
30
+ # if self.min_value > self.max_value:
31
+ # raise ValueError("min_value must be less than max_value")
32
+ # return self
33
+
34
+
35
+ class SecurityConstraints:
36
+ constraints: list
37
+
38
+
39
+ class LegalConstraints:
40
+ constraints: list
41
+
42
+
43
+ class Characteristics:
44
+ characteristics: list
45
+
46
+
47
+ class Capabilities:
48
+ capabilities: list
49
+
50
+
51
+ class Contact:
52
+ contact: list
53
+
54
+
55
+ class Documentation:
56
+ documentation: list
57
+
58
+
59
+ class HistoryEvent:
60
+ history_event: list
61
+
62
+
63
+ class ConfigurationSettings:
64
+ settings: list
65
+
66
+
67
+ class FeatureOfInterest:
68
+ feature: list
69
+
70
+
71
+ class Input:
72
+ input: list
73
+
74
+
75
+ class Output:
76
+ output: list
77
+
78
+
79
+ class Parameter:
80
+ parameter: list
81
+
82
+
83
+ class Mode:
84
+ mode: list
85
+
86
+
87
+ class ProcessMethod:
88
+ method: list
89
+
90
+
91
+ class SystemResource(BaseModel):
92
+ model_config = ConfigDict(arbitrary_types_allowed=True)
93
+
94
+ feature_type: str = Field(None, serialization_alias="type")
95
+ system_id: str = Field(None, serialization_alias="id")
96
+ properties: dict = Field(None)
97
+ geometry: Geometry | None = Field(None)
98
+ bbox: BoundingBox = Field(None)
99
+ links: List[Link] = Field(None)
100
+ description: str = Field(None)
101
+ uid: str = Field(None, serialization_alias="uniqueId")
102
+ label: str = Field(None)
103
+ lang: str = Field(None)
104
+ keywords: List[str] = Field(None)
105
+ identifiers: List[str] = Field(None)
106
+ classifiers: List[str] = Field(None)
107
+ valid_time: DateTimeSchema = Field(None, serialization_alias="validTime")
108
+ security_constraints: List[SecurityConstraints] = Field(None, serialization_alias="securityConstraints")
109
+ legal_constraints: List[LegalConstraints] = Field(None, serialization_alias="legalConstraints")
110
+ characteristics: List[Characteristics] = Field(None)
111
+ capabilities: List[Capabilities] = Field(None)
112
+ contacts: List[Contact] = Field(None)
113
+ documentation: List[Documentation] = Field(None)
114
+ history: List[HistoryEvent] = Field(None)
115
+ definition: str = Field(None)
116
+ type_of: str = Field(None, serialization_alias="typeOf")
117
+ configuration: ConfigurationSettings = Field(None)
118
+ features_of_interest: List[FeatureOfInterest] = Field(None, serialization_alias="featuresOfInterest")
119
+ inputs: List[Input] = Field(None)
120
+ outputs: List[Output] = Field(None)
121
+ parameters: List[Parameter] = Field(None)
122
+ modes: List[Mode] = Field(None)
123
+ method: ProcessMethod = Field(None)
124
+
125
+
126
+ class DatastreamResource(BaseModel):
127
+ """
128
+ The DatastreamResource class is a Pydantic model that represents a datastream resource in the OGC SensorThings API.
129
+ It contains all the necessary and optional properties listed in the OGC Connected Systems API documentation. Note
130
+ that, depending on the format of the request, the fields needed may differ. There may be derived models in a later
131
+ release that will have different sets of required fields to ease the validation process for users.
132
+ """
133
+ # model_config = ConfigDict(populate_by_name=True)
134
+
135
+ ds_id: str = Field(..., serialization_alias="id")
136
+ name: str = Field(...)
137
+ description: str = Field(None)
138
+ valid_time: TimePeriod = Field(..., serialization_alias="validTime")
139
+ output_name: str = Field(None, serialization_alias="outputName")
140
+ procedure_link: Link = Field(None, serialization_alias="procedureLink@link")
141
+ deployment_link: Link = Field(None, serialization_alias="deploymentLink@link")
142
+ ultimate_feature_of_interest_link: Link = Field(None, serialization_alias="ultimateFeatureOfInterest@link")
143
+ sampling_feature_link: Link = Field(None, serialization_alias="samplingFeature@link")
144
+ parameters: dict = Field(None)
145
+ phenomenon_time: TimePeriod = Field(None, serialization_alias="phenomenonTimeInterval")
146
+ result_time: TimePeriod = Field(None, serialization_alias="resultTimeInterval")
147
+ ds_type: str = Field(None, serialization_alias="type")
148
+ result_type: str = Field(None, serialization_alias="resultType")
149
+ links: List[Link] = Field(None)
150
+ record_schema: SerializeAsAny[DatastreamSchema] = Field(None, serialization_alias="schema")
151
+
152
+
153
+ class ObservationResource(BaseModel):
154
+ sampling_feature_id: str = Field(None, serialization_alias="samplingFeature@Id")
155
+ procedure_link: Link = Field(None, serialization_alias="procedure@link")
156
+ phenomenon_time: DateTimeSchema = Field(None, serialization_alias="phenomenonTime")
157
+ result_time: DateTimeSchema = Field(..., serialization_alias="resultTime")
158
+ parameters: dict = Field(None)
159
+ result: dict = Field(...)
160
+ result_link: Link = Field(None, serialization_alias="result@link")