plexus-python 0.1.0__py3-none-any.whl → 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.
- plexus/__init__.py +4 -22
- plexus/client.py +4 -4
- plexus/config.py +11 -29
- plexus_python-0.2.0.dist-info/METADATA +140 -0
- plexus_python-0.2.0.dist-info/RECORD +8 -0
- plexus/__main__.py +0 -4
- plexus/adapters/__init__.py +0 -122
- plexus/adapters/base.py +0 -409
- plexus/adapters/ble.py +0 -257
- plexus/adapters/can.py +0 -439
- plexus/adapters/can_detect.py +0 -174
- plexus/adapters/mavlink.py +0 -642
- plexus/adapters/mavlink_detect.py +0 -192
- plexus/adapters/modbus.py +0 -622
- plexus/adapters/mqtt.py +0 -350
- plexus/adapters/opcua.py +0 -607
- plexus/adapters/registry.py +0 -206
- plexus/adapters/serial_adapter.py +0 -547
- plexus/cameras/__init__.py +0 -57
- plexus/cameras/auto.py +0 -239
- plexus/cameras/base.py +0 -189
- plexus/cameras/picamera.py +0 -171
- plexus/cameras/usb.py +0 -143
- plexus/cli.py +0 -783
- plexus/connector.py +0 -666
- plexus/deps.py +0 -246
- plexus/detect.py +0 -1238
- plexus/importers/__init__.py +0 -25
- plexus/importers/rosbag.py +0 -778
- plexus/sensors/__init__.py +0 -118
- plexus/sensors/ads1115.py +0 -164
- plexus/sensors/adxl345.py +0 -179
- plexus/sensors/auto.py +0 -290
- plexus/sensors/base.py +0 -412
- plexus/sensors/bh1750.py +0 -102
- plexus/sensors/bme280.py +0 -241
- plexus/sensors/gps.py +0 -317
- plexus/sensors/ina219.py +0 -149
- plexus/sensors/magnetometer.py +0 -239
- plexus/sensors/mpu6050.py +0 -162
- plexus/sensors/sht3x.py +0 -139
- plexus/sensors/spi_scan.py +0 -164
- plexus/sensors/system.py +0 -261
- plexus/sensors/vl53l0x.py +0 -109
- plexus/streaming.py +0 -743
- plexus/tui.py +0 -642
- plexus_python-0.1.0.dist-info/METADATA +0 -470
- plexus_python-0.1.0.dist-info/RECORD +0 -50
- plexus_python-0.1.0.dist-info/entry_points.txt +0 -2
- {plexus_python-0.1.0.dist-info → plexus_python-0.2.0.dist-info}/WHEEL +0 -0
- {plexus_python-0.1.0.dist-info → plexus_python-0.2.0.dist-info}/licenses/LICENSE +0 -0
plexus/__init__.py
CHANGED
|
@@ -1,31 +1,13 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Plexus
|
|
2
|
+
Plexus — thin Python SDK for sending telemetry to the Plexus gateway.
|
|
3
3
|
|
|
4
|
-
Basic Usage:
|
|
5
4
|
from plexus import Plexus
|
|
6
5
|
|
|
7
|
-
px = Plexus()
|
|
6
|
+
px = Plexus(api_key="plx_xxx", source_id="device-001")
|
|
8
7
|
px.send("temperature", 72.5)
|
|
9
|
-
|
|
10
|
-
With Sensors (pip install plexus-python[sensors]):
|
|
11
|
-
from plexus import Plexus
|
|
12
|
-
from plexus.sensors import SensorHub, MPU6050, BME280
|
|
13
|
-
|
|
14
|
-
hub = SensorHub()
|
|
15
|
-
hub.add(MPU6050(sample_rate=100))
|
|
16
|
-
hub.add(BME280(sample_rate=1))
|
|
17
|
-
hub.run(Plexus())
|
|
18
|
-
|
|
19
|
-
Auto-Detection:
|
|
20
|
-
from plexus import Plexus
|
|
21
|
-
from plexus.sensors import auto_sensors
|
|
22
|
-
|
|
23
|
-
hub = auto_sensors() # Finds all connected sensors
|
|
24
|
-
hub.run(Plexus())
|
|
25
8
|
"""
|
|
26
9
|
|
|
27
10
|
from plexus.client import Plexus
|
|
28
|
-
from plexus.config import load_config, save_config
|
|
29
11
|
|
|
30
|
-
__version__ = "0.
|
|
31
|
-
__all__ = ["Plexus"
|
|
12
|
+
__version__ = "0.2.0"
|
|
13
|
+
__all__ = ["Plexus"]
|
plexus/client.py
CHANGED
|
@@ -49,7 +49,6 @@ from plexus.config import (
|
|
|
49
49
|
get_endpoint,
|
|
50
50
|
get_gateway_url,
|
|
51
51
|
get_source_id,
|
|
52
|
-
require_login,
|
|
53
52
|
)
|
|
54
53
|
logger = logging.getLogger(__name__)
|
|
55
54
|
|
|
@@ -98,10 +97,11 @@ class Plexus:
|
|
|
98
97
|
buffer_path: Optional[str] = None,
|
|
99
98
|
):
|
|
100
99
|
self.api_key = api_key or get_api_key()
|
|
101
|
-
|
|
102
|
-
# Require login if no API key provided
|
|
103
100
|
if not self.api_key:
|
|
104
|
-
|
|
101
|
+
raise ValueError(
|
|
102
|
+
"No API key. Pass api_key=... or set PLEXUS_API_KEY. "
|
|
103
|
+
"Get a key at app.plexus.company/devices."
|
|
104
|
+
)
|
|
105
105
|
|
|
106
106
|
self.endpoint = (endpoint or get_endpoint()).rstrip("/")
|
|
107
107
|
self.gateway_url = get_gateway_url()
|
plexus/config.py
CHANGED
|
@@ -50,15 +50,12 @@ CONFIG_FILE = CONFIG_DIR / "config.json"
|
|
|
50
50
|
|
|
51
51
|
PLEXUS_ENDPOINT = "https://app.plexus.company"
|
|
52
52
|
PLEXUS_GATEWAY_URL = "https://plexus-gateway.fly.dev"
|
|
53
|
+
PLEXUS_GATEWAY_WS_URL = "wss://plexus-gateway.fly.dev"
|
|
53
54
|
|
|
54
55
|
DEFAULT_CONFIG = {
|
|
55
56
|
"api_key": None,
|
|
56
57
|
"source_id": None,
|
|
57
|
-
"org_id": None,
|
|
58
|
-
"source_name": None,
|
|
59
|
-
"endpoint": None,
|
|
60
58
|
"persistent_buffer": True,
|
|
61
|
-
"sensors": None,
|
|
62
59
|
}
|
|
63
60
|
|
|
64
61
|
def get_config_path() -> Path:
|
|
@@ -117,7 +114,7 @@ def get_endpoint() -> str:
|
|
|
117
114
|
|
|
118
115
|
|
|
119
116
|
def get_gateway_url() -> str:
|
|
120
|
-
"""Get the ingest gateway base URL (POST /ingest
|
|
117
|
+
"""Get the ingest gateway base URL (POST /ingest)."""
|
|
121
118
|
env_gateway = os.environ.get("PLEXUS_GATEWAY_URL")
|
|
122
119
|
if env_gateway:
|
|
123
120
|
return env_gateway.rstrip("/")
|
|
@@ -125,6 +122,15 @@ def get_gateway_url() -> str:
|
|
|
125
122
|
return (config.get("gateway_url") or PLEXUS_GATEWAY_URL).rstrip("/")
|
|
126
123
|
|
|
127
124
|
|
|
125
|
+
def get_gateway_ws_url() -> str:
|
|
126
|
+
"""Get the gateway WebSocket base URL (/ws/device)."""
|
|
127
|
+
env_ws = os.environ.get("PLEXUS_GATEWAY_WS_URL")
|
|
128
|
+
if env_ws:
|
|
129
|
+
return env_ws.rstrip("/")
|
|
130
|
+
config = load_config()
|
|
131
|
+
return (config.get("gateway_ws_url") or PLEXUS_GATEWAY_WS_URL).rstrip("/")
|
|
132
|
+
|
|
133
|
+
|
|
128
134
|
def get_source_id() -> Optional[str]:
|
|
129
135
|
"""Get the source ID, generating one if not set."""
|
|
130
136
|
config = load_config()
|
|
@@ -139,30 +145,6 @@ def get_source_id() -> Optional[str]:
|
|
|
139
145
|
return source_id
|
|
140
146
|
|
|
141
147
|
|
|
142
|
-
def get_org_id() -> Optional[str]:
|
|
143
|
-
"""Get the organization ID from config or environment variable."""
|
|
144
|
-
# Environment variable takes precedence
|
|
145
|
-
env_org = os.environ.get("PLEXUS_ORG_ID")
|
|
146
|
-
if env_org:
|
|
147
|
-
return env_org
|
|
148
|
-
|
|
149
|
-
config = load_config()
|
|
150
|
-
return config.get("org_id")
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
def is_logged_in() -> bool:
|
|
154
|
-
"""Check if device is authenticated (has API key)."""
|
|
155
|
-
return get_api_key() is not None
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
def require_login() -> None:
|
|
159
|
-
"""Raise an error if not logged in."""
|
|
160
|
-
if not is_logged_in():
|
|
161
|
-
raise RuntimeError(
|
|
162
|
-
"Not logged in. Run 'plexus start' to connect your account."
|
|
163
|
-
)
|
|
164
|
-
|
|
165
|
-
|
|
166
148
|
def get_persistent_buffer() -> bool:
|
|
167
149
|
"""Get persistent buffer setting. Default True (store-and-forward enabled)."""
|
|
168
150
|
config = load_config()
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: plexus-python
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Thin Python SDK for Plexus — send telemetry in one line
|
|
5
|
+
Project-URL: Homepage, https://plexus.dev
|
|
6
|
+
Project-URL: Documentation, https://docs.plexus.dev
|
|
7
|
+
Project-URL: Repository, https://github.com/plexus-oss/plexus-python
|
|
8
|
+
Project-URL: Issues, https://github.com/plexus-oss/plexus-python/issues
|
|
9
|
+
Author-email: Plexus <hello@plexus.dev>
|
|
10
|
+
License-Expression: Apache-2.0
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: fleet,hardware,iot,monitoring,observability,telemetry
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering
|
|
24
|
+
Classifier: Topic :: System :: Hardware
|
|
25
|
+
Requires-Python: >=3.8
|
|
26
|
+
Requires-Dist: requests>=2.28.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest-cov; extra == 'dev'
|
|
30
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# plexus-python
|
|
34
|
+
|
|
35
|
+
**Thin Python SDK for [Plexus](https://plexus.company).** Send telemetry to the Plexus gateway in one line. Storage, dashboards, alerts, and fleet management live in the platform — this package just ships your data.
|
|
36
|
+
|
|
37
|
+
[](https://pypi.org/project/plexus-python/)
|
|
38
|
+
[](LICENSE)
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install plexus-python
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from plexus import Plexus
|
|
48
|
+
|
|
49
|
+
px = Plexus(api_key="plx_xxx", source_id="device-001")
|
|
50
|
+
px.send("temperature", 72.5)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Get an API key at [app.plexus.company](https://app.plexus.company) → Devices → Add Device.
|
|
54
|
+
|
|
55
|
+
## Usage
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from plexus import Plexus
|
|
59
|
+
|
|
60
|
+
px = Plexus(source_id="rig-01") # reads PLEXUS_API_KEY from env
|
|
61
|
+
|
|
62
|
+
# Numbers
|
|
63
|
+
px.send("engine.rpm", 3450)
|
|
64
|
+
px.send("coolant.temperature", 82.3, tags={"unit": "C"})
|
|
65
|
+
|
|
66
|
+
# Strings, bools, objects, arrays — all JSON-serializable
|
|
67
|
+
px.send("vehicle.state", "RUNNING")
|
|
68
|
+
px.send("motor.enabled", True)
|
|
69
|
+
px.send("position", {"x": 1.5, "y": 2.3, "z": 0.8})
|
|
70
|
+
|
|
71
|
+
# Batch
|
|
72
|
+
px.send_batch([
|
|
73
|
+
("temperature", 72.5),
|
|
74
|
+
("pressure", 1013.25),
|
|
75
|
+
])
|
|
76
|
+
|
|
77
|
+
# Named run for grouping related data
|
|
78
|
+
with px.run("thermal-cycle-001"):
|
|
79
|
+
while running:
|
|
80
|
+
px.send("temperature", read_temp())
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Bring Your Own Protocol
|
|
84
|
+
|
|
85
|
+
This package ships no adapters, auto-detection, or daemons — just the client. Use whatever library you'd use anyway and pipe values into `px.send()`.
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
# MAVLink (pymavlink)
|
|
89
|
+
for msg in conn:
|
|
90
|
+
if msg.get_type() == "ATTITUDE":
|
|
91
|
+
px.send("attitude.roll", msg.roll)
|
|
92
|
+
|
|
93
|
+
# CAN (python-can)
|
|
94
|
+
for msg in bus:
|
|
95
|
+
px.send(f"can.0x{msg.arbitration_id:x}", int.from_bytes(msg.data, "big"))
|
|
96
|
+
|
|
97
|
+
# MQTT (paho-mqtt)
|
|
98
|
+
def on_message(_c, _u, msg):
|
|
99
|
+
px.send(msg.topic.replace("/", "."), float(msg.payload))
|
|
100
|
+
|
|
101
|
+
# I2C sensor (Adafruit CircuitPython)
|
|
102
|
+
px.send("temperature", bme.temperature)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
See [`examples/`](examples/) for runnable versions of each.
|
|
106
|
+
|
|
107
|
+
## Reliability
|
|
108
|
+
|
|
109
|
+
Every send buffers locally before hitting the network, retries with exponential backoff, and keeps your data safe across outages. Enable SQLite persistence to survive restarts and power loss:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
px = Plexus(persistent_buffer=True)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Point counts and flush:
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
px.buffer_size()
|
|
119
|
+
px.flush_buffer()
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Environment Variables
|
|
123
|
+
|
|
124
|
+
| Variable | Description | Default |
|
|
125
|
+
| ----------------------- | ---------------------------- | -------------------------------- |
|
|
126
|
+
| `PLEXUS_API_KEY` | API key (required) | none |
|
|
127
|
+
| `PLEXUS_GATEWAY_URL` | HTTP ingest URL | `https://plexus-gateway.fly.dev` |
|
|
128
|
+
| `PLEXUS_GATEWAY_WS_URL` | WebSocket URL (unused in SDK, for compatibility) | `wss://plexus-gateway.fly.dev` |
|
|
129
|
+
|
|
130
|
+
## Architecture
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
Your code ── px.send() ── HTTP POST /ingest ──> plexus-gateway ──> ClickHouse + Dashboard
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
One thin path. No agent, no daemon, no adapters. If you want the full HardwareOps platform — dashboards, alerts, RCA, fleet views — that's the web UI at app.plexus.company. This package gets your data there.
|
|
137
|
+
|
|
138
|
+
## License
|
|
139
|
+
|
|
140
|
+
Apache 2.0
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
plexus/__init__.py,sha256=Kal4qSrpQ6S8-AE7F9UqFkJMvbhTD82kzkO59O-ruEw,282
|
|
2
|
+
plexus/buffer.py,sha256=3ykybqLs7yMXxQWFajAT8nGe3cs_lW8_6Xvn0vQ69dE,9262
|
|
3
|
+
plexus/client.py,sha256=X6gyFYS-CVwcqJt_VzwHuNtsuJhJJzSxH41T7UBv9dE,16212
|
|
4
|
+
plexus/config.py,sha256=RNym2Fon6JOCVi1rXPSRWjPFAdT8DSmokY5JPEljQOc,4450
|
|
5
|
+
plexus_python-0.2.0.dist-info/METADATA,sha256=51nhbClqTy2w07qn--JyzD8wAOnM7OQQhydvYUgswRI,4528
|
|
6
|
+
plexus_python-0.2.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
7
|
+
plexus_python-0.2.0.dist-info/licenses/LICENSE,sha256=nm3qP1F-JAGcfLpRVtIX24L20LMnRpxmZ2oKZzFpLVo,10755
|
|
8
|
+
plexus_python-0.2.0.dist-info/RECORD,,
|
plexus/__main__.py
DELETED
plexus/adapters/__init__.py
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Protocol Adapters - Extensible protocol support for Plexus
|
|
3
|
-
|
|
4
|
-
This module provides a plugin system for protocol adapters, enabling
|
|
5
|
-
Plexus to ingest data from any protocol without modifying core code.
|
|
6
|
-
|
|
7
|
-
Built-in adapters:
|
|
8
|
-
- MQTTAdapter: Bridge MQTT brokers to Plexus
|
|
9
|
-
- CANAdapter: CAN bus with DBC signal decoding
|
|
10
|
-
- MAVLinkAdapter: MAVLink for drones and autonomous vehicles
|
|
11
|
-
- OPCUAAdapter: OPC-UA client for industrial automation servers
|
|
12
|
-
- SerialAdapter: Serial port (USB/UART/RS-232/RS-485) reader
|
|
13
|
-
|
|
14
|
-
Usage:
|
|
15
|
-
from plexus.adapters import MQTTAdapter, CANAdapter, MAVLinkAdapter, AdapterRegistry
|
|
16
|
-
|
|
17
|
-
# Use built-in adapter
|
|
18
|
-
adapter = MQTTAdapter(broker="localhost", topic="sensors/#")
|
|
19
|
-
adapter.connect()
|
|
20
|
-
adapter.run(on_data=my_callback)
|
|
21
|
-
|
|
22
|
-
# CAN bus adapter
|
|
23
|
-
adapter = CANAdapter(interface="socketcan", channel="can0", dbc_path="vehicle.dbc")
|
|
24
|
-
with adapter:
|
|
25
|
-
for metric in adapter.poll():
|
|
26
|
-
print(f"{metric.name}: {metric.value}")
|
|
27
|
-
|
|
28
|
-
# MAVLink adapter
|
|
29
|
-
adapter = MAVLinkAdapter(connection_string="udpin:0.0.0.0:14550")
|
|
30
|
-
with adapter:
|
|
31
|
-
for metric in adapter.poll():
|
|
32
|
-
print(f"{metric.name}: {metric.value}")
|
|
33
|
-
|
|
34
|
-
# Create custom adapter
|
|
35
|
-
from plexus.adapters import ProtocolAdapter, Metric
|
|
36
|
-
|
|
37
|
-
class MyProtocolAdapter(ProtocolAdapter):
|
|
38
|
-
def connect(self) -> bool:
|
|
39
|
-
# Connect to your protocol
|
|
40
|
-
return True
|
|
41
|
-
|
|
42
|
-
def poll(self) -> "List[Metric]":
|
|
43
|
-
# Read data and return metrics
|
|
44
|
-
return [Metric("sensor.temp", 72.5)]
|
|
45
|
-
|
|
46
|
-
# Register custom adapter
|
|
47
|
-
AdapterRegistry.register("my-protocol", MyProtocolAdapter)
|
|
48
|
-
"""
|
|
49
|
-
|
|
50
|
-
from plexus.adapters.base import (
|
|
51
|
-
ProtocolAdapter,
|
|
52
|
-
Metric,
|
|
53
|
-
AdapterConfig,
|
|
54
|
-
AdapterState,
|
|
55
|
-
AdapterError,
|
|
56
|
-
)
|
|
57
|
-
from plexus.adapters.registry import AdapterRegistry
|
|
58
|
-
from plexus.adapters.mqtt import MQTTAdapter
|
|
59
|
-
|
|
60
|
-
# Import CANAdapter (requires optional [can] extra)
|
|
61
|
-
try:
|
|
62
|
-
from plexus.adapters.can import CANAdapter
|
|
63
|
-
_HAS_CAN = True
|
|
64
|
-
except ImportError:
|
|
65
|
-
CANAdapter = None # type: ignore
|
|
66
|
-
_HAS_CAN = False
|
|
67
|
-
|
|
68
|
-
# Import ModbusAdapter (requires optional [modbus] extra)
|
|
69
|
-
try:
|
|
70
|
-
from plexus.adapters.modbus import ModbusAdapter
|
|
71
|
-
_HAS_MODBUS = True
|
|
72
|
-
except ImportError:
|
|
73
|
-
ModbusAdapter = None # type: ignore
|
|
74
|
-
_HAS_MODBUS = False
|
|
75
|
-
|
|
76
|
-
# Import MAVLinkAdapter (requires optional [mavlink] extra)
|
|
77
|
-
try:
|
|
78
|
-
from plexus.adapters.mavlink import MAVLinkAdapter
|
|
79
|
-
_HAS_MAVLINK = True
|
|
80
|
-
except ImportError:
|
|
81
|
-
MAVLinkAdapter = None # type: ignore
|
|
82
|
-
_HAS_MAVLINK = False
|
|
83
|
-
|
|
84
|
-
# Import OPCUAAdapter (requires optional [opcua] extra)
|
|
85
|
-
try:
|
|
86
|
-
from plexus.adapters.opcua import OPCUAAdapter
|
|
87
|
-
_HAS_OPCUA = True
|
|
88
|
-
except ImportError:
|
|
89
|
-
OPCUAAdapter = None # type: ignore
|
|
90
|
-
_HAS_OPCUA = False
|
|
91
|
-
|
|
92
|
-
# Import SerialAdapter (requires optional [serial] extra)
|
|
93
|
-
try:
|
|
94
|
-
from plexus.adapters.serial_adapter import SerialAdapter
|
|
95
|
-
_HAS_SERIAL = True
|
|
96
|
-
except ImportError:
|
|
97
|
-
SerialAdapter = None # type: ignore
|
|
98
|
-
_HAS_SERIAL = False
|
|
99
|
-
|
|
100
|
-
# Import BLERelayAdapter (requires optional [ble] extra)
|
|
101
|
-
try:
|
|
102
|
-
from plexus.adapters.ble import BLERelayAdapter
|
|
103
|
-
_HAS_BLE = True
|
|
104
|
-
except ImportError:
|
|
105
|
-
BLERelayAdapter = None # type: ignore
|
|
106
|
-
_HAS_BLE = False
|
|
107
|
-
|
|
108
|
-
__all__ = [
|
|
109
|
-
"ProtocolAdapter",
|
|
110
|
-
"Metric",
|
|
111
|
-
"AdapterConfig",
|
|
112
|
-
"AdapterState",
|
|
113
|
-
"AdapterError",
|
|
114
|
-
"AdapterRegistry",
|
|
115
|
-
"MQTTAdapter",
|
|
116
|
-
"CANAdapter",
|
|
117
|
-
"ModbusAdapter",
|
|
118
|
-
"MAVLinkAdapter",
|
|
119
|
-
"OPCUAAdapter",
|
|
120
|
-
"SerialAdapter",
|
|
121
|
-
"BLERelayAdapter",
|
|
122
|
-
]
|