Skip to content

Commit 8edec24

Browse files
add basic data retrieval tutorial
1 parent bd4289a commit 8edec24

File tree

3 files changed

+159
-0
lines changed

3 files changed

+159
-0
lines changed

docs/source/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ certain streaming features made possible by OpenSensorHub.
1313
:caption: Contents
1414

1515
api
16+
tutorial
1617

1718

1819

docs/source/tutorial.rst

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
OSH Connect Tutorial
2+
====================
3+
OSH Connect for Python is a straightforward library for interacting with OpenSensorHub using OGC API Connected Systems.
4+
This tutorial will help guide you through a few simple examples to get you started with OSH Connect.
5+
6+
OSH Connect Installation
7+
--------------------------
8+
OSH Connect can be installed using `pip`. To install the latest version of OSH Connect, run the following command:
9+
10+
.. code-block:: bash
11+
12+
pip install git+https://github.com/Botts-Innovative-Research/OSHConnect-Python.git
13+
14+
Or, if you prefer `poetry`:
15+
16+
.. code-block:: bash
17+
18+
poetry add git+https://github.com/Botts-Innovative-Research/OSHConnect-Python.git
19+
20+
Creating an instance of OSHConnect
21+
---------------------------------------
22+
The intended method of interacting with OpenSensorHub is through the `OSHConnect` class.
23+
To this you must first create an instance of `OSHConnect`:
24+
25+
.. code-block:: python
26+
27+
from oshconnect.oshconnectapi import OSHConnect, TemporalModes
28+
29+
connect_app = OSHConnect(name='OSHConnect', playback_mode=TemporalModes.REAL_TIME)
30+
31+
.. tip::
32+
33+
The `name` parameter is optional, but can be useful for debugging purposes.
34+
The playback mode determines how the data is retrieved from OpenSensorHub.
35+
36+
The next step is to add a `Node` to the `OSHConnect` instance. A `Node` is a representation of a server that you want to connect to.
37+
The OSHConnect instance can support multiple Nodes at once.
38+
39+
Adding a Node to an OSHConnect instance
40+
-----------------------------------------
41+
.. code-block:: python
42+
43+
from oshconnect.oshconnectapi import OSHConnect, TemporalModes
44+
from oshconnect.osh_connect_datamodels import Node
45+
46+
connect_app = OSHConnect(name='OSHConnect', playback_mode=TemporalModes.REAL_TIME)
47+
node = Node(protocol='http', address="localhost", port=8585, username="test", password="test")
48+
connect_app.add_node(node)
49+
50+
System Discovery
51+
-----------------------------------------
52+
Once you have added a Node to the OSHConnect instance, you can discover the systems that are available on that Node.
53+
This is done by calling the `discover_systems()` method on the OSHConnect instance.
54+
55+
.. code-block:: python
56+
57+
connect_app.discover_systems()
58+
59+
Datastream Discovery
60+
-----------------------------------------
61+
Once you have discovered the systems that are available on a Node, you can discover the datastreams that are available to those
62+
systems. This is done by calling the `discover_datastreams` method on the OSHConnect instance.
63+
64+
.. code-block:: python
65+
66+
connect_app.discover_datastreams()
67+
68+
Playing back data
69+
-----------------------------------------
70+
Once you have discovered the datastreams that are available on a Node, you can play back the data from those datastreams.
71+
This is done by calling the `playback_streams` method on the OSHConnect instance.
72+
73+
.. code-block:: python
74+
75+
connect_app.playback_streams()
76+
77+
Accessing data
78+
-----------------------------------------
79+
To access the data retrieved from the datastreams, you need to access the messages available to the OSHConnect instance.
80+
Calling the `get_messages` method on the OSHConnect instance will return a list of `MessageWrapper` objects that contain individual
81+
observations.
82+
83+
.. code-block:: python
84+
85+
messages = connect_app.get_messages()
86+
87+
for message in messages:
88+
print(message)
89+
90+
# or, to access the individual observations
91+
for message in messages:
92+
for observation in message.observations:
93+
do_something_with(observation)

oshconnect/control.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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 commit comments

Comments
 (0)