plexus-python 0.1.0__tar.gz
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_python-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +68 -0
- plexus_python-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +57 -0
- plexus_python-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +17 -0
- plexus_python-0.1.0/.github/workflows/ci.yml +83 -0
- plexus_python-0.1.0/.github/workflows/publish.yml +73 -0
- plexus_python-0.1.0/.gitignore +54 -0
- plexus_python-0.1.0/AGENTS.md +79 -0
- plexus_python-0.1.0/API.md +508 -0
- plexus_python-0.1.0/CHANGELOG.md +9 -0
- plexus_python-0.1.0/CODE_OF_CONDUCT.md +30 -0
- plexus_python-0.1.0/CONTRIBUTING.md +53 -0
- plexus_python-0.1.0/LICENSE +190 -0
- plexus_python-0.1.0/PKG-INFO +470 -0
- plexus_python-0.1.0/README.md +388 -0
- plexus_python-0.1.0/SECURITY.md +31 -0
- plexus_python-0.1.0/examples/can_basic.py +173 -0
- plexus_python-0.1.0/examples/demo_field_unit.py +254 -0
- plexus_python-0.1.0/examples/demo_ground_station.py +135 -0
- plexus_python-0.1.0/examples/gateway_ble_relay.py +97 -0
- plexus_python-0.1.0/examples/mavlink_basic.py +157 -0
- plexus_python-0.1.0/plexus/__init__.py +31 -0
- plexus_python-0.1.0/plexus/__main__.py +4 -0
- plexus_python-0.1.0/plexus/adapters/__init__.py +122 -0
- plexus_python-0.1.0/plexus/adapters/base.py +409 -0
- plexus_python-0.1.0/plexus/adapters/ble.py +257 -0
- plexus_python-0.1.0/plexus/adapters/can.py +439 -0
- plexus_python-0.1.0/plexus/adapters/can_detect.py +174 -0
- plexus_python-0.1.0/plexus/adapters/mavlink.py +642 -0
- plexus_python-0.1.0/plexus/adapters/mavlink_detect.py +192 -0
- plexus_python-0.1.0/plexus/adapters/modbus.py +622 -0
- plexus_python-0.1.0/plexus/adapters/mqtt.py +350 -0
- plexus_python-0.1.0/plexus/adapters/opcua.py +607 -0
- plexus_python-0.1.0/plexus/adapters/registry.py +206 -0
- plexus_python-0.1.0/plexus/adapters/serial_adapter.py +547 -0
- plexus_python-0.1.0/plexus/buffer.py +257 -0
- plexus_python-0.1.0/plexus/cameras/__init__.py +57 -0
- plexus_python-0.1.0/plexus/cameras/auto.py +239 -0
- plexus_python-0.1.0/plexus/cameras/base.py +189 -0
- plexus_python-0.1.0/plexus/cameras/picamera.py +171 -0
- plexus_python-0.1.0/plexus/cameras/usb.py +143 -0
- plexus_python-0.1.0/plexus/cli.py +783 -0
- plexus_python-0.1.0/plexus/client.py +465 -0
- plexus_python-0.1.0/plexus/config.py +169 -0
- plexus_python-0.1.0/plexus/connector.py +666 -0
- plexus_python-0.1.0/plexus/deps.py +246 -0
- plexus_python-0.1.0/plexus/detect.py +1238 -0
- plexus_python-0.1.0/plexus/importers/__init__.py +25 -0
- plexus_python-0.1.0/plexus/importers/rosbag.py +778 -0
- plexus_python-0.1.0/plexus/sensors/__init__.py +118 -0
- plexus_python-0.1.0/plexus/sensors/ads1115.py +164 -0
- plexus_python-0.1.0/plexus/sensors/adxl345.py +179 -0
- plexus_python-0.1.0/plexus/sensors/auto.py +290 -0
- plexus_python-0.1.0/plexus/sensors/base.py +412 -0
- plexus_python-0.1.0/plexus/sensors/bh1750.py +102 -0
- plexus_python-0.1.0/plexus/sensors/bme280.py +241 -0
- plexus_python-0.1.0/plexus/sensors/gps.py +317 -0
- plexus_python-0.1.0/plexus/sensors/ina219.py +149 -0
- plexus_python-0.1.0/plexus/sensors/magnetometer.py +239 -0
- plexus_python-0.1.0/plexus/sensors/mpu6050.py +162 -0
- plexus_python-0.1.0/plexus/sensors/sht3x.py +139 -0
- plexus_python-0.1.0/plexus/sensors/spi_scan.py +164 -0
- plexus_python-0.1.0/plexus/sensors/system.py +261 -0
- plexus_python-0.1.0/plexus/sensors/vl53l0x.py +109 -0
- plexus_python-0.1.0/plexus/streaming.py +743 -0
- plexus_python-0.1.0/plexus/tui.py +642 -0
- plexus_python-0.1.0/pyproject.toml +114 -0
- plexus_python-0.1.0/scripts/plexus.service +27 -0
- plexus_python-0.1.0/scripts/scan_buses.py +16 -0
- plexus_python-0.1.0/scripts/setup.sh +333 -0
- plexus_python-0.1.0/tests/test_basic.py +43 -0
- plexus_python-0.1.0/tests/test_buffer.py +145 -0
- plexus_python-0.1.0/tests/test_can_adapter.py +332 -0
- plexus_python-0.1.0/tests/test_config.py +47 -0
- plexus_python-0.1.0/tests/test_connector.py +30 -0
- plexus_python-0.1.0/tests/test_gps.py +147 -0
- plexus_python-0.1.0/tests/test_mavlink_adapter.py +711 -0
- plexus_python-0.1.0/tests/test_modbus_adapter.py +412 -0
- plexus_python-0.1.0/tests/test_mqtt_adapter.py +288 -0
- plexus_python-0.1.0/tests/test_retry.py +353 -0
- plexus_python-0.1.0/tests/test_sensor_hub.py +208 -0
- plexus_python-0.1.0/tests/test_serial_adapter.py +305 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
name: Bug Report
|
|
2
|
+
description: Report a bug in plexus-python
|
|
3
|
+
title: "[Bug]: "
|
|
4
|
+
labels: ["bug"]
|
|
5
|
+
body:
|
|
6
|
+
- type: input
|
|
7
|
+
id: agent-version
|
|
8
|
+
attributes:
|
|
9
|
+
label: Agent Version
|
|
10
|
+
description: Output of `plexus --version` or version in pyproject.toml
|
|
11
|
+
placeholder: "0.9.6"
|
|
12
|
+
validations:
|
|
13
|
+
required: true
|
|
14
|
+
|
|
15
|
+
- type: input
|
|
16
|
+
id: python-version
|
|
17
|
+
attributes:
|
|
18
|
+
label: Python Version
|
|
19
|
+
description: Output of `python3 --version`
|
|
20
|
+
placeholder: "3.11.0"
|
|
21
|
+
validations:
|
|
22
|
+
required: true
|
|
23
|
+
|
|
24
|
+
- type: dropdown
|
|
25
|
+
id: platform
|
|
26
|
+
attributes:
|
|
27
|
+
label: Platform
|
|
28
|
+
description: What device/OS are you running on?
|
|
29
|
+
options:
|
|
30
|
+
- Raspberry Pi (Raspbian/Debian)
|
|
31
|
+
- Ubuntu/Debian (x86)
|
|
32
|
+
- macOS
|
|
33
|
+
- Windows
|
|
34
|
+
- Other Linux
|
|
35
|
+
- Other
|
|
36
|
+
validations:
|
|
37
|
+
required: true
|
|
38
|
+
|
|
39
|
+
- type: textarea
|
|
40
|
+
id: description
|
|
41
|
+
attributes:
|
|
42
|
+
label: Description
|
|
43
|
+
description: Clear description of the bug
|
|
44
|
+
validations:
|
|
45
|
+
required: true
|
|
46
|
+
|
|
47
|
+
- type: textarea
|
|
48
|
+
id: repro
|
|
49
|
+
attributes:
|
|
50
|
+
label: Reproduction Steps
|
|
51
|
+
description: Minimal code or CLI commands to reproduce the issue
|
|
52
|
+
render: python
|
|
53
|
+
validations:
|
|
54
|
+
required: true
|
|
55
|
+
|
|
56
|
+
- type: textarea
|
|
57
|
+
id: extras
|
|
58
|
+
attributes:
|
|
59
|
+
label: Installed Extras
|
|
60
|
+
description: Which optional extras are installed? (e.g., sensors, can, mavlink, camera)
|
|
61
|
+
placeholder: "pip install plexus-python[sensors,can]"
|
|
62
|
+
|
|
63
|
+
- type: textarea
|
|
64
|
+
id: logs
|
|
65
|
+
attributes:
|
|
66
|
+
label: Logs / Traceback
|
|
67
|
+
description: Any relevant error output
|
|
68
|
+
render: text
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
name: Feature Request
|
|
2
|
+
description: Suggest a new feature or improvement
|
|
3
|
+
title: "[Feature]: "
|
|
4
|
+
labels: ["enhancement"]
|
|
5
|
+
body:
|
|
6
|
+
- type: textarea
|
|
7
|
+
id: problem
|
|
8
|
+
attributes:
|
|
9
|
+
label: Problem / Use Case
|
|
10
|
+
description: What problem does this feature solve? What are you trying to do?
|
|
11
|
+
validations:
|
|
12
|
+
required: true
|
|
13
|
+
|
|
14
|
+
- type: textarea
|
|
15
|
+
id: solution
|
|
16
|
+
attributes:
|
|
17
|
+
label: Proposed Solution
|
|
18
|
+
description: How should this work? Include example code if applicable.
|
|
19
|
+
render: python
|
|
20
|
+
|
|
21
|
+
- type: checkboxes
|
|
22
|
+
id: adapters
|
|
23
|
+
attributes:
|
|
24
|
+
label: Related Adapters
|
|
25
|
+
description: Which adapters or protocols does this relate to?
|
|
26
|
+
options:
|
|
27
|
+
- label: Core SDK / Client
|
|
28
|
+
- label: Sensors (I2C/smbus)
|
|
29
|
+
- label: CAN bus
|
|
30
|
+
- label: MAVLink
|
|
31
|
+
- label: MQTT
|
|
32
|
+
- label: Serial
|
|
33
|
+
- label: BLE
|
|
34
|
+
- label: Camera / Video
|
|
35
|
+
- label: OPC-UA
|
|
36
|
+
- label: Modbus
|
|
37
|
+
- label: ROS bags
|
|
38
|
+
- label: New adapter
|
|
39
|
+
|
|
40
|
+
- type: dropdown
|
|
41
|
+
id: priority
|
|
42
|
+
attributes:
|
|
43
|
+
label: Priority
|
|
44
|
+
description: How important is this to your project?
|
|
45
|
+
options:
|
|
46
|
+
- Nice to have
|
|
47
|
+
- Important — working around it today
|
|
48
|
+
- Critical — blocking my project
|
|
49
|
+
validations:
|
|
50
|
+
required: true
|
|
51
|
+
|
|
52
|
+
- type: checkboxes
|
|
53
|
+
id: contribution
|
|
54
|
+
attributes:
|
|
55
|
+
label: Contribution
|
|
56
|
+
options:
|
|
57
|
+
- label: I'm willing to submit a PR for this feature
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
## What does this PR do?
|
|
2
|
+
|
|
3
|
+
<!-- Brief description of the change -->
|
|
4
|
+
|
|
5
|
+
## Why?
|
|
6
|
+
|
|
7
|
+
<!-- What problem does this solve? Link to issue if applicable. -->
|
|
8
|
+
|
|
9
|
+
Closes #
|
|
10
|
+
|
|
11
|
+
## Checklist
|
|
12
|
+
|
|
13
|
+
- [ ] Tests pass (`pytest`)
|
|
14
|
+
- [ ] Linting passes (`ruff check .`)
|
|
15
|
+
- [ ] New code has type hints
|
|
16
|
+
- [ ] Updated CHANGELOG.md (if user-facing change)
|
|
17
|
+
- [ ] Tested on target hardware (if applicable)
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
name: Lint
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Set up Python
|
|
17
|
+
uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: '3.12'
|
|
20
|
+
|
|
21
|
+
- name: Install dependencies
|
|
22
|
+
run: |
|
|
23
|
+
python -m pip install --upgrade pip
|
|
24
|
+
pip install -e ".[dev]"
|
|
25
|
+
|
|
26
|
+
- name: Lint with ruff
|
|
27
|
+
run: ruff check .
|
|
28
|
+
|
|
29
|
+
test:
|
|
30
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
strategy:
|
|
33
|
+
matrix:
|
|
34
|
+
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
|
|
35
|
+
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
|
|
39
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
40
|
+
uses: actions/setup-python@v5
|
|
41
|
+
with:
|
|
42
|
+
python-version: ${{ matrix.python-version }}
|
|
43
|
+
|
|
44
|
+
- name: Install dependencies
|
|
45
|
+
run: |
|
|
46
|
+
python -m pip install --upgrade pip
|
|
47
|
+
pip install -e ".[dev]"
|
|
48
|
+
|
|
49
|
+
- name: Run tests
|
|
50
|
+
run: pytest -v
|
|
51
|
+
|
|
52
|
+
version-check:
|
|
53
|
+
name: Version sync
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
steps:
|
|
56
|
+
- uses: actions/checkout@v4
|
|
57
|
+
|
|
58
|
+
- name: Set up Python
|
|
59
|
+
uses: actions/setup-python@v5
|
|
60
|
+
with:
|
|
61
|
+
python-version: '3.12'
|
|
62
|
+
|
|
63
|
+
- name: Check version consistency
|
|
64
|
+
run: |
|
|
65
|
+
PYPROJECT_VERSION=$(python -c "
|
|
66
|
+
import re
|
|
67
|
+
with open('pyproject.toml') as f:
|
|
68
|
+
match = re.search(r'^version\s*=\s*\"(.+?)\"', f.read(), re.MULTILINE)
|
|
69
|
+
print(match.group(1))
|
|
70
|
+
")
|
|
71
|
+
INIT_VERSION=$(python -c "
|
|
72
|
+
import re
|
|
73
|
+
with open('plexus/__init__.py') as f:
|
|
74
|
+
match = re.search(r'^__version__\s*=\s*\"(.+?)\"', f.read(), re.MULTILINE)
|
|
75
|
+
print(match.group(1))
|
|
76
|
+
")
|
|
77
|
+
echo "pyproject.toml version: $PYPROJECT_VERSION"
|
|
78
|
+
echo "__init__.py version: $INIT_VERSION"
|
|
79
|
+
if [ "$PYPROJECT_VERSION" != "$INIT_VERSION" ]; then
|
|
80
|
+
echo "::error::Version mismatch! pyproject.toml=$PYPROJECT_VERSION, __init__.py=$INIT_VERSION"
|
|
81
|
+
exit 1
|
|
82
|
+
fi
|
|
83
|
+
echo "Versions match: $PYPROJECT_VERSION"
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
validate:
|
|
9
|
+
name: Validate release
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
|
|
14
|
+
- name: Set up Python
|
|
15
|
+
uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: '3.12'
|
|
18
|
+
|
|
19
|
+
- name: Install dependencies
|
|
20
|
+
run: |
|
|
21
|
+
python -m pip install --upgrade pip
|
|
22
|
+
pip install -e ".[dev]"
|
|
23
|
+
|
|
24
|
+
- name: Check tag matches code version
|
|
25
|
+
run: |
|
|
26
|
+
TAG="${GITHUB_REF#refs/tags/v}"
|
|
27
|
+
CODE_VERSION=$(python -c "
|
|
28
|
+
import re
|
|
29
|
+
with open('pyproject.toml') as f:
|
|
30
|
+
match = re.search(r'^version\s*=\s*\"(.+?)\"', f.read(), re.MULTILINE)
|
|
31
|
+
print(match.group(1))
|
|
32
|
+
")
|
|
33
|
+
echo "Git tag version: $TAG"
|
|
34
|
+
echo "Code version: $CODE_VERSION"
|
|
35
|
+
if [ "$TAG" != "$CODE_VERSION" ]; then
|
|
36
|
+
echo "::error::Tag v$TAG does not match code version $CODE_VERSION"
|
|
37
|
+
exit 1
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
- name: Lint
|
|
41
|
+
run: ruff check .
|
|
42
|
+
|
|
43
|
+
- name: Run tests
|
|
44
|
+
run: pytest -v
|
|
45
|
+
|
|
46
|
+
publish:
|
|
47
|
+
name: Publish to PyPI
|
|
48
|
+
needs: validate
|
|
49
|
+
runs-on: ubuntu-latest
|
|
50
|
+
permissions:
|
|
51
|
+
id-token: write
|
|
52
|
+
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@v4
|
|
55
|
+
|
|
56
|
+
- name: Set up Python
|
|
57
|
+
uses: actions/setup-python@v5
|
|
58
|
+
with:
|
|
59
|
+
python-version: '3.12'
|
|
60
|
+
|
|
61
|
+
- name: Install build tools
|
|
62
|
+
run: |
|
|
63
|
+
python -m pip install --upgrade pip
|
|
64
|
+
pip install build twine
|
|
65
|
+
|
|
66
|
+
- name: Build package
|
|
67
|
+
run: python -m build
|
|
68
|
+
|
|
69
|
+
- name: Check package
|
|
70
|
+
run: twine check dist/*
|
|
71
|
+
|
|
72
|
+
- name: Publish to PyPI
|
|
73
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
.ruff_cache/
|
|
7
|
+
|
|
8
|
+
# Distribution / packaging
|
|
9
|
+
.Python
|
|
10
|
+
build/
|
|
11
|
+
develop-eggs/
|
|
12
|
+
dist/
|
|
13
|
+
downloads/
|
|
14
|
+
eggs/
|
|
15
|
+
.eggs/
|
|
16
|
+
lib/
|
|
17
|
+
lib64/
|
|
18
|
+
parts/
|
|
19
|
+
sdist/
|
|
20
|
+
var/
|
|
21
|
+
wheels/
|
|
22
|
+
*.egg-info/
|
|
23
|
+
.installed.cfg
|
|
24
|
+
*.egg
|
|
25
|
+
|
|
26
|
+
# Virtual environments
|
|
27
|
+
venv/
|
|
28
|
+
ENV/
|
|
29
|
+
env/
|
|
30
|
+
.venv/
|
|
31
|
+
|
|
32
|
+
# IDE
|
|
33
|
+
.idea/
|
|
34
|
+
.vscode/
|
|
35
|
+
*.swp
|
|
36
|
+
*.swo
|
|
37
|
+
*~
|
|
38
|
+
|
|
39
|
+
# Testing
|
|
40
|
+
.pytest_cache/
|
|
41
|
+
.coverage
|
|
42
|
+
htmlcov/
|
|
43
|
+
.tox/
|
|
44
|
+
.nox/
|
|
45
|
+
|
|
46
|
+
# Type checking
|
|
47
|
+
.mypy_cache/
|
|
48
|
+
|
|
49
|
+
# Jupyter
|
|
50
|
+
.ipynb_checkpoints/
|
|
51
|
+
|
|
52
|
+
# Local config
|
|
53
|
+
.env
|
|
54
|
+
.env.local
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# AGENTS.md — Plexus Agent
|
|
2
|
+
|
|
3
|
+
Machine-readable interface for AI assistants and automation scripts.
|
|
4
|
+
|
|
5
|
+
## Environment Variables
|
|
6
|
+
|
|
7
|
+
| Variable | Description | Example |
|
|
8
|
+
| ----------------- | -------------------------------------------------- | ----------------------------- |
|
|
9
|
+
| `PLEXUS_API_KEY` | API key for authentication | `plx_xxxxx` |
|
|
10
|
+
| `PLEXUS_ENDPOINT` | Server URL (default: `https://app.plexus.company`) | `https://custom.endpoint.com` |
|
|
11
|
+
| `PLEXUS_ORG_ID` | Organization ID | `org_xxxxx` |
|
|
12
|
+
| `PLEXUS_WS_URL` | Gateway WebSocket URL (overrides API discovery) | `ws://localhost:8080` |
|
|
13
|
+
|
|
14
|
+
## CLI Commands
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
plexus start # Interactive setup + stream
|
|
18
|
+
plexus start --key plx_xxxxx # Non-interactive auth
|
|
19
|
+
plexus start --device-id my-device # Set device identifier
|
|
20
|
+
plexus reset # Clear config and start over
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Headless mode is auto-detected when output is piped or in a non-TTY environment. Set `PLEXUS_API_KEY` to skip interactive auth in headless contexts.
|
|
24
|
+
|
|
25
|
+
## Exit Codes
|
|
26
|
+
|
|
27
|
+
| Code | Meaning |
|
|
28
|
+
| ----- | ------------------------------------- |
|
|
29
|
+
| `0` | Clean shutdown |
|
|
30
|
+
| `1` | Configuration or authentication error |
|
|
31
|
+
| `130` | Interrupted (SIGINT / Ctrl+C) |
|
|
32
|
+
|
|
33
|
+
## Python SDK
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from plexus import Plexus
|
|
37
|
+
|
|
38
|
+
px = Plexus(api_key="plx_xxxxx", source_id="device-001")
|
|
39
|
+
px.send("temperature", 72.5)
|
|
40
|
+
px.send("pressure", 1013.25, tags={"unit": "hPa"})
|
|
41
|
+
|
|
42
|
+
# Batch
|
|
43
|
+
px.send_batch([
|
|
44
|
+
("temperature", 72.5),
|
|
45
|
+
("pressure", 1013.25),
|
|
46
|
+
])
|
|
47
|
+
|
|
48
|
+
# Persistent buffering for reliability
|
|
49
|
+
px = Plexus(api_key="plx_xxxxx", persistent_buffer=True)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Project Structure
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
plexus/
|
|
56
|
+
├── cli.py # CLI entry point (click commands)
|
|
57
|
+
├── tui.py # Live terminal dashboard (Rich)
|
|
58
|
+
├── client.py # Plexus HTTP client
|
|
59
|
+
├── connector.py # WebSocket connector
|
|
60
|
+
├── config.py # Config file management (~/.plexus/)
|
|
61
|
+
├── detect.py # Hardware auto-detection
|
|
62
|
+
├── deps.py # Dependency management
|
|
63
|
+
├── sensors/ # Sensor drivers (I2C, system)
|
|
64
|
+
│ ├── base.py # BaseSensor, SensorHub
|
|
65
|
+
│ └── drivers/ # Individual sensor implementations
|
|
66
|
+
├── adapters/ # Protocol adapters
|
|
67
|
+
│ ├── can.py # CAN bus
|
|
68
|
+
│ ├── mavlink.py # MAVLink (drones)
|
|
69
|
+
│ ├── mqtt.py # MQTT bridge
|
|
70
|
+
│ └── camera.py # Camera capture
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Key Conventions
|
|
74
|
+
|
|
75
|
+
- Config lives in `~/.plexus/config.json`
|
|
76
|
+
- API keys are prefixed with `plx_`
|
|
77
|
+
- Source IDs (device slugs) are used for metric namespacing
|
|
78
|
+
- Telemetry is sent via WebSocket (real-time) and HTTP (persistence)
|
|
79
|
+
- The TUI is enabled by default in interactive terminals; headless mode is auto-detected
|