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.
Files changed (81) hide show
  1. plexus_python-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +68 -0
  2. plexus_python-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +57 -0
  3. plexus_python-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +17 -0
  4. plexus_python-0.1.0/.github/workflows/ci.yml +83 -0
  5. plexus_python-0.1.0/.github/workflows/publish.yml +73 -0
  6. plexus_python-0.1.0/.gitignore +54 -0
  7. plexus_python-0.1.0/AGENTS.md +79 -0
  8. plexus_python-0.1.0/API.md +508 -0
  9. plexus_python-0.1.0/CHANGELOG.md +9 -0
  10. plexus_python-0.1.0/CODE_OF_CONDUCT.md +30 -0
  11. plexus_python-0.1.0/CONTRIBUTING.md +53 -0
  12. plexus_python-0.1.0/LICENSE +190 -0
  13. plexus_python-0.1.0/PKG-INFO +470 -0
  14. plexus_python-0.1.0/README.md +388 -0
  15. plexus_python-0.1.0/SECURITY.md +31 -0
  16. plexus_python-0.1.0/examples/can_basic.py +173 -0
  17. plexus_python-0.1.0/examples/demo_field_unit.py +254 -0
  18. plexus_python-0.1.0/examples/demo_ground_station.py +135 -0
  19. plexus_python-0.1.0/examples/gateway_ble_relay.py +97 -0
  20. plexus_python-0.1.0/examples/mavlink_basic.py +157 -0
  21. plexus_python-0.1.0/plexus/__init__.py +31 -0
  22. plexus_python-0.1.0/plexus/__main__.py +4 -0
  23. plexus_python-0.1.0/plexus/adapters/__init__.py +122 -0
  24. plexus_python-0.1.0/plexus/adapters/base.py +409 -0
  25. plexus_python-0.1.0/plexus/adapters/ble.py +257 -0
  26. plexus_python-0.1.0/plexus/adapters/can.py +439 -0
  27. plexus_python-0.1.0/plexus/adapters/can_detect.py +174 -0
  28. plexus_python-0.1.0/plexus/adapters/mavlink.py +642 -0
  29. plexus_python-0.1.0/plexus/adapters/mavlink_detect.py +192 -0
  30. plexus_python-0.1.0/plexus/adapters/modbus.py +622 -0
  31. plexus_python-0.1.0/plexus/adapters/mqtt.py +350 -0
  32. plexus_python-0.1.0/plexus/adapters/opcua.py +607 -0
  33. plexus_python-0.1.0/plexus/adapters/registry.py +206 -0
  34. plexus_python-0.1.0/plexus/adapters/serial_adapter.py +547 -0
  35. plexus_python-0.1.0/plexus/buffer.py +257 -0
  36. plexus_python-0.1.0/plexus/cameras/__init__.py +57 -0
  37. plexus_python-0.1.0/plexus/cameras/auto.py +239 -0
  38. plexus_python-0.1.0/plexus/cameras/base.py +189 -0
  39. plexus_python-0.1.0/plexus/cameras/picamera.py +171 -0
  40. plexus_python-0.1.0/plexus/cameras/usb.py +143 -0
  41. plexus_python-0.1.0/plexus/cli.py +783 -0
  42. plexus_python-0.1.0/plexus/client.py +465 -0
  43. plexus_python-0.1.0/plexus/config.py +169 -0
  44. plexus_python-0.1.0/plexus/connector.py +666 -0
  45. plexus_python-0.1.0/plexus/deps.py +246 -0
  46. plexus_python-0.1.0/plexus/detect.py +1238 -0
  47. plexus_python-0.1.0/plexus/importers/__init__.py +25 -0
  48. plexus_python-0.1.0/plexus/importers/rosbag.py +778 -0
  49. plexus_python-0.1.0/plexus/sensors/__init__.py +118 -0
  50. plexus_python-0.1.0/plexus/sensors/ads1115.py +164 -0
  51. plexus_python-0.1.0/plexus/sensors/adxl345.py +179 -0
  52. plexus_python-0.1.0/plexus/sensors/auto.py +290 -0
  53. plexus_python-0.1.0/plexus/sensors/base.py +412 -0
  54. plexus_python-0.1.0/plexus/sensors/bh1750.py +102 -0
  55. plexus_python-0.1.0/plexus/sensors/bme280.py +241 -0
  56. plexus_python-0.1.0/plexus/sensors/gps.py +317 -0
  57. plexus_python-0.1.0/plexus/sensors/ina219.py +149 -0
  58. plexus_python-0.1.0/plexus/sensors/magnetometer.py +239 -0
  59. plexus_python-0.1.0/plexus/sensors/mpu6050.py +162 -0
  60. plexus_python-0.1.0/plexus/sensors/sht3x.py +139 -0
  61. plexus_python-0.1.0/plexus/sensors/spi_scan.py +164 -0
  62. plexus_python-0.1.0/plexus/sensors/system.py +261 -0
  63. plexus_python-0.1.0/plexus/sensors/vl53l0x.py +109 -0
  64. plexus_python-0.1.0/plexus/streaming.py +743 -0
  65. plexus_python-0.1.0/plexus/tui.py +642 -0
  66. plexus_python-0.1.0/pyproject.toml +114 -0
  67. plexus_python-0.1.0/scripts/plexus.service +27 -0
  68. plexus_python-0.1.0/scripts/scan_buses.py +16 -0
  69. plexus_python-0.1.0/scripts/setup.sh +333 -0
  70. plexus_python-0.1.0/tests/test_basic.py +43 -0
  71. plexus_python-0.1.0/tests/test_buffer.py +145 -0
  72. plexus_python-0.1.0/tests/test_can_adapter.py +332 -0
  73. plexus_python-0.1.0/tests/test_config.py +47 -0
  74. plexus_python-0.1.0/tests/test_connector.py +30 -0
  75. plexus_python-0.1.0/tests/test_gps.py +147 -0
  76. plexus_python-0.1.0/tests/test_mavlink_adapter.py +711 -0
  77. plexus_python-0.1.0/tests/test_modbus_adapter.py +412 -0
  78. plexus_python-0.1.0/tests/test_mqtt_adapter.py +288 -0
  79. plexus_python-0.1.0/tests/test_retry.py +353 -0
  80. plexus_python-0.1.0/tests/test_sensor_hub.py +208 -0
  81. 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