Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Build & Run Commands
- Create environment: `mamba create -n openhsi python==3.10 openhsi flask`
- Activate environment: `mamba activate openhsi`
- Run server: `python server.py`
- Run as service: `sudo systemctl start openhsi-flask.service`
- Service management: `sudo systemctl {start|stop|restart|status} openhsi-flask.service`
- View logs: `sudo journalctl -u openhsi-flask.service -f`

## Code Style Guidelines
- Indentation: 4 spaces
- Line length: ~88 characters (Black default)
- Imports: Group by source (stdlib, third-party, local); use parenthesized imports
- Naming: Classes: PascalCase, Functions/vars: snake_case, Constants: UPPER_SNAKE_CASE
- Error handling: Use try/except with specific exceptions, log errors with app.logger
- Types: Type annotations not currently used
- Documentation: Docstrings and Flask-RestX for API endpoints
- API patterns: Use Flask-RestX models for validation and documentation

## Architecture Overview

### Core Application Structure
- **Single-file Flask application** (`server.py`) with Flask-RestX for API documentation
- **Threaded camera operations** with global state management using thread locks
- **Real-time status polling** architecture for capture progress monitoring
- **Bootstrap-based responsive frontend** with tabbed interface

### Camera Integration Patterns
- **Custom OpenHSI camera wrapper** extending `FlirCamera` with progress callbacks
- **Thread-safe capture operations** using `capture_lock` and `capture_status` globals
- **Dual-tier settings system**: Basic settings (exposure, lines, processing) and advanced settings (binning, windowing, etc.)
- **Calibration file integration**: Hardcoded paths to `.json` settings and `.nc` calibration files

### API Architecture
- **RESTful endpoints** grouped by functionality (camera, file management, system)
- **Flask-RestX models** for request/response validation and auto-generated Swagger docs
- **Secure file operations** restricted to `/data` directory with path traversal protection
- **System time management** with sudo permission handling

### Frontend Communication
- **AJAX polling pattern** (500ms intervals) for real-time status updates
- **Tabbed interface** with Bootstrap for modular feature organization
- **Progress monitoring** with elapsed time and capture rate display
- **File browser integration** with download, view, and delete capabilities

### Key Global Variables
- `capture_lock`: Threading lock for camera operations
- `capture_status`: Dictionary tracking capture state, progress, and timing
- `log_messages`: Centralized logging system with timestamps and severity levels
- `current_camera`: Global camera instance for thread-safe operations

### File System Integration
- **Secure file browsing** within `/data` directory only
- **Multiple file operations**: view, download, delete files and empty folders
- **Image display options**: histogram equalization and contrast adjustment
- **Metadata extraction** for file listings

## Deployment Configuration
- **Systemd service**: Pre-configured in `assets/openhsi-flask.service`
- **Nginx reverse proxy**: Configuration in `assets/openhsi.ngnix`
- **Time permissions**: `setup_time_permissions.sh` for sudo date command access
- **Production settings**: Environment variables and user permissions for `openhsi` user
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@

An example simple webinterface to drive an OpenHSI camera.

![Screen Cap for Web interface](assets/screencap.png)
![Screen Cap for Web interface](assets/screencap.png)

## Setup

For detailed installation and setup instructions, see: [Setup Guide](docs/setup.md)
Binary file added assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions assets/openhsi-flask.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[Unit]
Description=OpenHSI Flask Web Server
After=network.target

[Service]
User=openhsi
WorkingDirectory=/home/openhsi/orlar/simple-web-controller
ExecStart=/home/openhsi/miniforge3/envs/openhsi/bin/python /home/openhsi/orlar/simple-web-controller/server.py
Restart=always
Environment=FLASK_ENV=production

[Install]
WantedBy=multi-user.target
12 changes: 12 additions & 0 deletions assets/openhsi.ngnix
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
server {
listen 80;
server_name _; # Replace with your domain or IP address

location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
32 changes: 32 additions & 0 deletions docs/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<html>

<head>
<!-- Load the latest Swagger UI code and style from npm using unpkg.com -->
<script src="https://unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js"></script>
<link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@3/swagger-ui.css" />
<title>My New API</title>
</head>

<body>
<div id="swagger-ui"></div> <!-- Div to hold the UI component -->
<script>
window.onload = function () {
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
url: "swagger.json", //Location of Open API spec in the repo
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
})
window.ui = ui
}
</script>
</body>

</html>
219 changes: 219 additions & 0 deletions docs/setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
![[assets/logo.png]]

## Install dependancies

### Miniforge
Download and install miniforge.
`wget "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh"`
`bash Miniforge3-$(uname)-$(uname -m).sh`

### Openhsi env
make python env and install openhsi+depenacies (match python version to that required by FLIR/Spinaker)
`mamba create -n openhsi python==3.10 openhsi flask`
`mamba activate openhsi`

The rest assume you have openhsi env activated etc.

### # Spinnaker SDK (FLIR camera, see openhsi docs for other cameras)
Download SDK.
https://www.teledynevisionsolutions.com/products/spinnaker-sdk/?model=Spinnaker%20SDK&vertical=machine%20vision&segment=iis

#### Spinnaker SDK 4.2.0.46 for Ubuntu 22.04 (January 10, 2025)
https://flir.netx.net/file/asset/68772/original/attachment - 64-bit ARM SDK
https://flir.netx.net/file/asset/68774/original/attachment - Python 3.10 aarch64

`wget -O spinnaker_python-4.2.0.46-cp310-cp310-linux_aarch64-22.04.tar.gz https://flir.netx.net/file/asset/68774/original/attachment
`wget -O spinnaker-4.2.0.46-arm64-22.04-pkg.tar.gz https://flir.netx.net/file/asset/68772/original/attachment`

`tar -xvzf spinnaker_python-4.2.0.46-cp310-cp310-linux_aarch64-22.04.tar.gz`
`tar -xvzf spinnaker-4.2.0.46-arm64-22.04-pkg.tar.gz`

`sudo apt-get install libusb-1.0-0 qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools`
`sudo sh install_spinnaker_arm.sh`

Answer yes to all quesitons. At "Adding new members to usergroup flirimaging", and any users on system that need to access camera., eg. *openhsi* user.

`pip install spinnaker_python-4.2.0.46-cp310-cp310-linux_aarch64.whl --no-deps`
`pip install simple-pyspin --no-deps`

## Install OpenHSI Orlar code
Clone or download this repo.


#### Setup Systemd Auto Start

##### Raspberry Pi Permissions Note
By default on Raspberry Pi, the original user (typically `pi`) has sudo NOPASSWD privileges configured in `/etc/sudoers.d/010_pi-nopasswd`. This means the default user can run sudo commands without entering a password.

##### Service Installation
From the repo folder:

```bash
# Copy the service file to systemd directory
sudo cp assets/openhsi-flask.service /etc/systemd/system/openhsi-flask.service

# Edit the service file to match your paths (if different from default)
sudo nano /etc/systemd/system/openhsi-flask.service

# Reload systemd to recognize the new service
sudo systemctl daemon-reload

# Enable the service to start on boot
sudo systemctl enable openhsi-flask.service

# Start the service now
sudo systemctl start openhsi-flask.service

# Check service status
sudo systemctl status openhsi-flask.service
```

##### Service Management Commands
```bash
# Start the service
sudo systemctl start openhsi-flask.service

# Stop the service
sudo systemctl stop openhsi-flask.service

# Restart the service
sudo systemctl restart openhsi-flask.service

# Check service status and logs
sudo systemctl status openhsi-flask.service
sudo journalctl -u openhsi-flask.service -f # Follow logs in real-time
sudo journalctl -u openhsi-flask.service --since today # Today's logs
```

##### Time Permissions Setup
The OpenHSI application may need to set the system time for synchronization purposes. The included `setup_time_permissions.sh` script configures the necessary permissions:

**Note for Raspberry Pi OS:** The default Raspberry Pi OS does not require this permissions script. The default user (typically `pi`) already has passwordless sudo access for all commands via `/etc/sudoers.d/010_pi-nopasswd`. This script is useful for:
- Non-Raspberry Pi systems
- Custom user accounts without full sudo access
- Production deployments where you want to limit sudo permissions to only the `date` command

```bash
# Make the script executable
chmod +x setup_time_permissions.sh

# Run as root to set up time permissions for the openhsi user
sudo ./setup_time_permissions.sh

# Or specify a different user
sudo ./setup_time_permissions.sh myuser
```

**What the script does:**
1. **Creates a sudoers rule** in `/etc/sudoers.d/openhsi-time`
2. **Allows the specified user** (default: `openhsi`) to run `sudo date` without password
3. **Sets proper permissions** (440) on the sudoers file for security
4. **Validates syntax** using `visudo -c` to prevent system lockout

**Security Note:** This only grants permission to run the `date` command with sudo, not full sudo access.

**Usage after setup:**
```bash
# The openhsi user can now set system time without password prompt
sudo date -s '2024-12-25 10:30:00'
```

## Updating the System

### Update OpenHSI Package
To update the OpenHSI package to the latest version:

```bash
# Activate the openhsi environment
mamba activate openhsi

# Update OpenHSI package
mamba update openhsi

# Or update all packages in the environment
mamba update --all
```

### Update Repository Code

#### Update to Latest Development Version
```bash
# Navigate to the repository directory
cd /path/to/simple-web-controller

# Pull latest changes from the dev branch (active development)
git pull origin dev

# Or pull from main branch (stable releases)
git pull origin main

# Restart the service to apply changes
sudo systemctl restart openhsi-flask.service
```

#### Update to Specific Release
```bash
# Navigate to the repository directory
cd /path/to/simple-web-controller

# Fetch all tags and releases
git fetch --tags

# List available release tags
git tag -l

# Checkout a specific release (replace v1.2.3 with desired version)
git checkout v1.2.3

# Restart the service to apply changes
sudo systemctl restart openhsi-flask.service
```

#### Check Current Version
```bash
# Check current git commit/tag
git describe --tags --always

# Check current branch
git branch --show-current

# View recent commits
git log --oneline -5
```

### Update Workflow
1. Stop the service: `sudo systemctl stop openhsi-flask.service`
2. Update OpenHSI package (if needed): `mamba update openhsi`
3. Update repository code: `git pull` or `git checkout <tag>`
4. Start the service: `sudo systemctl start openhsi-flask.service`
5. Check service status: `sudo systemctl status openhsi-flask.service`


#### ngnix port 80 proxy
Setup ngnix proxy so interface can accessed via browser without port.

`sudo apt update`
`sudo apt install nginx`

`sudo rm /etc/nginx/sites-enabled/default`
`sudp cp assets//openhsi.ngnix /etc/nginx/sites-available/openhsi`
`sudo ln -s /etc/nginx/sites-available/openhsi /etc/nginx/sites-enabled/`

`sudo nginx -t`
`sudo systemctl reload nginx`


## Setup Tailscale (FOR REMOTE ACCESS)
Depending on use case and deployment, it may be sensible to setup a remote access system, such as tailscale.com












Loading