Skip to content

added custom model and board - added reverse logic endstop#50

Open
MicioMax wants to merge 100 commits into
OpenScan-org:mainfrom
MicioMax:miciomax
Open

added custom model and board - added reverse logic endstop#50
MicioMax wants to merge 100 commits into
OpenScan-org:mainfrom
MicioMax:miciomax

Conversation

@MicioMax
Copy link
Copy Markdown
Contributor

As from Discord post, I added the ability to set a "custom" device and shield, in order to allow custom models.
I also added an "active_high" endstop parameter to use endstops with reverse logic (high when pressed instead of low).

@esto-openscan
Copy link
Copy Markdown
Member

Thanks for the PR!

Custom builds (CUSTOM enums + MicioMax config)
The CUSTOM enum values look like a nice addition for supporting custom builds. Regarding the MicioMax device config, I’m not sure we should ship it as a default config in the repo, otherwise every custom PCB might need its own file. Would you be okay adding it as example_custom.json instead? I think this would be a great starting point for anyone with custom hardware.

Endstop / active_high 
You mentioned the switch is "high when pressed". With pull_up=True, the callback is still wired to when_released, so the trigger timing might not match your intent. Could you quickly double-check whether the motor stops when the endstop is hit, not when it is released? If it stops on release, we should switch between when_pressed and when_released based on active_high.

move_to_endstop()
This duplicates parts of move_degrees() but misses some safety guards. The main concern is the missing _stop_requested = False reset. If a previous stop() was called (e.g. by an endstop trigger), the motor would silently skip the entire movement. The is_busy() guard is less critical since the router already checks it, but good to have for when move_to_endstop() gets called from elsewhere.

Side note: the homing flow (initial angle override, hardcoded degrees, sleep(3)) and even _execute_movement() could use cleanup. I can follow up separately so we keep this PR focused.

@MicioMax
Copy link
Copy Markdown
Contributor Author

Hi, some notes on yours and more enhancements:

Custom builds (CUSTOM enums + MicioMax config)
It's ok to put in examples, I didn't know about them and I let inside default configs to show usage of active_high

Endstop / active_high
My switch is a "normally closed" one, so it opens when pressed. When wired as yours (pull up resistor and connection to ground) brings high (1) level when pressed and low (0) level when released, so you need the active_high. I tested it and it works correctly. I could also wire the endstop differently, so with a pull-down resistor and wired to positive rail instead of negative, so the "active_high" flag would not be needed; but then you should wire differently the endstops basing on their kind.
Resuming : if you take my code, with NO "active_high" flag it behaves the old way; with "active_high" enabled it stops the motor on 1 level, so when switch opens if wired like usual.

move_to_endstop()
the safety guard should be the endstop itself, maybe we can limit the number of steps to do a full 360° turn or, at least, 180°. IIRC you have 140° maximum, which if started when the scanner is pointing to 0° is not enough.
IMHO the "home" command should deserve an API endpoint and its behaviour should be set by some flags in the device settings, for exampe "home_mode=normal | calibrate_at_startup_only | calibrate_when_motors_idle" | calibrate_always" so it could cover all usages. To be on the safest side we'd need TWO endstops.... my PCB has connectors for them and doing so we could even measure the max and min device positions. A bit overkilling, maybe.

timeouts
simple motor timeout could be "timeout=0" for no timeout and "timeout=nnn" for nnn seconds motor timeout.
If we want to go deeper, we could put a "motor_timeout" and a "device_timeout" which puts the whole device, including the raspberry, in sleep mode. A bit overkilling, but it could spare some CO2 if the device is left alone for hours ;-)

device discovery in network
I was playing yesterday with device discovery on my K1Max, I got to appear it as a printer device which, when double clicked on it, opens the browser to the main page. On K1Max I had to use a python script because the provided wsdd2 service is lacking, but on raspberry we could have both the network shares as "computer" and the web page as "scanner device" with some settings tweaking, which would be nice... it's simpler to open the "network share" page and double click on the scanner device.

@esto-openscan
Copy link
Copy Markdown
Member

Awesome and thanks for pushing this forward!

Also, the additional feature ideas here and the process you shared on Discord sound really cool.

How would you like to proceed with this and the open PR?

I think we could merge this fairly quickly with a few small changes (e.g. config naming and resetting _stop_requested). If you're okay with it, I'm happy to suggest the changes directly on your PR (or push a small follow-up commit), so we can keep the momentum and get it merged.

For the newer feature ideas: do you prefer opening separate PRs for those, or should we turn the current PR into a draft and merge it later as a bigger package?

@MicioMax
Copy link
Copy Markdown
Contributor Author

Hi,
I think is better to wait and merge a bit later, as I've ready (just testing a bit more) the sleep mode stuff and I plan to add the PWM control (probably an endpoitn /light/light name/dim with a value from 0 to 100% and a dedicated HOME endpoint (so we can let the backend choose which kind of home depending on config values).
Later I could also implement the LCD display with the ability to do "offline scans".
It's ok for you ?

@esto-openscan
Copy link
Copy Markdown
Member

That sounds great, and I really like the direction.

I think it makes sense to wait a little and merge after the motor sleep mode and home endpoint are included. Those two features are closely related, and merging them should still be manageable.

For the other ideas (PWM light control, LCD + offline scans), I’d prefer separate PRs afterwards to keep the review smaller and avoid too much divergence and merge conflicts with the develop branch.

So let’s proceed like this: we keep this PR open (or convert it to draft while you finish testing), add sleep mode + home endpoint, then we merge this PR and continue with PWM / LCD in follow-up PRs.

If you need any help while testing or wiring this up, feel free to ping me.

esto-openscan and others added 19 commits March 6, 2026 17:37
- Replaced `photo_async` with `photo` for single photo captures, now again correctly allowing different image formats.
- Added regression tests to ensure proper handling of configured image formats.
- Refactored `_scanner_device` creation into `_create_default_scanner_device` for better reusability.
- Introduced `_FACTORY_DEFAULT_CONFIG` to store factory defaults in JSON format.
- Updated configuration logic to enforce safe defaults (e.g., `motors_timeout`, `startup_mode`, `calibrate_mode`).
- Enhanced `initialize` method with better parameter handling and separation of concerns.
- Added integration and unit tests to validate configuration handling and initialization logic.
* feat(tasks): add QR code WiFi scan task and utility functions

- Introduced `qr_scan_task` to detect and apply WiFi credentials from QR codes via the camera.
- Added `/qr-scan` endpoint to start background QR code scanning.
- Implemented `wifi.py` utilities for QR code parsing and network configuration.
- Updated `task_manager` to register `qr_scan_task`.
- Added auto-start of QR WiFi scan task on startup if enabled in firmware settings and no WiFi is connected.
- Introduced `firmware_settings.json` for global firmware configuration.

* feat(tasks): enhance QR WiFi scan with robust decoding and improved performance
- Extended dependencies in `pyproject.toml` to include `zxing-cpp`.
- Introduced `_cleanup_stale_qr_tasks` to remove cancelled/interrupted QR tasks and trim error task history.
- Enhanced task initialization in `qr_scan_task` with automatic cleanup on startup.
- Added tests to validate success and error scenarios for `qr_scan_task`.
- Verified proper cleanup of stale tasks including cancelled and outdated error tasks.
- Ensured correct task status updates and WiFi QR credential parsing logic.
…ig-init

fix(device): scanner initialization and add safe defaults
…hoto-formats

fix(scan_task): fix photo capture to support non-JPEG formats
- Added `max_attempts` and `rescan_delay` to fine-tune WiFi connection behavior.
- Implemented retry logic with scan rescans for better network recovery.
- Introduced cooldown and backoff delays for repeated connection attempts in QR scan tasks.
- Introduced `repo.json` containing device filtering, firmware metadata, and download links.
- Added support for Raspberry Pi models 3, 4, 400, and 5.
- Included detailed descriptions, capabilities, and SHA256 checksums for image files.
- Introduced a `calibrated` property in motor status responses.
- Added `force` parameter to allow recalibration even when the motor is already considered calibrated.
- Updated OpenAPI schemas (`v0.6`, `v0.7`, `v0.8`, and `next`) to reflect these changes.
- Added `ensure_wifi_radio_enabled()` to confirm the WiFi radio is on.
- Introduced helper methods `is_wifi_radio_enabled()` and `_run_nmcli_command()` for consistent `nmcli` handling.
- Improved error handling and logging for WiFi operations.
…est file

- Updated firmware metadata in `repo.json`, including release dates, file sizes, and SHA256 checksums.
- Added `local_json.rpi-imager-manifest` file for Raspberry Pi Imager compatibility, supporting device filtering and capability tags.
…anifests

- Updated `repo.json` and `local_json.rpi-imager-manifest` with new release dates, file sizes, and SHA256 checksums.
…file paths in manifests

- Added `extract_size` and `extract_sha256` metadata to `repo.json` and `local_json.rpi-imager-manifest`.
- Updated file paths in manifests for firmware deployment.
- Included missing `icon` in firmware metadata and adjusted descriptions.
esto-openscan and others added 30 commits April 15, 2026 17:21
chore: bump project version to 0.11.2 in pyproject.toml
- Consolidated `ScannerDeviceConfig` schema by removing separate `Input` and `Output` definitions.
- Added `camera_preview_enabled` toggle for non-live camera workflows.
- Introduced `scan_radius_mm` and `min_phi`/`max_phi` properties in calibration models.
- Replaced `TriggerPolarity` with `TriggerActiveLevel` standard enum.
- Enhanced `FirmwareSettings` schema with additional attributes.
update image manifests and openanpi types
- Added `_get_cloud_temp_dir` utility to manage cloud temp directories.
- Introduced `_temp_storage_error` to raise detailed errors for insufficient temp storage.
- Updated `_build_project_archive` and cloud download logic to use specific temp directories and handle ENOSPC errors.
- Added unit tests to verify behavior when temp storage is exhausted.
- Added `_create_cloud_download_temp_file` and `_register_active_cloud_temp_path` for better temp file management.
- Introduced `_ensure_cloud_temp_space` to verify sufficient storage before cloud operations.
- Implemented `_cleanup_cloud_temp_dir` to remove stale files securely.
- Updated cloud upload and download logic to handle temporary storage limitations properly.
- Added comprehensive unit tests to validate changes.
…ive updates

- Introduced throttling for task progress persistence to reduce writes for minor updates.
- Added configurable parameters for persistence intervals and delta thresholds.
- Updated task state handling to selectively persist progress based on update significance.
- Included additional tests to verify throttling behavior and ensure consistency.
- Introduced the `prefer_stacked_photos` query parameter to prioritize stacked JPEG outputs in project and scan ZIP downloads.
- Updated backend logic to skip original photos when stacked results exist.
- Enhanced OpenAPI schema to document the new parameter.
- Added tests to verify preferred photo selection and proper ZIP stream behavior.
- Added functionality to register and manage stacked photo paths in scan metadata.
- Introduced `stacked_size_bytes` to track the total size of stacked JPEG outputs.
- Updated task cancellation and completion handlers to persist stacked photo updates.
- Enhanced scan size recalculation to account for stacked photo metadata.
- Adjusted APIs to handle stacked photo paths and avoid duplication.
- Added tests to validate stacked photo handling, scan size updates, and path normalization.
- Simplified the `delete_photos` implementation to remove redundant try-except blocks and improve readability.
- Added detailed `Query` descriptions for better API documentation.
- Enhanced error handling for missing scans, invalid paths, and unknown exceptions.
- Updated and added tests to validate new behaviors for edge cases.
- Updated logic to filter out "stacked/" photos from ZIP downloads unless explicitly preferred.
- Applied changes across multiple API versions for consistency.
- Added tests to validate exclusion behavior of stacked photos in `photos_only` downloads.
…-fs-zip-download

Feature/prefer fs zip download
- Introduced `pause_before_capture_ms` setting to allow configurable delays before photo capture.
- Enhanced scan logic to detect cancellation before and during the pause.
- Updated schema to include the new pause setting with validation.
…nge validation

- Updated `focus_range` type in `ScanSetting` to use `Annotated` for clearer and more reusable validation constraints.
- Replaced `confloat` with the `FocusValue` type alias for focus range fields.
…narios

- Added tests for `pause_before_capture_ms` behavior, including handling of delay, cancellation, and resume scenarios.
- Improved test coverage for photo capture logic during cancellation.
- Verified default pause setting for legacy scan configurations.
…lt phi constraints

- Added new tests for `get_constrained_path` to validate behavior for fixed theta and phi constraints, as well as fully fixed positions.
- Updated existing tests to reflect default `min_phi` and `max_phi` values.
- Adjusted validation logic to handle equal theta/phi bounds and default values.
- Enhanced path generation to account for fully constrained positions and edge cases.
… handling

- Added comprehensive tests for GPIO auto-initialization, error cases, and router patch handling.
- Introduced new motor tests for movement execution, direction handling, and stop behavior.
- Restored and updated scan task path generation tests to validate phi constraints and default values.
- Enhanced mocking strategies to simplify setup for hardware and executor dependencies.
Allow equal phi and theta angles in constrained paths
# Conflicts:
#	tests/controllers/services/test_scan_task.py
Feature: Adjustable pause before capture in scan task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants