Conversation
…prehensive documentation Co-authored-by: sgbaird <45469701+sgbaird@users.noreply.github.com>
…ect CLI usage Co-authored-by: sgbaird <45469701+sgbaird@users.noreply.github.com>
Co-authored-by: sgbaird <45469701+sgbaird@users.noreply.github.com>
…loyment_examples Co-authored-by: sgbaird <45469701+sgbaird@users.noreply.github.com>
…logic, extract testing functions Co-authored-by: sgbaird <45469701+sgbaird@users.noreply.github.com>
…ing to tests folder Co-authored-by: sgbaird <45469701+sgbaird@users.noreply.github.com>
Co-authored-by: sgbaird <45469701+sgbaird@users.noreply.github.com>
Add Prefect-based async deployment for desk lifter control
There was a problem hiding this comment.
Pull Request Overview
This PR adds comprehensive desk lifter control functionality to the progressive-automations-python package, introducing Prefect workflow orchestration, GPIO-based movement control, duty cycle management, and testing utilities. The changes enable remote desk control via Prefect Cloud with safety features to protect the motor.
Key changes:
- Adds Prefect workflow orchestration with async deployment and polling capabilities
- Implements GPIO-based movement control and duty cycle management for motor protection
- Provides CLI tools for testing and monitoring
Reviewed Changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/testing.py | Testing utilities for movement sequences and configuration-based execution |
| src/progressive_automations_python/prefect_flows.py | Prefect flow definitions and deployment functions |
| src/progressive_automations_python/movement_control.py | Low-level GPIO control for desk movements |
| src/progressive_automations_python/duty_cycle.py | Duty cycle tracking and enforcement logic |
| src/progressive_automations_python/desk_controller.py | High-level desk controller with safety checks |
| src/progressive_automations_python/deployment.py | Prefect deployment configuration utilities |
| src/progressive_automations_python/config.py | Configuration settings with validation |
| src/progressive_automations_python/cli.py | Command-line interface for testing |
| src/progressive_automations_python/init.py | Package exports and API definitions |
| setup.cfg | Dependencies and console script entry points |
| docs/quick-start.md | Quick start guide for setup and usage |
| docs/installation-and-usage.md | Comprehensive installation and usage documentation |
| docs/index.md | Documentation index updates |
| README.md | Updated package description and usage examples |
| ) | ||
|
|
||
| from progressive_automations_python.prefect_flows import ( | ||
| simple_movement_flow, |
There was a problem hiding this comment.
Duplicate export of simple_movement_flow in __all__ list. The second occurrence should likely be custom_movements_flow, test_sequence_flow, duty_cycle_monitoring_flow, or scheduled_duty_cycle_check which are imported but not exported.
| deployment = custom_movements_flow.from_source( | ||
| source=".", | ||
| entrypoint="prefect_flows.py:custom_movements_flow", |
There was a problem hiding this comment.
References undefined custom_movements_flow. This flow is not defined in the new prefect_flows.py file, but is referenced in deployment functions and imports in init.py. The flow definition is missing from this file.
|
|
||
| if len(sys.argv) > 1: | ||
| if sys.argv[1] == "test": | ||
| test_sequence_flow() |
There was a problem hiding this comment.
References undefined test_sequence_flow. This flow is not defined in the new prefect_flows.py file but is called in the __main__ section. The flow definition is missing.
| if sys.argv[1] == "test": | ||
| test_sequence_flow() | ||
| elif sys.argv[1] == "movements": | ||
| custom_movements_flow() |
There was a problem hiding this comment.
References undefined custom_movements_flow. This flow is not defined in the new prefect_flows.py file but is called in the __main__ section. The flow definition is missing.
| elif sys.argv[1] == "movements": | ||
| custom_movements_flow() | ||
| elif sys.argv[1] == "monitor": | ||
| duty_cycle_monitoring_flow() |
There was a problem hiding this comment.
References undefined duty_cycle_monitoring_flow. This flow is not defined in the new prefect_flows.py file but is called in the __main__ section. The flow definition is missing.
|
|
||
| # Phase 2: Rest | ||
| print(f"\n--- Phase 2: Resting for {rest_time} seconds ---") | ||
| import time |
There was a problem hiding this comment.
Import statement placed in the middle of function body. The time module should be imported at the top of the file with other imports to follow Python conventions.
| logger.warning(f"⏳ Duty cycle capacity insufficient - will wait {wait_time:.1f}s before movement") | ||
|
|
||
| # Wait for duty cycle to free up | ||
| import time |
There was a problem hiding this comment.
Import statement placed in the middle of function body. The time module should be imported at the top of the file with other imports to follow Python conventions.
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
There was a problem hiding this comment.
Excessive blank lines (9 consecutive blank lines) between functions reduce code readability. Consider removing these to maintain consistency with Python style guidelines (typically 2 blank lines between top-level functions).
|
|
||
| The system enforces a 10% duty cycle (2 minutes on, 18 minutes off) to protect the motor: | ||
|
|
||
| - **Maximum continuous runtime**: 30 seconds |
There was a problem hiding this comment.
Documentation states maximum continuous runtime as 30 seconds, but config.py sets MAX_CONTINUOUS_RUNTIME = 45. This inconsistency between documentation and code could confuse users.
| raise ValueError("No last known position in state file") | ||
|
|
||
| # Check movement requirements | ||
| check_result = check_movement_against_duty_cycle(target_height, current_height, UP_RATE, DOWN_RATE) |
There was a problem hiding this comment.
Function call passes UP_RATE and DOWN_RATE parameters, but the function signature in duty_cycle.py shows these parameters have default values of 4.8. The actual config values are 0.54 and 0.55, suggesting the defaults are incorrect and will cause movement time calculation errors.
merged in wrong order originally