telemetry-server 0.1.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.
app.py ADDED
@@ -0,0 +1,6 @@
1
+ from autoboat_telemetry_server import create_app
2
+
3
+ app = create_app()
4
+
5
+ if __name__ == "__main__":
6
+ app.run()
@@ -0,0 +1,44 @@
1
+ """Telemetry server for Autoboat at Virginia Tech."""
2
+
3
+ import os
4
+ from flask import Flask as _flask
5
+ from autoboat_telemetry_server.routes import AutopilotParametersEndpoint, BoatStatusEndpoint, WaypointEndpoint
6
+
7
+ __all__ = ["create_app"]
8
+
9
+
10
+ def create_app() -> _flask:
11
+ """
12
+ Create and configure the Flask application instance.
13
+
14
+ Returns
15
+ -------
16
+ _flask
17
+ Configured Flask application instance.
18
+ """
19
+
20
+ app = _flask(__name__)
21
+
22
+ instance_dir = "/home/ubuntu/telemetry_server/src/instance"
23
+ config_path = os.path.join(instance_dir, "config.py")
24
+
25
+ app.config.from_pyfile(config_path)
26
+
27
+ app.register_blueprint(AutopilotParametersEndpoint().blueprint)
28
+ app.register_blueprint(BoatStatusEndpoint().blueprint)
29
+ app.register_blueprint(WaypointEndpoint().blueprint)
30
+
31
+ @app.route("/")
32
+ def index() -> str:
33
+ """
34
+ Root route for the telemetry server.
35
+
36
+ Returns
37
+ -------
38
+ str
39
+ Confirmation message indicating which server is running.
40
+ """
41
+
42
+ return "This is the production telemetry server. It is running!"
43
+
44
+ return app
@@ -0,0 +1,29 @@
1
+ """
2
+ Module containing the routes for the Autoboat telemetry server.
3
+
4
+ Autopilot Routes:
5
+ - `/autopilot_parameters/test`: Test route for autopilot parameters.
6
+ - `/autopilot_parameters/get`: Get the current autopilot parameters.
7
+ - `/autopilot_parameters/get_new`: Get the latest autopilot parameters if they haven't been seen yet.
8
+ - `/autopilot_parameters/get_default`: Get the default autopilot parameters.
9
+ - `/autopilot_parameters/set`: Set the autopilot parameters from the request data.
10
+ - `/autopilot_parameters/set_default`: Set the default autopilot parameters from the request data.
11
+
12
+ Boat Status Routes:
13
+ - `/boat_status/test`: Test route for boat status.
14
+ - `/boat_status/get`: Get the current boat status.
15
+ - `/boat_status/get_new`: Get the latest boat status if it hasn't been seen yet.
16
+ - `/boat_status/set`: Set the boat status from the request data.
17
+
18
+ Waypoint Routes:
19
+ - `/waypoints/test`: Test route for waypoints.
20
+ - `/waypoints/get`: Get the current waypoints.
21
+ - `/waypoints/get_new`: Get the latest waypoints if they haven't been seen yet.
22
+ - `/waypoints/set`: Set the waypoints from the request data.
23
+ """
24
+
25
+ __all__ = ["AutopilotParametersEndpoint", "BoatStatusEndpoint", "WaypointEndpoint"]
26
+
27
+ from .autopilot_parameters import AutopilotParametersEndpoint
28
+ from .boat_status import BoatStatusEndpoint
29
+ from .waypoints import WaypointEndpoint
@@ -0,0 +1,176 @@
1
+ from flask import Blueprint, Response, jsonify, request
2
+ from typing import Literal, Any
3
+
4
+
5
+ class AutopilotParametersEndpoint:
6
+ """Endpoint for handling autopilot parameters."""
7
+
8
+ def __init__(self) -> None:
9
+ self._blueprint = Blueprint("autopilot_parameters_page", __name__, url_prefix="/autopilot_parameters")
10
+ self.autopilot_parameters: dict[str, Any] = {}
11
+ self.default_autopilot_parameters: dict[str, Any] = {}
12
+ self.new_flag: bool = False
13
+ self._register_routes()
14
+
15
+ @property
16
+ def blueprint(self) -> Blueprint:
17
+ """Returns the Flask blueprint for autopilot parameters."""
18
+
19
+ return self._blueprint
20
+
21
+ def _register_routes(self) -> str:
22
+ """
23
+ Registers the routes for the autopilot parameters endpoint.
24
+
25
+ Returns
26
+ -------
27
+ str
28
+ Confirmation message indicating the routes have been registered successfully.
29
+ """
30
+
31
+ @self._blueprint.route("/test", methods=["GET"])
32
+ def test_route() -> Literal["autopilot_parameters route testing!"]:
33
+ """
34
+ Test route for autopilot parameters.
35
+
36
+ Method: GET
37
+
38
+ Returns
39
+ -------
40
+ Literal["autopilot_parameters route testing!"]
41
+ Confirmation message for testing the autopilot parameters route.
42
+ """
43
+
44
+ return "autopilot_parameters route testing!"
45
+
46
+ @self._blueprint.route("/get", methods=["GET"])
47
+ def get_route() -> tuple[Response, int]:
48
+ """
49
+ Get the current autopilot parameters.
50
+
51
+ Method: GET
52
+
53
+ Returns
54
+ -------
55
+ tuple[Response, int]
56
+ A tuple containing the JSON response of the autopilot parameters and the HTTP status code.
57
+ """
58
+
59
+ return jsonify(self.autopilot_parameters), 200
60
+
61
+ @self._blueprint.route("/get_new", methods=["GET"])
62
+ def get_new_route() -> tuple[Response, int]:
63
+ """
64
+ Get the latest autopilot parameters if they haven't been seen yet.
65
+
66
+ Method: GET
67
+
68
+ Returns
69
+ -------
70
+ tuple[Response, int]
71
+ A tuple containing the JSON response of the autopilot parameters if new,
72
+ otherwise an empty JSON object, along with the HTTP status code.
73
+ """
74
+
75
+ if self.new_flag:
76
+ self.new_flag = False
77
+ return jsonify(self.autopilot_parameters), 200
78
+
79
+ else:
80
+ return jsonify({}), 200
81
+
82
+ @self._blueprint.route("/get_default", methods=["GET"])
83
+ def get_default_route() -> tuple[Response, int]:
84
+ """
85
+ Get the default autopilot parameters.
86
+
87
+ Method: GET
88
+
89
+ Returns
90
+ -------
91
+ tuple[Response, int]
92
+ A tuple containing the JSON response of the default autopilot parameters and the HTTP status code.
93
+ """
94
+
95
+ return jsonify(self.default_autopilot_parameters), 200
96
+
97
+ @self._blueprint.route("/set", methods=["POST"])
98
+ def set_route() -> tuple[Response, int]:
99
+ """
100
+ Set the autopilot parameters from the request data.
101
+
102
+ Method: POST
103
+
104
+ Returns
105
+ -------
106
+ tuple[Response, int]
107
+ A tuple containing a success message or error message and the corresponding HTTP status code.
108
+ """
109
+
110
+ try:
111
+ new_parameters = request.json
112
+ if not isinstance(new_parameters, dict):
113
+ raise TypeError("Invalid autopilot parameters format. Expected a dictionary.")
114
+
115
+ if self.default_autopilot_parameters != {}:
116
+ new_parameters_keys = list(new_parameters.keys())
117
+ if len(new_parameters_keys) == 1 and new_parameters_keys[0] in self.default_autopilot_parameters:
118
+ self.autopilot_parameters[new_parameters_keys[0]] = new_parameters[new_parameters_keys[0]]
119
+
120
+ elif new_parameters_keys == list(self.default_autopilot_parameters.keys()):
121
+ self.autopilot_parameters = new_parameters
122
+
123
+ else:
124
+ raise ValueError("Invalid keys in autopilot parameters.")
125
+
126
+ else:
127
+ self.autopilot_parameters = new_parameters
128
+
129
+ self.new_flag = True
130
+ return jsonify("Autopilot parameters updated successfully."), 200
131
+
132
+ except TypeError as e:
133
+ return jsonify(str(e)), 400
134
+
135
+ except ValueError as e:
136
+ return jsonify(str(e)), 400
137
+
138
+ except Exception as e:
139
+ return jsonify(str(e)), 500
140
+
141
+ @self._blueprint.route("/set_default", methods=["POST"])
142
+ def set_default_route() -> tuple[Response, int]:
143
+ """
144
+ Set the default autopilot parameters from the request data.
145
+
146
+ Method: POST
147
+
148
+ Returns
149
+ -------
150
+ tuple[Response, int]
151
+ A tuple containing a success message or error message and the corresponding HTTP status code.
152
+ """
153
+
154
+ try:
155
+ new_default_parameters = request.json
156
+ if not isinstance(new_default_parameters, dict):
157
+ raise TypeError("Invalid default autopilot parameters format. Expected a dictionary.")
158
+
159
+ if new_default_parameters != {}:
160
+ filtered_autopilot_parameters = {}
161
+ for key in new_default_parameters:
162
+ if key in self.default_autopilot_parameters:
163
+ filtered_autopilot_parameters[key] = new_default_parameters[key]
164
+
165
+ self.autopilot_parameters = filtered_autopilot_parameters
166
+
167
+ self.default_autopilot_parameters = new_default_parameters
168
+ return jsonify("Default autopilot parameters updated successfully."), 200
169
+
170
+ except TypeError as e:
171
+ return jsonify(str(e)), 400
172
+
173
+ except Exception as e:
174
+ return jsonify(str(e)), 500
175
+
176
+ return f"autopilot_parameters paths registered successfully: {self._blueprint.url_prefix}"
@@ -0,0 +1,108 @@
1
+ from flask import Blueprint, Response, jsonify, request
2
+ from typing import Literal, Any
3
+
4
+
5
+ class BoatStatusEndpoint:
6
+ """Endpoint for handling boat status."""
7
+
8
+ def __init__(self) -> None:
9
+ self._blueprint = Blueprint("boat_status_page", __name__, url_prefix="/boat_status")
10
+ self.boat_status: dict[str, Any] = {}
11
+ self.new_flag: bool = False
12
+ self._register_routes()
13
+
14
+ @property
15
+ def blueprint(self) -> Blueprint:
16
+ """Returns the Flask blueprint for autopilot parameters."""
17
+ return self._blueprint
18
+
19
+ def _register_routes(self) -> str:
20
+ """
21
+ Registers the routes for the boat status endpoint.
22
+
23
+ Returns
24
+ -------
25
+ str
26
+ Confirmation message indicating the routes have been registered successfully.
27
+ """
28
+
29
+ @self._blueprint.route("/test", methods=["GET"])
30
+ def test_route() -> Literal["boat_status route testing!"]:
31
+ """
32
+ Test route for boat status.
33
+
34
+ Method: GET
35
+
36
+ Returns
37
+ -------
38
+ Literal["boat_status route testing!"]
39
+ Confirmation message for testing the boat status route.
40
+ """
41
+
42
+ return "boat_status route testing!"
43
+
44
+ @self._blueprint.route("/get", methods=["GET"])
45
+ def get_route() -> tuple[Response, int]:
46
+ """
47
+ Get the current boat status.
48
+
49
+ Method: GET
50
+
51
+ Returns
52
+ -------
53
+ tuple[Response, int]
54
+ A tuple containing the JSON response of the boat status and the HTTP status code.
55
+ """
56
+
57
+ return jsonify(self.boat_status)
58
+
59
+ @self._blueprint.route("/get_new", methods=["GET"])
60
+ def get_new_route() -> tuple[Response, int]:
61
+ """
62
+ Get the latest boat status if it hasn't been seen yet.
63
+
64
+ Method: GET
65
+
66
+ Returns
67
+ -------
68
+ tuple[Response, int]
69
+ A tuple containing the JSON response of the new boat status (or empty if none) and the HTTP status code.
70
+ """
71
+
72
+ if self.new_flag:
73
+ self.new_flag = False
74
+ return jsonify(self.boat_status), 200
75
+
76
+ else:
77
+ return jsonify({}), 200
78
+
79
+ @self._blueprint.route("/set", methods=["POST"])
80
+ def set_route() -> tuple[Response, int]:
81
+ """
82
+ Set the boat status from the request data.
83
+
84
+ Method: POST
85
+
86
+ Returns
87
+ -------
88
+ tuple[Response, int]
89
+ A tuple containing a confirmation message and the HTTP status code.
90
+ """
91
+
92
+ try:
93
+ new_status = request.json
94
+ if not isinstance(new_status, dict):
95
+ raise TypeError("Invalid boat status format. Expected a dictionary.")
96
+
97
+ self.boat_status = new_status
98
+ self.new_flag = True
99
+
100
+ return jsonify("Boat status updated successfully."), 200
101
+
102
+ except TypeError as e:
103
+ return jsonify(str(e)), 400
104
+
105
+ except Exception as e:
106
+ return jsonify(str(e)), 500
107
+
108
+ return f"boat_status paths registered successfully: {self._blueprint.url_prefix}"
@@ -0,0 +1,108 @@
1
+ from flask import Blueprint, Response, jsonify, request
2
+ from typing import Literal
3
+
4
+
5
+ class WaypointEndpoint:
6
+ """Endpoint for handling waypoints."""
7
+
8
+ def __init__(self) -> None:
9
+ self._blueprint = Blueprint("waypoints_page", __name__, url_prefix="/waypoints")
10
+ self.waypoints: list[list[float]] = []
11
+ self.new_flag: bool = False
12
+ self._register_routes()
13
+
14
+ @property
15
+ def blueprint(self) -> Blueprint:
16
+ """Returns the Flask blueprint for autopilot parameters."""
17
+ return self._blueprint
18
+
19
+ def _register_routes(self) -> str:
20
+ """
21
+ Registers the routes for the waypoints endpoint.
22
+
23
+ Returns
24
+ -------
25
+ str
26
+ Confirmation message indicating the routes have been registered successfully.
27
+ """
28
+
29
+ @self._blueprint.route("/test", methods=["GET"])
30
+ def test_route() -> Literal["waypoints route testing!"]:
31
+ """
32
+ Test route for waypoints.
33
+
34
+ Method: GET
35
+
36
+ Returns
37
+ -------
38
+ Literal["waypoints route testing!"]
39
+ Confirmation message for testing the waypoints route.
40
+ """
41
+
42
+ return "waypoints route testing!"
43
+
44
+ @self._blueprint.route("/get", methods=["GET"])
45
+ def get_route() -> tuple[Response, int]:
46
+ """
47
+ Get the current waypoints.
48
+
49
+ Method: GET
50
+
51
+ Returns
52
+ -------
53
+ tuple[Response, int]
54
+ A tuple containing the JSON response of the waypoints and the HTTP status code.
55
+ """
56
+
57
+ return jsonify(self.waypoints), 200
58
+
59
+ @self._blueprint.route("/get_new", methods=["GET"])
60
+ def get_new_route() -> tuple[Response, int]:
61
+ """
62
+ Get the latest waypoints if they haven't been seen yet.
63
+
64
+ Method: GET
65
+
66
+ Returns
67
+ -------
68
+ tuple[Response, int]
69
+ A tuple containing the JSON response of the new waypoints (or empty if none) and the HTTP status code.
70
+ """
71
+
72
+ if self.new_flag:
73
+ self.new_flag = False
74
+ return jsonify(self.waypoints), 200
75
+
76
+ else:
77
+ return jsonify({}), 200
78
+
79
+ @self._blueprint.route("/set", methods=["POST"])
80
+ def set_route() -> tuple[Response, int]:
81
+ """
82
+ Set the waypoints from the request data.
83
+
84
+ Method: POST
85
+
86
+ Returns
87
+ -------
88
+ tuple[Response, int]
89
+ A tuple containing a confirmation message and the HTTP status code.
90
+ """
91
+
92
+ try:
93
+ new_waypoints = request.json
94
+ if not isinstance(new_waypoints, list):
95
+ raise TypeError("Invalid waypoints format. Expected a list of lists of floats.")
96
+
97
+ self.waypoints = new_waypoints
98
+ self.new_flag = True
99
+
100
+ return jsonify("Waypoints updated successfully."), 200
101
+
102
+ except TypeError as e:
103
+ return jsonify(str(e)), 400
104
+
105
+ except Exception as e:
106
+ return jsonify(str(e)), 500
107
+
108
+ return f"waypoints paths registered successfully: {self._blueprint.url_prefix}"
instance/config.py ADDED
@@ -0,0 +1,5 @@
1
+ import os
2
+
3
+ BASE_DIR = os.path.abspath(os.path.dirname(__file__))
4
+ SQLALCHEMY_DATABASE_URI = f"sqlite:///{os.path.join(BASE_DIR, 'app.db')}"
5
+ SQLALCHEMY_TRACK_MODIFICATIONS = False
@@ -0,0 +1,58 @@
1
+ Metadata-Version: 2.4
2
+ Name: telemetry_server
3
+ Version: 0.1.0
4
+ Project-URL: repository, https://github.com/autoboat-vt/telemetry_server
5
+ Description-Content-Type: text/markdown
6
+ Requires-Dist: flask
7
+ Requires-Dist: gunicorn
8
+
9
+ # Autoboat Telemetry Server
10
+
11
+ A lightweight Flask-based web server to collect, display, and manage telemetry data from the Virginia Tech Autoboat project.
12
+
13
+ ## 📦 Project Structure
14
+
15
+ ```txt
16
+ autoboat_telemetry_server/
17
+ ├── __init__.py # App factory
18
+ ├── routes
19
+ ├── __init__.py # Routes initialization
20
+ ├── autopilot_parameters.py # Autopilot parameters routes
21
+ ├── boat_status.py # Boat status routes
22
+ ├── waypoints.py # Waypoints management routes
23
+
24
+ instance/
25
+ ├── config.py # Configuration file
26
+ ```
27
+
28
+ ## 🚀 Quick Start
29
+
30
+ ### Installation
31
+
32
+ ```bash
33
+ pip install -e .
34
+ ```
35
+
36
+ ### Running the server
37
+
38
+ 1. Production ([Gunicorn](https://gunicorn.org/)):
39
+
40
+ ```bash
41
+ gunicorn "autoboat_telemetry_server:create_app()"
42
+ ```
43
+
44
+ 2. Development (Flask):
45
+
46
+ ```bash
47
+ flask run
48
+ ```
49
+
50
+ ## Server (Long term)
51
+
52
+ ### Installation
53
+
54
+ ```bash
55
+ git clone https://github.com/autoboat-vt/telemetry_server
56
+ cd telemetry_server
57
+ ./server_files/install.sh
58
+ ```
@@ -0,0 +1,11 @@
1
+ app.py,sha256=bia5RTM3ljRs6u2ANIwTsahzu48CmUzqNmMGxJTASpI,111
2
+ autoboat_telemetry_server/__init__.py,sha256=La0KoBk2RGZVNq-MoJCF0YOx7ocbvsx8c9yrz-gTev0,1117
3
+ autoboat_telemetry_server/routes/__init__.py,sha256=ru7YCQu4qAVnJDHA4M8fN3FkkiMEFpHc4RKFE3hXnvk,1344
4
+ autoboat_telemetry_server/routes/autopilot_parameters.py,sha256=WQ5pjKABPP0c-BUM8BReTUrtUGY1AUwWA4wSybremzg,6258
5
+ autoboat_telemetry_server/routes/boat_status.py,sha256=XgbrsB4niUDTCMa_0x3mANpOLROH2hKMiEE0X5D23F0,3272
6
+ autoboat_telemetry_server/routes/waypoints.py,sha256=_qpy3DNLlLh0bEUXjYQbr6cv3DAhEbWLPzys0qeWmw8,3256
7
+ instance/config.py,sha256=Ll7E0tPZ91v5XNLmEkhbSa793-ugFRCDF7olhXyvEdU,178
8
+ telemetry_server-0.1.0.dist-info/METADATA,sha256=sHTd7-tn0_D36rhLLOR03HwBjzDuN2Y_GC2vevRV_bA,1285
9
+ telemetry_server-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
10
+ telemetry_server-0.1.0.dist-info/top_level.txt,sha256=GK0z6liXhI5z6-OmWt5pjq3CaxQ98wguiMhFHonnKvM,39
11
+ telemetry_server-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,3 @@
1
+ app
2
+ autoboat_telemetry_server
3
+ instance