Showing preview only (2,909K chars total). Download the full file or copy to clipboard to get everything.
Repository: signag/raspi-cam-srv
Branch: main
Commit: 41367ee33931
Files: 143
Total size: 2.8 MB
Directory structure:
gitextract_uzgjfrtj/
├── .dockerignore
├── .gitignore
├── .vscode/
│ └── launch.json
├── Dockerfile
├── LICENSE
├── README.md
├── config/
│ ├── raspiCamSrv.service
│ └── raspiCamSrv_gunicorn.service
├── docker-compose.yml
├── docs/
│ ├── API.md
│ ├── AiCameraSupport.md
│ ├── Authentication.md
│ ├── Background Processes.md
│ ├── Cam.md
│ ├── CamCalibration.md
│ ├── CamMulticam.md
│ ├── CamStereo.md
│ ├── CamWebcam.md
│ ├── CameraControls.md
│ ├── CameraControls_AutoExposure.md
│ ├── CameraControls_Ctrl.md
│ ├── CameraControls_Exposure.md
│ ├── CameraControls_Image.md
│ ├── CameraControls_UsbCams.md
│ ├── Configuration.md
│ ├── Configuration_AI.md
│ ├── Console.md
│ ├── ConsoleActionButtons.md
│ ├── ConsoleVButtons.md
│ ├── FocusHandling.md
│ ├── Information.md
│ ├── Information_Cam.md
│ ├── Information_CamPrp.md
│ ├── Information_Sensor.md
│ ├── Information_Sys.md
│ ├── LiveDirectControl.md
│ ├── LiveScreen.md
│ ├── PhotoSeries.md
│ ├── PhotoSeriesExp.md
│ ├── PhotoSeriesFocus.md
│ ├── PhotoSeriesTimelapse.md
│ ├── PhotoViewer.md
│ ├── Phototaking.md
│ ├── ReleaseNotes.md
│ ├── ScalerCrop.md
│ ├── Settings.md
│ ├── SettingsAButtons.md
│ ├── SettingsAPI.md
│ ├── SettingsConfiguration.md
│ ├── SettingsConfiguration_NoCam.md
│ ├── SettingsDevices.md
│ ├── SettingsLButtons.md
│ ├── SettingsUpdate.md
│ ├── SettingsUsers.md
│ ├── SettingsVButtons.md
│ ├── Settings_NoCam.md
│ ├── SetupDocker.md
│ ├── Trigger.md
│ ├── TriggerActions.md
│ ├── TriggerActive.md
│ ├── TriggerCalendar.md
│ ├── TriggerCameraActions.md
│ ├── TriggerControl.md
│ ├── TriggerEventViewer.md
│ ├── TriggerMotion.md
│ ├── TriggerNotification.md
│ ├── TriggerOverview.md
│ ├── TriggerTriggerActions.md
│ ├── TriggerTriggers.md
│ ├── Troubelshooting.md
│ ├── Tuning.md
│ ├── UserGuide.md
│ ├── UserGuide_NoCam.md
│ ├── Z_Legacy_Information.md
│ ├── ZoomPan.md
│ ├── api/
│ │ └── postman/
│ │ └── raspiCamSrv.postman_collection.json
│ ├── bp_Hotspot_Bookworm.md
│ ├── bp_Hotspot_Bullseye.md
│ ├── bp_Hotspot_Trixie.md
│ ├── bp_PiZero_Standalone.md
│ ├── features.md
│ ├── getting_started_overview.md
│ ├── gpioDevices/
│ │ ├── ServoPWM.md
│ │ └── StepperMotor.md
│ ├── img/
│ │ └── TLSeriesStateChart.vsdx
│ ├── index.md
│ ├── installation.md
│ ├── installation_man.md
│ ├── picamera2_manual.md
│ ├── requirements.md
│ ├── service_configuration.md
│ ├── system_setup.md
│ ├── tutorials/
│ │ ├── AWB_with_neural_networks.md
│ │ └── Tutorials_Overview.md
│ └── updating_raspiCamSrv.md
├── mkdocs.yml
├── raspiCamSrv/
│ ├── __init__.py
│ ├── api.py
│ ├── auth.py
│ ├── auth_su.py
│ ├── camCfg.py
│ ├── camera_pi.py
│ ├── config.py
│ ├── console.py
│ ├── db.py
│ ├── dbx.py
│ ├── gpioDeviceTypes.py
│ ├── gpioDevices.py
│ ├── home.py
│ ├── images.py
│ ├── info.py
│ ├── motionAlgoIB.py
│ ├── motionDetector.py
│ ├── photoseries.py
│ ├── photoseriesCfg.py
│ ├── schema.sql
│ ├── settings.py
│ ├── static/
│ │ └── w3.css
│ ├── stereoCam.py
│ ├── sun.py
│ ├── templates/
│ │ ├── auth/
│ │ │ ├── login.html
│ │ │ ├── password.html
│ │ │ └── register.html
│ │ ├── base.html
│ │ ├── config/
│ │ │ └── main.html
│ │ ├── console/
│ │ │ └── console.html
│ │ ├── home/
│ │ │ ├── index.html
│ │ │ └── liveDirectPanel.html
│ │ ├── images/
│ │ │ └── main.html
│ │ ├── info/
│ │ │ └── info.html
│ │ ├── media_viewer.html
│ │ ├── photoseries/
│ │ │ └── main.html
│ │ ├── settings/
│ │ │ └── main.html
│ │ ├── trigger/
│ │ │ └── trigger.html
│ │ └── webcam/
│ │ └── webcam.html
│ ├── trigger.py
│ ├── triggerHandler.py
│ ├── version.py
│ ├── versionDoc.py
│ └── webcam.py
├── requirements.txt
└── scripts/
├── install_raspiCamSrv.sh
└── uninstall_raspiCamSrv.sh
================================================
FILE CONTENTS
================================================
================================================
FILE: .dockerignore
================================================
**/__pycache__
**/.env
**/.git
**/.venv
**/.vscode
config
**/docs
**/instance
**/logs
**/backups
raspiCamSrv/static/config
raspiCamSrv/static/events
raspiCamSrv/static/photos
raspiCamSrv/static/photoseries
raspiCamSrv/static/tuning
**/tests
**/.dockerignore
**/.gitignore
**/docker-compose*
**/Dockerfile*
LICENSE
README.md
================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
tests/
user_code/
logs/
output/
backups
raspiCamSrv/static/calib_data/
raspiCamSrv/static/calib_photos/
raspiCamSrv/static/photos/
raspiCamSrv/static/timelapse/
raspiCamSrv/static/photoseries/
raspiCamSrv/static/config/
raspiCamSrv/static/events/
raspiCamSrv/static/tuning/
*.mp4
*.h264
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
================================================
FILE: .vscode/launch.json
================================================
{
// Verwendet IntelliSense zum Ermitteln möglicher Attribute.
// Zeigen Sie auf vorhandene Attribute, um die zugehörigen Beschreibungen anzuzeigen.
// Weitere Informationen finden Sie unter https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python-Debugger: Aktuelle Datei",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
}
]
}
================================================
FILE: Dockerfile
================================================
# syntax=docker/dockerfile:1
FROM dtcooper/raspberrypi-os:bookworm
LABEL maintainer="signag"
RUN apt update && apt -y upgrade
RUN apt update && apt install -y \
gcc-aarch64-linux-gnu \
systemd \
systemd-timesyncd \
python3 \
python3-dev \
python3-pip \
python3-venv \
python3-opencv \
python3-gpiozero \
python3-lgpio \
ffmpeg \
python3-picamera2 --no-install-recommends \
imx500-all \
dpkg-dev \
v4l-utils
RUN ln -s /usr/bin/python3 /usr/bin/python
# Prevents Python from writing pyc files.
ENV PYTHONDONTWRITEBYTECODE=1
# Keeps Python from buffering stdout and stderr to avoid situations where
# the application crashes without emitting any logs due to buffering.
ENV PYTHONUNBUFFERED=1
# Set environment variables
ENV DEBIAN_FRONTEND=noninteractive
WORKDIR /app
# Copy the source code into the container.
COPY . .
# Install Python dependencies in virtual environment
RUN python -m venv --system-site-packages .venv
ENV PATH=".venv/bin:$PATH"
RUN pip install --no-cache-dir -r requirements.txt
# Expose the port that the application listens on.
EXPOSE 5000
# Initialize database for Flask
RUN flask --app raspiCamSrv init-db
# Run the application.
CMD gunicorn -b 0.0.0.0:5000 -w 1 -k gthread --threads 6 --timeout 0 --log-level info 'raspiCamSrv:create_app()'
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2023 signag
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# raspiCamSrv V4.10.0
**raspiCamSrv** is a Web server for Raspberry Pi systems providing an App for control and streaming of CSI and USB cameras as well as for controlling a large variety of connected GPIO devices.
While all currently connected cameras are accessible by the system, up to two cameras can be operated simultaneously at a time, supporting multi-camera features like Stereo Vision.
Interoperability between Cameras and GPIO devices is achieved through the freely configurable event handling infrastructure.
**raspiCamSrv** supports all Raspberry Pi platforms from Pi Zero to Pi 5, running Bullseye, Bookworm or Trixie OS.
Besides the currently available Raspberry Pi cameras, also compatible CSI cameras from other providers can be used.
USB web cams are seamlessly integrated.
**raspiCamSrv** is built with Flask 3.x and uses the Picamera2 library.
Due to responsive layout from W3.CSS, all modern browsers on PC, Mac or mobile devices can be used as clients.
For more details, refer to the [raspiCamSrv Documentation](https://signag.github.io/raspi-cam-srv/latest/), especially the [Features List](https://signag.github.io/raspi-cam-srv/latest/features/)
or check the [Release Notes](https://signag.github.io/raspi-cam-srv/latest/ReleaseNotes/) for current version and latest updates.

To [get started with raspiCamSrv](https://signag.github.io/raspi-cam-srv/latest/getting_started_overview/),
1. [Check necessary requirements](https://signag.github.io/raspi-cam-srv/latest/requirements/)
2. [Set up your Raspberry Pi](https://signag.github.io/raspi-cam-srv/latest/system_setup/)
3. [Install raspiCamSrv](https://signag.github.io/raspi-cam-srv/latest/installation/)
4. Refer to the raspiCamSrv [User Guide](https://signag.github.io/raspi-cam-srv/latest/UserGuide/)
================================================
FILE: config/raspiCamSrv.service
================================================
[Unit]
Description=raspiCamSrv
After=network.target
[Service]
ExecStart=/home/<user>/prg/raspi-cam-srv/.venv/bin/python -m flask --app raspiCamSrv run --port 5000 --host=0.0.0.0
Environment="PATH=/home/<user>/prg/raspi-cam-srv/.venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
WorkingDirectory=/home/<user>/prg/raspi-cam-srv
StandardOutput=inherit
StandardError=inherit
Restart=always
User=<user>
[Install]
WantedBy=multi-user.target
================================================
FILE: config/raspiCamSrv_gunicorn.service
================================================
[Unit]
Description=raspiCamSrv
After=network.target
[Service]
ExecStart=/home/<user>/prg/raspi-cam-srv/.venv/bin/gunicorn -b 0.0.0.0:5000 -w 1 -k gthread --threads 6 --timeout 0 --log-level info 'raspiCamSrv:create_app()'
Environment="PATH=/home/<user>/prg/raspi-cam-srv/.venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Environment="GUNICORN_THREADS=6"
WorkingDirectory=/home/<user>/prg/raspi-cam-srv
StandardOutput=inherit
StandardError=inherit
Restart=always
User=<user>
[Install]
WantedBy=multi-user.target
================================================
FILE: docker-compose.yml
================================================
name: raspi-cam-srv
services:
raspi-cam-srv:
container_name: raspi-cam-srv
build: .
image: signag/raspi-cam-srv
network_mode: "host"
ports:
- "5000:5000"
devices:
- /dev/video0:/dev/video0
- /dev/gpiochip0:/dev/gpiochip0
volumes:
- /dev:/dev
- /sys:/sys
- /run/udev/:/run/udev:ro
- /run/systemd:/run/systemd:ro
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
environment:
- GPIOZERO_PIN_FACTORY=lgpio
- SYSTEMD_BUS_ADDRESS=unix:path=/run/systemd/private
restart: unless-stopped
privileged: true
================================================
FILE: docs/API.md
================================================
# raspiCamSrv API
[](./UserGuide.md)
The **raspiCamSrv** API allows access to several RaspberryPi camera functions through WebService endpoints.
Configuration of the API is done on the [Settings/API](./SettingsAPI.md) screen.
## Postman Test Collection
For testing the API, a [Postman](https://www.postman.com/) collection is available at [docs/api/postman](https://github.com/signag/raspi-cam-srv/tree/main/docs/api/postman) which can be downloaded and imported into a Postman instance.

## API Documentation
The [docs/api/postman](https://github.com/signag/raspi-cam-srv/tree/main/docs/api/postman) folder contains also the [API Documentation](./api/postman/raspiCamSrv.postman_collection.pdf) generated from Postman.
## Variables
The collection uses a set of variables:

```base_url```, ```user``` and ```pwd``` need to be adjusted to the current environment for a user which has been previously created in raspiCamSrv.
```access_token``` and ```refresh_token``` will be automatically filled from responses of the /api/login and /api/refresh endpoints.
## Usage
### 1. Login
Use the ```api login``` request to log in to **raspiCamSrv** and receive an Access Token and a Refresh Token
### 2. Interact with **raspiCamSrv**
Use any of the GET requests to interact with **raspiCamSrv**.
These requests use the Access Token for authentication.
### 3. Refresh the Access Token
If a request returns a token expiration error, refresh the Access Token using the ```api refresh``` request.
This will use the Refresh Token for authentication and return a fresh Access Token.
================================================
FILE: docs/AiCameraSupport.md
================================================
# raspiCamSrv AI Camera Support
[](./UserGuide.md)
The [Raspberry Pi AI Camera](https://www.raspberrypi.com/documentation/accessories/ai-camera.html) has an integrated AI accelerator which can process Input Tensor data delivered by the camera ISP directly within the camera system.
Output Tensor data with inference information are delivered to the Raspberry Pi host system in the context of image meta data.
Therefore, the main computational effort for the neural network is on the camera system while the host system is left with analysis and visualization of inference from the meta data.
This makes it possible to see Neural Networks at work even on low cost system such as Raspberry Pi Zero 2 (See [Raspberry Models lower 5 and Raspberry Pi Zero](#raspberry-models-4-and-lower-and-raspberry-pi-zero)).
**raspiCamSrv** from V4.6 supports AI features for the imx500 on the basis of published [neural network models](https://github.com/raspberrypi/imx500-models) which are deployed together with the imx500-all package and for which Picamera2 provides [demo implemetations](https://github.com/raspberrypi/picamera2/tree/main/examples/imx500).
These implementations have been integrated in **raspiCamSrv** with minor modifications for visualization on different camera streams.
**NOTE**: Currently, Visualization of inference data always scales to the [Stream Size](./Configuration.md#stream-size-width-height) and does not consider cropping. Therefore you should avoid [zoom and pan](./ZoomPan.md).
## Installation
All required packages are installed with the [automatic installer](./installation.md#installer) if you confirm to use the AI Camera.
## Update from previous raspiCamSrv Versions
If you update from a previous **raspiCamSrv** version (V4.5 and earlier), you can just run the [automatic installer](./installation.md) again.
It will recognize components which are already installed and only install new components or update existing ones to the latest version.
## Activation
If an imx500 camera is connected to one of the CSI ports, this will be recognized by the raspiCamSrv Flask server at startup and is shown in the [Info/Cameras](./Information_Cam.md#ai-features) dialog.
By default, the imx500 camera is handled like a normal CSI camera.
To activate Camera AI support, you need to check *Use Camera AI* in the [Settings](./Settings.md#activating-and-deactivating-the-use-of-camera-ai-features) dialog.
## Neural Network Configuration
If *Use Camera AI* is activated, the [Config](./Configuration.md) menu will show an additional submenu [AI Configuration](./Configuration_AI.md)
Here you can choose a Task to be executed by the model and, subsequently, one of the models which implements the chosen task.
In addition, you can choose a set of parameters which allow restricting detections by specific threshold values or by number.
By default, inference results are visualized on the *lores* camera stream which is usually used for the Live View.
If you need this visualization also on photos and/or videos, you need to activate visualization on the *main* stream.
**NOTE** For Fotos and Videos, the [Stream Size](./Configuration.md#stream-size-width-height) for the *main* stream should be set to values similar to those of the *lores* stream.
The reson is that currently text sizes and line width of the visualization do not scale with the stream size.
## Enabling a Neural Network
Once the configuration is done, you can enable the selected network model in the [AI Configuration](./Configuration_AI.md#enable-ai) dialog.
Now, when the camera is started, the network model will be loaded onto the camera system.
This may take a while, depending on the platform used.
In order to avoid irritations about long camera startup times, **raspiCamSrv** shows an [animation](./UserGuide.md#live-stream-at-camera-start) when the camera is started until the first frame is delevered by the camera.
## Recommendations
The current implementation of imx500 AI support is initial and not all combinations of network models and other configuration settings have been tested.
The following recommendations may serve as a starting point for gaining experience with this subject.
### Configuration Settings
It is recommended setting the [Stream Size](./Configuration.md#stream-size-width-height) for *Photo* and *Video* to the same low value as for the *Live View* (e.g. **640 x 480**).
This assures better representation of inference results on photos and videos, if these are activated.
[Buffer Count](./Configuration.md#buffer-count) should be set to **12**, which is also used by the Picamera2 [demo implemetations](https://github.com/raspberrypi/picamera2/tree/main/examples/imx500)
### Neural Network Models
The following models have been successfully tested within **raspiCamSrv**
| Task | Model |
|------------------|-------------------------------------------------------|
| Classification | imx500_network_mobilenet_v2.rpk |
| Object Detection | imx500_network_ssd_mobilenetv2_fpnlite_320x320_pp.rpk |
| Pose Estimation | imx500_network_higherhrnet_coco.rpk |
| Segmentation | imx500_network_deeplabv3plus.rpk
### Parameter Settings
For performance reasons, you should enable *Draw Results on Stream main* only if needed for photos and videos.
If you do not see any results, you may need to:
- Decrease *Detection Threshold*
If performance is low, for example on a Raspberry Pi Zero, you may need to:
- Increase *Detection Threshold* in order to reduce the number of detections to be handled.
### Raspberry Models 4 and lower and Raspberry Pi Zero
For these models, the *lores* stream needs to be in YUV format according to te [Picamera2 Manual](https://pip-assets.raspberrypi.com/categories/652-raspberry-pi-camera-module-2/documents/RP-008156-DS-2-picamera2-manual.pdf) ch. 4.2.
The YUV format is not supported by all AI postprocessing pipelines.
It is, therefore, recommended using the following [Configuration](./Configuration.md) settingss for **all** use cases except *Raw Photo*, :
- Buffer Count: 12
- Sensor Mode: Custom
- Stream: main
- Stream Size: 640 x 480
- Stream Format: XBGR8888
For [AI Configuration](./Configuration_AI.md):
- Disable: *Draw Results on Stream lores*
- Enable: *Draw Results on Stream main*
### Case for Raspberry Pi Zero 2
The official case for the Raspberry Pi Zero models is not suitable for the AI Camera.
As alternatives, there are 3D-printed cases, e.g. [Case for Raspberry Pi Zero Models with Camera](https://makerworld.com/en/models/1804527-case-for-raspberry-pi-zero-models-with-camera):

## System Journal at Camera Startup
Before the camera is actually started, Picamera2 issues a message to stdout with a hint about long starting times:

Depending on whether a model is initially loaded or whether a previously loaded model is replaced, there will be kernel messages accompanying the loading process:

## Live Stream
Depending on the task of the neural network model, different types of visualizations will be used.
Resulting information is drawn on the individual frames in a pre_callback which is executed by Picamera2 before the frames are supplied to applications.
### Classification

With the *Classification* task, the neural network will identify individual classes out of a set of about 1000 classes (see [below](#classes))
When photos are taken, the Metadata include on the input and output tensors used by the neural network.
### Object Detection

With the *Object Detection* task, the neural network will track and frame individual objects out of a set of about 1000 classes (see [below](#classes))
### Segmentation

With the *Segmentation* task, the neural network will track and mask individual objects.
The implementation in **raspiCamSrv** differs from the [demo implementation](https://github.com/raspberrypi/picamera2/blob/main/examples/imx500/imx500_segmentation_demo.py), in which masks are burned on the GPU preview only.
These overlays are, therefore, not available in the *lores* and *main* streams used by **raspiCamSrv** for Live view and Photo/Video.
Since the inference rate of 19 of the neural network is significantly lower than the framerate (30), a larger part of frames is not processed by the neural network.
To avoid flickering, overlays are cached and the last overlay is used for frames which have bypassed AI processing.
As a consequence, when photos are taken, there will be photos for which the *Metadata* do not show tensor information, although a mask is visible on the photo.
## AI Camera as Second Camera
You can also use an AI camera as Second Camera or, on a Pi 5, you can work with two AI cameras.
[AI configuration](./Configuration_AI.md) is treated like any other [Camera Configuration](./Configuration.md).
This means that, in order to preserve any configuration changes for a camera switch, you need to apply the [Save Active Camera Settings for Camera Switch](./CamMulticam.md#save-active-camera-settings-for-camera-switch) button before you replace the active camera with another camera or before you switch cameras.
## Classes
The following classes are used in tasks *Classification* and *Object Detection*:
```
"classes": {
"labels": [
"0:background",
"1:tench, Tinca tinca",
"2:goldfish, Carassius auratus",
"3:great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias",
"4:tiger shark, Galeocerdo cuvieri",
"5:hammerhead, hammerhead shark",
"6:electric ray, crampfish, numbfish, torpedo",
"7:stingray",
"8:cock",
"9:hen",
"10:ostrich, Struthio camelus",
"11:brambling, Fringilla montifringilla",
"12:goldfinch, Carduelis carduelis",
"13:house finch, linnet, Carpodacus mexicanus",
"14:junco, snowbird",
"15:indigo bunting, indigo finch, indigo bird, Passerina cyanea",
"16:robin, American robin, Turdus migratorius",
"17:bulbul",
"18:jay",
"19:magpie",
"20:chickadee",
"21:water ouzel, dipper",
"22:kite",
"23:bald eagle, American eagle, Haliaeetus leucocephalus",
"24:vulture",
"25:great grey owl, great gray owl, Strix nebulosa",
"26:European fire salamander, Salamandra salamandra",
"27:common newt, Triturus vulgaris",
"28:eft",
"29:spotted salamander, Ambystoma maculatum",
"30:axolotl, mud puppy, Ambystoma mexicanum",
"31:bullfrog, Rana catesbeiana",
"32:tree frog, tree-frog",
"33:tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui",
"34:loggerhead, loggerhead turtle, Caretta caretta",
"35:leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea",
"36:mud turtle",
"37:terrapin",
"38:box turtle, box tortoise",
"39:banded gecko",
"40:common iguana, iguana, Iguana iguana",
"41:American chameleon, anole, Anolis carolinensis",
"42:whiptail, whiptail lizard",
"43:agama",
"44:frilled lizard, Chlamydosaurus kingi",
"45:alligator lizard",
"46:Gila monster, Heloderma suspectum",
"47:green lizard, Lacerta viridis",
"48:African chameleon, Chamaeleo chamaeleon",
"49:Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis",
"50:African crocodile, Nile crocodile, Crocodylus niloticus",
"51:American alligator, Alligator mississipiensis",
"52:triceratops",
"53:thunder snake, worm snake, Carphophis amoenus",
"54:ringneck snake, ring-necked snake, ring snake",
"55:hognose snake, puff adder, sand viper",
"56:green snake, grass snake",
"57:king snake, kingsnake",
"58:garter snake, grass snake",
"59:water snake",
"60:vine snake",
"61:night snake, Hypsiglena torquata",
"62:boa constrictor, Constrictor constrictor",
"63:rock python, rock snake, Python sebae",
"64:Indian cobra, Naja naja",
"65:green mamba",
"66:sea snake",
"67:horned viper, cerastes, sand viper, horned asp, Cerastes cornutus",
"68:diamondback, diamondback rattlesnake, Crotalus adamanteus",
"69:sidewinder, horned rattlesnake, Crotalus cerastes",
"70:trilobite",
"71:harvestman, daddy longlegs, Phalangium opilio",
"72:scorpion",
"73:black and gold garden spider, Argiope aurantia",
"74:barn spider, Araneus cavaticus",
"75:garden spider, Aranea diademata",
"76:black widow, Latrodectus mactans",
"77:tarantula",
"78:wolf spider, hunting spider",
"79:tick",
"80:centipede",
"81:black grouse",
"82:ptarmigan",
"83:ruffed grouse, partridge, Bonasa umbellus",
"84:prairie chicken, prairie grouse, prairie fowl",
"85:peacock",
"86:quail",
"87:partridge",
"88:African grey, African gray, Psittacus erithacus",
"89:macaw",
"90:sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita",
"91:lorikeet",
"92:coucal",
"93:bee eater",
"94:hornbill",
"95:hummingbird",
"96:jacamar",
"97:toucan",
"98:drake",
"99:red-breasted merganser, Mergus serrator",
"100:goose",
"101:black swan, Cygnus atratus",
"102:tusker",
"103:echidna, spiny anteater, anteater",
"104:platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus",
"105:wallaby, brush kangaroo",
"106:koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus",
"107:wombat",
"108:jellyfish",
"109:sea anemone, anemone",
"110:brain coral",
"111:flatworm, platyhelminth",
"112:nematode, nematode worm, roundworm",
"113:conch",
"114:snail",
"115:slug",
"116:sea slug, nudibranch",
"117:chiton, coat-of-mail shell, sea cradle, polyplacophore",
"118:chambered nautilus, pearly nautilus, nautilus",
"119:Dungeness crab, Cancer magister",
"120:rock crab, Cancer irroratus",
"121:fiddler crab",
"122:king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica",
"123:American lobster, Northern lobster, Maine lobster, Homarus americanus",
"124:spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish",
"125:crayfish, crawfish, crawdad, crawdaddy",
"126:hermit crab",
"127:isopod",
"128:white stork, Ciconia ciconia",
"129:black stork, Ciconia nigra",
"130:spoonbill",
"131:flamingo",
"132:little blue heron, Egretta caerulea",
"133:American egret, great white heron, Egretta albus",
"134:bittern",
"135:crane",
"136:limpkin, Aramus pictus",
"137:European gallinule, Porphyrio porphyrio",
"138:American coot, marsh hen, mud hen, water hen, Fulica americana",
"139:bustard",
"140:ruddy turnstone, Arenaria interpres",
"141:red-backed sandpiper, dunlin, Erolia alpina",
"142:redshank, Tringa totanus",
"143:dowitcher",
"144:oystercatcher, oyster catcher",
"145:pelican",
"146:king penguin, Aptenodytes patagonica",
"147:albatross, mollymawk",
"148:grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus",
"149:killer whale, killer, orca, grampus, sea wolf, Orcinus orca",
"150:dugong, Dugong dugon",
"151:sea lion",
"152:Chihuahua",
"153:Japanese spaniel",
"154:Maltese dog, Maltese terrier, Maltese",
"155:Pekinese, Pekingese, Peke",
"156:Shih-Tzu",
"157:Blenheim spaniel",
"158:papillon",
"159:toy terrier",
"160:Rhodesian ridgeback",
"161:Afghan hound, Afghan",
"162:basset, basset hound",
"163:beagle",
"164:bloodhound, sleuthhound",
"165:bluetick",
"166:black-and-tan coonhound",
"167:Walker hound, Walker foxhound",
"168:English foxhound",
"169:redbone",
"170:borzoi, Russian wolfhound",
"171:Irish wolfhound",
"172:Italian greyhound",
"173:whippet",
"174:Ibizan hound, Ibizan Podenco",
"175:Norwegian elkhound, elkhound",
"176:otterhound, otter hound",
"177:Saluki, gazelle hound",
"178:Scottish deerhound, deerhound",
"179:Weimaraner",
"180:Staffordshire bullterrier, Staffordshire bull terrier",
"181:American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier",
"182:Bedlington terrier",
"183:Border terrier",
"184:Kerry blue terrier",
"185:Irish terrier",
"186:Norfolk terrier",
"187:Norwich terrier",
"188:Yorkshire terrier",
"189:wire-haired fox terrier",
"190:Lakeland terrier",
"191:Sealyham terrier, Sealyham",
"192:Airedale, Airedale terrier",
"193:cairn, cairn terrier",
"194:Australian terrier",
"195:Dandie Dinmont, Dandie Dinmont terrier",
"196:Boston bull, Boston terrier",
"197:miniature schnauzer",
"198:giant schnauzer",
"199:standard schnauzer",
"200:Scotch terrier, Scottish terrier, Scottie",
"201:Tibetan terrier, chrysanthemum dog",
"202:silky terrier, Sydney silky",
"203:soft-coated wheaten terrier",
"204:West Highland white terrier",
"205:Lhasa, Lhasa apso",
"206:flat-coated retriever",
"207:curly-coated retriever",
"208:golden retriever",
"209:Labrador retriever",
"210:Chesapeake Bay retriever",
"211:German short-haired pointer",
"212:vizsla, Hungarian pointer",
"213:English setter",
"214:Irish setter, red setter",
"215:Gordon setter",
"216:Brittany spaniel",
"217:clumber, clumber spaniel",
"218:English springer, English springer spaniel",
"219:Welsh springer spaniel",
"220:cocker spaniel, English cocker spaniel, cocker",
"221:Sussex spaniel",
"222:Irish water spaniel",
"223:kuvasz",
"224:schipperke",
"225:groenendael",
"226:malinois",
"227:briard",
"228:kelpie",
"229:komondor",
"230:Old English sheepdog, bobtail",
"231:Shetland sheepdog, Shetland sheep dog, Shetland",
"232:collie",
"233:Border collie",
"234:Bouvier des Flandres, Bouviers des Flandres",
"235:Rottweiler",
"236:German shepherd, German shepherd dog, German police dog, alsatian",
"237:Doberman, Doberman pinscher",
"238:miniature pinscher",
"239:Greater Swiss Mountain dog",
"240:Bernese mountain dog",
"241:Appenzeller",
"242:EntleBucher",
"243:boxer",
"244:bull mastiff",
"245:Tibetan mastiff",
"246:French bulldog",
"247:Great Dane",
"248:Saint Bernard, St Bernard",
"249:Eskimo dog, husky",
"250:malamute, malemute, Alaskan malamute",
"251:Siberian husky",
"252:dalmatian, coach dog, carriage dog",
"253:affenpinscher, monkey pinscher, monkey dog",
"254:basenji",
"255:pug, pug-dog",
"256:Leonberg",
"257:Newfoundland, Newfoundland dog",
"258:Great Pyrenees",
"259:Samoyed, Samoyede",
"260:Pomeranian",
"261:chow, chow chow",
"262:keeshond",
"263:Brabancon griffon",
"264:Pembroke, Pembroke Welsh corgi",
"265:Cardigan, Cardigan Welsh corgi",
"266:toy poodle",
"267:miniature poodle",
"268:standard poodle",
"269:Mexican hairless",
"270:timber wolf, grey wolf, gray wolf, Canis lupus",
"271:white wolf, Arctic wolf, Canis lupus tundrarum",
"272:red wolf, maned wolf, Canis rufus, Canis niger",
"273:coyote, prairie wolf, brush wolf, Canis latrans",
"274:dingo, warrigal, warragal, Canis dingo",
"275:dhole, Cuon alpinus",
"276:African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus",
"277:hyena, hyaena",
"278:red fox, Vulpes vulpes",
"279:kit fox, Vulpes macrotis",
"280:Arctic fox, white fox, Alopex lagopus",
"281:grey fox, gray fox, Urocyon cinereoargenteus",
"282:tabby, tabby cat",
"283:tiger cat",
"284:Persian cat",
"285:Siamese cat, Siamese",
"286:Egyptian cat",
"287:cougar, puma, catamount, mountain lion, painter, panther, Felis concolor",
"288:lynx, catamount",
"289:leopard, Panthera pardus",
"290:snow leopard, ounce, Panthera uncia",
"291:jaguar, panther, Panthera onca, Felis onca",
"292:lion, king of beasts, Panthera leo",
"293:tiger, Panthera tigris",
"294:cheetah, chetah, Acinonyx jubatus",
"295:brown bear, bruin, Ursus arctos",
"296:American black bear, black bear, Ursus americanus, Euarctos americanus",
"297:ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus",
"298:sloth bear, Melursus ursinus, Ursus ursinus",
"299:mongoose",
"300:meerkat, mierkat",
"301:tiger beetle",
"302:ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle",
"303:ground beetle, carabid beetle",
"304:long-horned beetle, longicorn, longicorn beetle",
"305:leaf beetle, chrysomelid",
"306:dung beetle",
"307:rhinoceros beetle",
"308:weevil",
"309:fly",
"310:bee",
"311:ant, emmet, pismire",
"312:grasshopper, hopper",
"313:cricket",
"314:walking stick, walkingstick, stick insect",
"315:cockroach, roach",
"316:mantis, mantid",
"317:cicada, cicala",
"318:leafhopper",
"319:lacewing, lacewing fly",
"320:dragonfly, darning needle, devil's darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk",
"321:damselfly",
"322:admiral",
"323:ringlet, ringlet butterfly",
"324:monarch, monarch butterfly, milkweed butterfly, Danaus plexippus",
"325:cabbage butterfly",
"326:sulphur butterfly, sulfur butterfly",
"327:lycaenid, lycaenid butterfly",
"328:starfish, sea star",
"329:sea urchin",
"330:sea cucumber, holothurian",
"331:wood rabbit, cottontail, cottontail rabbit",
"332:hare",
"333:Angora, Angora rabbit",
"334:hamster",
"335:porcupine, hedgehog",
"336:fox squirrel, eastern fox squirrel, Sciurus niger",
"337:marmot",
"338:beaver",
"339:guinea pig, Cavia cobaya",
"340:sorrel",
"341:zebra",
"342:hog, pig, grunter, squealer, Sus scrofa",
"343:wild boar, boar, Sus scrofa",
"344:warthog",
"345:hippopotamus, hippo, river horse, Hippopotamus amphibius",
"346:ox",
"347:water buffalo, water ox, Asiatic buffalo, Bubalus bubalis",
"348:bison",
"349:ram, tup",
"350:bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis",
"351:ibex, Capra ibex",
"352:hartebeest",
"353:impala, Aepyceros melampus",
"354:gazelle",
"355:Arabian camel, dromedary, Camelus dromedarius",
"356:llama",
"357:weasel",
"358:mink",
"359:polecat, fitch, foulmart, foumart, Mustela putorius",
"360:black-footed ferret, ferret, Mustela nigripes",
"361:otter",
"362:skunk, polecat, wood pussy",
"363:badger",
"364:armadillo",
"365:three-toed sloth, ai, Bradypus tridactylus",
"366:orangutan, orang, orangutang, Pongo pygmaeus",
"367:gorilla, Gorilla gorilla",
"368:chimpanzee, chimp, Pan troglodytes",
"369:gibbon, Hylobates lar",
"370:siamang, Hylobates syndactylus, Symphalangus syndactylus",
"371:guenon, guenon monkey",
"372:patas, hussar monkey, Erythrocebus patas",
"373:baboon",
"374:macaque",
"375:langur",
"376:colobus, colobus monkey",
"377:proboscis monkey, Nasalis larvatus",
"378:marmoset",
"379:capuchin, ringtail, Cebus capucinus",
"380:howler monkey, howler",
"381:titi, titi monkey",
"382:spider monkey, Ateles geoffroyi",
"383:squirrel monkey, Saimiri sciureus",
"384:Madagascar cat, ring-tailed lemur, Lemur catta",
"385:indri, indris, Indri indri, Indri brevicaudatus",
"386:Indian elephant, Elephas maximus",
"387:African elephant, Loxodonta africana",
"388:lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens",
"389:giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca",
"390:barracouta, snoek",
"391:eel",
"392:coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch",
"393:rock beauty, Holocanthus tricolor",
"394:anemone fish",
"395:sturgeon",
"396:gar, garfish, garpike, billfish, Lepisosteus osseus",
"397:lionfish",
"398:puffer, pufferfish, blowfish, globefish",
"399:abacus",
"400:abaya",
"401:academic gown, academic robe, judge's robe",
"402:accordion, piano accordion, squeeze box",
"403:acoustic guitar",
"404:aircraft carrier, carrier, flattop, attack aircraft carrier",
"405:airliner",
"406:airship, dirigible",
"407:altar",
"408:ambulance",
"409:amphibian, amphibious vehicle",
"410:analog clock",
"411:apiary, bee house",
"412:apron",
"413:ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin",
"414:assault rifle, assault gun",
"415:backpack, back pack, knapsack, packsack, rucksack, haversack",
"416:bakery, bakeshop, bakehouse",
"417:balance beam, beam",
"418:balloon",
"419:ballpoint, ballpoint pen, ballpen, Biro",
"420:Band Aid",
"421:banjo",
"422:bannister, banister, balustrade, balusters, handrail",
"423:barbell",
"424:barber chair",
"425:barbershop",
"426:barn",
"427:barometer",
"428:barrel, cask",
"429:barrow, garden cart, lawn cart, wheelbarrow",
"430:baseball",
"431:basketball",
"432:bassinet",
"433:bassoon",
"434:bathing cap, swimming cap",
"435:bath towel",
"436:bathtub, bathing tub, bath, tub",
"437:beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon",
"438:beacon, lighthouse, beacon light, pharos",
"439:beaker",
"440:bearskin, busby, shako",
"441:beer bottle",
"442:beer glass",
"443:bell cote, bell cot",
"444:bib",
"445:bicycle-built-for-two, tandem bicycle, tandem",
"446:bikini, two-piece",
"447:binder, ring-binder",
"448:binoculars, field glasses, opera glasses",
"449:birdhouse",
"450:boathouse",
"451:bobsled, bobsleigh, bob",
"452:bolo tie, bolo, bola tie, bola",
"453:bonnet, poke bonnet",
"454:bookcase",
"455:bookshop, bookstore, bookstall",
"456:bottlecap",
"457:bow",
"458:bow tie, bow-tie, bowtie",
"459:brass, memorial tablet, plaque",
"460:brassiere, bra, bandeau",
"461:breakwater, groin, groyne, mole, bulwark, seawall, jetty",
"462:breastplate, aegis, egis",
"463:broom",
"464:bucket, pail",
"465:buckle",
"466:bulletproof vest",
"467:bullet train, bullet",
"468:butcher shop, meat market",
"469:cab, hack, taxi, taxicab",
"470:caldron, cauldron",
"471:candle, taper, wax light",
"472:cannon",
"473:canoe",
"474:can opener, tin opener",
"475:cardigan",
"476:car mirror",
"477:carousel, carrousel, merry-go-round, roundabout, whirligig",
"478:carpenter's kit, tool kit",
"479:carton",
"480:car wheel",
"481:cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM",
"482:cassette",
"483:cassette player",
"484:castle",
"485:catamaran",
"486:CD player",
"487:cello, violoncello",
"488:cellular telephone, cellular phone, cellphone, cell, mobile phone",
"489:chain",
"490:chainlink fence",
"491:chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour",
"492:chain saw, chainsaw",
"493:chest",
"494:chiffonier, commode",
"495:chime, bell, gong",
"496:china cabinet, china closet",
"497:Christmas stocking",
"498:church, church building",
"499:cinema, movie theater, movie theatre, movie house, picture palace",
"500:cleaver, meat cleaver, chopper",
"501:cliff dwelling",
"502:cloak",
"503:clog, geta, patten, sabot",
"504:cocktail shaker",
"505:coffee mug",
"506:coffeepot",
"507:coil, spiral, volute, whorl, helix",
"508:combination lock",
"509:computer keyboard, keypad",
"510:confectionery, confectionary, candy store",
"511:container ship, containership, container vessel",
"512:convertible",
"513:corkscrew, bottle screw",
"514:cornet, horn, trumpet, trump",
"515:cowboy boot",
"516:cowboy hat, ten-gallon hat",
"517:cradle",
"518:crane",
"519:crash helmet",
"520:crate",
"521:crib, cot",
"522:Crock Pot",
"523:croquet ball",
"524:crutch",
"525:cuirass",
"526:dam, dike, dyke",
"527:desk",
"528:desktop computer",
"529:dial telephone, dial phone",
"530:diaper, nappy, napkin",
"531:digital clock",
"532:digital watch",
"533:dining table, board",
"534:dishrag, dishcloth",
"535:dishwasher, dish washer, dishwashing machine",
"536:disk brake, disc brake",
"537:dock, dockage, docking facility",
"538:dogsled, dog sled, dog sleigh",
"539:dome",
"540:doormat, welcome mat",
"541:drilling platform, offshore rig",
"542:drum, membranophone, tympan",
"543:drumstick",
"544:dumbbell",
"545:Dutch oven",
"546:electric fan, blower",
"547:electric guitar",
"548:electric locomotive",
"549:entertainment center",
"550:envelope",
"551:espresso maker",
"552:face powder",
"553:feather boa, boa",
"554:file, file cabinet, filing cabinet",
"555:fireboat",
"556:fire engine, fire truck",
"557:fire screen, fireguard",
"558:flagpole, flagstaff",
"559:flute, transverse flute",
"560:folding chair",
"561:football helmet",
"562:forklift",
"563:fountain",
"564:fountain pen",
"565:four-poster",
"566:freight car",
"567:French horn, horn",
"568:frying pan, frypan, skillet",
"569:fur coat",
"570:garbage truck, dustcart",
"571:gasmask, respirator, gas helmet",
"572:gas pump, gasoline pump, petrol pump, island dispenser",
"573:goblet",
"574:go-kart",
"575:golf ball",
"576:golfcart, golf cart",
"577:gondola",
"578:gong, tam-tam",
"579:gown",
"580:grand piano, grand",
"581:greenhouse, nursery, glasshouse",
"582:grille, radiator grille",
"583:grocery store, grocery, food market, market",
"584:guillotine",
"585:hair slide",
"586:hair spray",
"587:half track",
"588:hammer",
"589:hamper",
"590:hand blower, blow dryer, blow drier, hair dryer, hair drier",
"591:hand-held computer, hand-held microcomputer",
"592:handkerchief, hankie, hanky, hankey",
"593:hard disc, hard disk, fixed disk",
"594:harmonica, mouth organ, harp, mouth harp",
"595:harp",
"596:harvester, reaper",
"597:hatchet",
"598:holster",
"599:home theater, home theatre",
"600:honeycomb",
"601:hook, claw",
"602:hoopskirt, crinoline",
"603:horizontal bar, high bar",
"604:horse cart, horse-cart",
"605:hourglass",
"606:iPod",
"607:iron, smoothing iron",
"608:jack-o'-lantern",
"609:jean, blue jean, denim",
"610:jeep, landrover",
"611:jersey, T-shirt, tee shirt",
"612:jigsaw puzzle",
"613:jinrikisha, ricksha, rickshaw",
"614:joystick",
"615:kimono",
"616:knee pad",
"617:knot",
"618:lab coat, laboratory coat",
"619:ladle",
"620:lampshade, lamp shade",
"621:laptop, laptop computer",
"622:lawn mower, mower",
"623:lens cap, lens cover",
"624:letter opener, paper knife, paperknife",
"625:library",
"626:lifeboat",
"627:lighter, light, igniter, ignitor",
"628:limousine, limo",
"629:liner, ocean liner",
"630:lipstick, lip rouge",
"631:Loafer",
"632:lotion",
"633:loudspeaker, speaker, speaker unit, loudspeaker system, speaker system",
"634:loupe, jeweler's loupe",
"635:lumbermill, sawmill",
"636:magnetic compass",
"637:mailbag, postbag",
"638:mailbox, letter box",
"639:maillot",
"640:maillot, tank suit",
"641:manhole cover",
"642:maraca",
"643:marimba, xylophone",
"644:mask",
"645:matchstick",
"646:maypole",
"647:maze, labyrinth",
"648:measuring cup",
"649:medicine chest, medicine cabinet",
"650:megalith, megalithic structure",
"651:microphone, mike",
"652:microwave, microwave oven",
"653:military uniform",
"654:milk can",
"655:minibus",
"656:miniskirt, mini",
"657:minivan",
"658:missile",
"659:mitten",
"660:mixing bowl",
"661:mobile home, manufactured home",
"662:Model T",
"663:modem",
"664:monastery",
"665:monitor",
"666:moped",
"667:mortar",
"668:mortarboard",
"669:mosque",
"670:mosquito net",
"671:motor scooter, scooter",
"672:mountain bike, all-terrain bike, off-roader",
"673:mountain tent",
"674:mouse, computer mouse",
"675:mousetrap",
"676:moving van",
"677:muzzle",
"678:nail",
"679:neck brace",
"680:necklace",
"681:nipple",
"682:notebook, notebook computer",
"683:obelisk",
"684:oboe, hautboy, hautbois",
"685:ocarina, sweet potato",
"686:odometer, hodometer, mileometer, milometer",
"687:oil filter",
"688:organ, pipe organ",
"689:oscilloscope, scope, cathode-ray oscilloscope, CRO",
"690:overskirt",
"691:oxcart",
"692:oxygen mask",
"693:packet",
"694:paddle, boat paddle",
"695:paddlewheel, paddle wheel",
"696:padlock",
"697:paintbrush",
"698:pajama, pyjama, pj's, jammies",
"699:palace",
"700:panpipe, pandean pipe, syrinx",
"701:paper towel",
"702:parachute, chute",
"703:parallel bars, bars",
"704:park bench",
"705:parking meter",
"706:passenger car, coach, carriage",
"707:patio, terrace",
"708:pay-phone, pay-station",
"709:pedestal, plinth, footstall",
"710:pencil box, pencil case",
"711:pencil sharpener",
"712:perfume, essence",
"713:Petri dish",
"714:photocopier",
"715:pick, plectrum, plectron",
"716:pickelhaube",
"717:picket fence, paling",
"718:pickup, pickup truck",
"719:pier",
"720:piggy bank, penny bank",
"721:pill bottle",
"722:pillow",
"723:ping-pong ball",
"724:pinwheel",
"725:pirate, pirate ship",
"726:pitcher, ewer",
"727:plane, carpenter's plane, woodworking plane",
"728:planetarium",
"729:plastic bag",
"730:plate rack",
"731:plow, plough",
"732:plunger, plumber's helper",
"733:Polaroid camera, Polaroid Land camera",
"734:pole",
"735:police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria",
"736:poncho",
"737:pool table, billiard table, snooker table",
"738:pop bottle, soda bottle",
"739:pot, flowerpot",
"740:potter's wheel",
"741:power drill",
"742:prayer rug, prayer mat",
"743:printer",
"744:prison, prison house",
"745:projectile, missile",
"746:projector",
"747:puck, hockey puck",
"748:punching bag, punch bag, punching ball, punchball",
"749:purse",
"750:quill, quill pen",
"751:quilt, comforter, comfort, puff",
"752:racer, race car, racing car",
"753:racket, racquet",
"754:radiator",
"755:radio, wireless",
"756:radio telescope, radio reflector",
"757:rain barrel",
"758:recreational vehicle, RV, R.V.",
"759:reel",
"760:reflex camera",
"761:refrigerator, icebox",
"762:remote control, remote",
"763:restaurant, eating house, eating place, eatery",
"764:revolver, six-gun, six-shooter",
"765:rifle",
"766:rocking chair, rocker",
"767:rotisserie",
"768:rubber eraser, rubber, pencil eraser",
"769:rugby ball",
"770:rule, ruler",
"771:running shoe",
"772:safe",
"773:safety pin",
"774:saltshaker, salt shaker",
"775:sandal",
"776:sarong",
"777:sax, saxophone",
"778:scabbard",
"779:scale, weighing machine",
"780:school bus",
"781:schooner",
"782:scoreboard",
"783:screen, CRT screen",
"784:screw",
"785:screwdriver",
"786:seat belt, seatbelt",
"787:sewing machine",
"788:shield, buckler",
"789:shoe shop, shoe-shop, shoe store",
"790:shoji",
"791:shopping basket",
"792:shopping cart",
"793:shovel",
"794:shower cap",
"795:shower curtain",
"796:ski",
"797:ski mask",
"798:sleeping bag",
"799:slide rule, slipstick",
"800:sliding door",
"801:slot, one-armed bandit",
"802:snorkel",
"803:snowmobile",
"804:snowplow, snowplough",
"805:soap dispenser",
"806:soccer ball",
"807:sock",
"808:solar dish, solar collector, solar furnace",
"809:sombrero",
"810:soup bowl",
"811:space bar",
"812:space heater",
"813:space shuttle",
"814:spatula",
"815:speedboat",
"816:spider web, spider's web",
"817:spindle",
"818:sports car, sport car",
"819:spotlight, spot",
"820:stage",
"821:steam locomotive",
"822:steel arch bridge",
"823:steel drum",
"824:stethoscope",
"825:stole",
"826:stone wall",
"827:stopwatch, stop watch",
"828:stove",
"829:strainer",
"830:streetcar, tram, tramcar, trolley, trolley car",
"831:stretcher",
"832:studio couch, day bed",
"833:stupa, tope",
"834:submarine, pigboat, sub, U-boat",
"835:suit, suit of clothes",
"836:sundial",
"837:sunglass",
"838:sunglasses, dark glasses, shades",
"839:sunscreen, sunblock, sun blocker",
"840:suspension bridge",
"841:swab, swob, mop",
"842:sweatshirt",
"843:swimming trunks, bathing trunks",
"844:swing",
"845:switch, electric switch, electrical switch",
"846:syringe",
"847:table lamp",
"848:tank, army tank, armored combat vehicle, armoured combat vehicle",
"849:tape player",
"850:teapot",
"851:teddy, teddy bear",
"852:television, television system",
"853:tennis ball",
"854:thatch, thatched roof",
"855:theater curtain, theatre curtain",
"856:thimble",
"857:thresher, thrasher, threshing machine",
"858:throne",
"859:tile roof",
"860:toaster",
"861:tobacco shop, tobacconist shop, tobacconist",
"862:toilet seat",
"863:torch",
"864:totem pole",
"865:tow truck, tow car, wrecker",
"866:toyshop",
"867:tractor",
"868:trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi",
"869:tray",
"870:trench coat",
"871:tricycle, trike, velocipede",
"872:trimaran",
"873:tripod",
"874:triumphal arch",
"875:trolleybus, trolley coach, trackless trolley",
"876:trombone",
"877:tub, vat",
"878:turnstile",
"879:typewriter keyboard",
"880:umbrella",
"881:unicycle, monocycle",
"882:upright, upright piano",
"883:vacuum, vacuum cleaner",
"884:vase",
"885:vault",
"886:velvet",
"887:vending machine",
"888:vestment",
"889:viaduct",
"890:violin, fiddle",
"891:volleyball",
"892:waffle iron",
"893:wall clock",
"894:wallet, billfold, notecase, pocketbook",
"895:wardrobe, closet, press",
"896:warplane, military plane",
"897:washbasin, handbasin, washbowl, lavabo, wash-hand basin",
"898:washer, automatic washer, washing machine",
"899:water bottle",
"900:water jug",
"901:water tower",
"902:whiskey jug",
"903:whistle",
"904:wig",
"905:window screen",
"906:window shade",
"907:Windsor tie",
"908:wine bottle",
"909:wing",
"910:wok",
"911:wooden spoon",
"912:wool, woolen, woollen",
"913:worm fence, snake fence, snake-rail fence, Virginia fence",
"914:wreck",
"915:yawl",
"916:yurt",
"917:web site, website, internet site, site",
"918:comic book",
"919:crossword puzzle, crossword",
"920:street sign",
"921:traffic light, traffic signal, stoplight",
"922:book jacket, dust cover, dust jacket, dust wrapper",
"923:menu",
"924:plate",
"925:guacamole",
"926:consomme",
"927:hot pot, hotpot",
"928:trifle",
"929:ice cream, icecream",
"930:ice lolly, lolly, lollipop, popsicle",
"931:French loaf",
"932:bagel, beigel",
"933:pretzel",
"934:cheeseburger",
"935:hotdog, hot dog, red hot",
"936:mashed potato",
"937:head cabbage",
"938:broccoli",
"939:cauliflower",
"940:zucchini, courgette",
"941:spaghetti squash",
"942:acorn squash",
"943:butternut squash",
"944:cucumber, cuke",
"945:artichoke, globe artichoke",
"946:bell pepper",
"947:cardoon",
"948:mushroom",
"949:Granny Smith",
"950:strawberry",
"951:orange",
"952:lemon",
"953:fig",
"954:pineapple, ananas",
"955:banana",
"956:jackfruit, jak, jack",
"957:custard apple",
"958:pomegranate",
"959:hay",
"960:carbonara",
"961:chocolate sauce, chocolate syrup",
"962:dough",
"963:meat loaf, meatloaf",
"964:pizza, pizza pie",
"965:potpie",
"966:burrito",
"967:red wine",
"968:espresso",
"969:cup",
"970:eggnog",
"971:alp",
"972:bubble",
"973:cliff, drop, drop-off",
"974:coral reef",
"975:geyser",
"976:lakeside, lakeshore",
"977:promontory, headland, head, foreland",
"978:sandbar, sand bar",
"979:seashore, coast, seacoast, sea-coast",
"980:valley, vale",
"981:volcano",
"982:ballplayer, baseball player",
"983:groom, bridegroom",
"984:scuba diver",
"985:rapeseed",
"986:daisy",
"987:yellow lady's slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum",
"988:corn",
"989:acorn",
"990:hip, rose hip, rosehip",
"991:buckeye, horse chestnut, conker",
"992:coral fungus",
"993:agaric",
"994:gyromitra",
"995:stinkhorn, carrion fungus",
"996:earthstar",
"997:hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa",
"998:bolete",
"999:ear, spike, capitulum",
"1000:toilet tissue, toilet paper, bathroom tissue"
]
}
```
================================================
FILE: docs/Authentication.md
================================================
# raspiCamSrv Authorization
[](./UserGuide.md)
Access to the raspiCamSrv server requires login with Username and Password.
A user session will live as long as the browser remains open, even if the tab with a **raspiCamSrv** dialog has been closed.
The basic principle is that the first user in the system will be automatically registered as SuperUser.
Only the SuperUser will be able to register new users or remove users from the system.
After the database has been initialized with ```flask --app raspiCamSrv init-db``` (see [RaspiCamSrv Installation](./installation.md)) Step 11), there is no user in the database.
In this situation, any connect to the server will open the *Register* screen:

Now, the SuperUser can complete his registration and will then be redirected to the *Log In* screen:

From now on, the *Register* screen will no longer be available through the menu.
Also, direct access through the *Register* screen URL will only be allowed for the SuperUser. Other users will be redirected to the *Live* screen.
## User Management
For management of users, the *Settings* screen has an additional section *Users* which is visible only for the SuperUser:

The list shows all registered users with
- unique user *ID*
- user *Name*
- *Initial*, indicating whether the user has been initially created by the SuperUser and needs to change password on first log-in.
- *SuperUser*, indicating the user registered as SuperUser
The SuperUser can
- register new users using the *Register New User* button
- remove users which have been selected in the list
## Password
Users with flag "Initial" will automatically be requested to change their password when they log in for the first time.
All users can change their password before they are logged in.

After the password has been successfully changed, the *Log In* screen will be opened.
## Old User Schema
The functionality described above is available for systems installed after Feb. 15, 2024.
Systems installed before but updated (git pull) later, still work with the old user schema.
In this case, all users are considered SuperUsers.
The [User Management](#user-management) functionality in the *Settings* screen will be available for all users.
However, a hint is shown to update the database schema:

================================================
FILE: docs/Background Processes.md
================================================
# raspiCamSrv Tasks and Background Processes
[](./UserGuide.md)
The figure below gives an overview of the different tasks available in **raspiCamSrv** and their relation to **raspiCamSrv** [Configurations](./Configuration.md) and camera strams.
For more information on the components, see the [Picamera2 manual](./picamera2-manual.pdf), chapter 4.2.

The tasks marked in green are executed in background processes (Threads) and may run simultaneously.
The status of each of these processes is indicated with [status indicators](./UserGuide.md#process-status-indicators):

## Default Configuration
The association between **raspiCamSrv** [Configurations](./Configuration.md) and camera streams shown in the figure above, is the default configuration.
In addition, default values for other configuration parameters are harmonized in such a way that all background processes can run simultaneously.
This is especially important for the live stream which will remain active while a video is recorded, while photos are taken or while a Photo Series is executed.
**raspiCamSrv** merges the different configurations to a single one which is applied when the camera is started.
This requires that the following configuration parameters must have the same values for the different configurations:
- *Transform*
- *Colour Space*
- *Queue*
The values for *Buffer Count* can be different. In the merge process, the largest number of buffers will be selected.
## Configuration Changes
All configuration scan be changed, including the association between configuration and camera stream (except raw).
If a configuration change, for example Transform, is made for a single configuration, for example *Video*, it is no longer possible to use a common configuration for all tasks.
If then, for example, a video is recorded, the video thread needs to run in exclusive mode because it cannot share configuration with the Live Stream. For this purpose:
1. The Live Stream must be stopped and paused during video recording
2. The Encoder for the Live Stream must be stopped
3. The camera must be stopped
4. The camera must be configured with the Video configuration
5. The camera must be started
6. The encoder for video must be started while the video is being recorded
7. The encoder must be stopped when video recording is finished
8. The camera must be stopped
9. The camera must be configured for the LiveStream, including eventally compatible configurations
10. The camera must be started
11. The MJPEG encoder for Live Stream must be started
12. The Live Stream Thread must be started
In case of harmonized configurations, only steps 7 and 8 would have been required.
================================================
FILE: docs/Cam.md
================================================
# Cam - Camera Usage
[](./UserGuide.md)

This menu gives access to the available high-level camera usage scenarios, in particular in the case of multiple cameras connected to a Raspberry Pi (currently only Pi 5 can connect two CSI cameras).
When connecting USB cameras, in addition to CSI cameras, you can in principle, get access to as many cameras as you can connect. However, raspiCamSrv can only operate up to 2 cameras simultaneusly.
So, you will need to select which of the connected cameras (see [Info/Cameras](./Information_Cam.md)) shall be used as *Active Camera* and as *Second Camera*.
- The [Web Cam](./CamWebcam.md) dialog demonstrates how to stream video or image from your cameras.
- The [Multi-Cam](./CamMulticam.md) dialog allows controlling both cameras individually or synchronously.
(This dialog is only available for multi-camera systems)
- The [Camera Calibration](./CamCalibration.md) dialog can be used for calibration and rectification of stereo cameras.
(This dialog is only available if *Stereo Vision* is activated in the [Settings](./Settings.md#activating-and-deactivating-stereo-vision) dialog)
- The [Stereo-Cam](./CamStereo.md) dialog can be used for visualization of depth maps as well as for viewing and recording of 3D videos.
(This dialog is only available if *Stereo Vision* is activated in the [Settings](./Settings.md#activating-and-deactivating-stereo-vision))
================================================
FILE: docs/CamCalibration.md
================================================
# Camera Calibration
[](./Cam.md)
This dialog allows calibration of the [stereo camera system](./CamStereo.md#stereo-camera) in order to improve the quality of the stereo result.
**NOTE**:The dialog is only accessible if [Stereo Vision](./Settings.md#activating-and-deactivating-stereo-vision) has been activated.
**REMINDER**: When finished with calibration you will need to [Store Configuration](./Settings.md#configuration) in order to preserve the results over a server restart.

When opened without existing calibration data, the dialog allows configuring the calibration process:
- *Calibration Pattern* allows selecting the pattern to be used for calibration.
Currently, only the [Chessboard pattern from OpenCV](https://github.com/opencv/opencv/blob/4.x/doc/pattern.png) is supported.
This pattern needs to be printed or displayed on a tablet for being used during the calibration process.
- *Pattern Size* specifies the number of columns and rows of identifiable vertices of the pattern. 9x6 is appropriate for the standard chessboard pattern. (Only the inner vertices count)
- In *Number of Photos required* you can specify how many photos you want to use for calibration.
The dialog allows selecting as few as 5 photos but this is only to see how quality decreases with the number of photos. 20-30 will be a better choice.
- *Number of Photos taken* will show the current number of photos.
- *Rectify Scale* is a parameter used during rectification.
"Valid Pixels Only" will include only valid pixels in the final result and will remove black areas.
"All Pixels" will include all pixels in the final result of transformed images.
## Picture Taking
The process of photo taking is automatic:
When the pattern is presented to the cameras so that it is fully visible in both cameras, the system will try to find the specified number of corners.
Only if this is successful, the image will be stored.
After 2 seconds, the next pair of images will be analyzed until sufficient photos have been taken.
The process is started with button **Start taking Pattern Photos** which will request a confirmation:

and signal readiness to take a photo:

Now you need to bring the pattern in the visible area and slowly change its orientation and position within the image areas.

If not all required corners could be found at the current position, this will be indicated:

## Picture Review
After all required pictures have been taken, camera streaming stops and the stored pictures are presented for being reviewed:

A navigation bar is shown which allows scrolling through the taken images.
Images with bad quality can be removed.
*Show Corners* will present images where the found corners are shown:

If photos have been removed, the missing ones need to be filled up using button "Continue taking Pattern Photos"

Button **Reset Calibration Photos** will remove all photos and reset the calibration process after a confirmation.
## Calibration
When the required number of photos have been taken, you can continue with calibration.

Display of the time of calibration as well as the *RMS Re-Projection Error* indicate that valid calibration data are available.
The color with which the error is shown, (green, yellow, red) indicates the quality of the calibration:
- < 0.5 px : excellent
- 0.5 - 1 px : acceptable
- > 1 px : poor
## Calibration Data Storage
Calibration photos (with and without corners) are stored underneath the ```raspiCamSrv/static``` folder:

================================================
FILE: docs/CamMulticam.md
================================================
# Multi-Camera Control
[](./Cam.md)
**NOTE**: This dialog is only available for systems with two or more CSI or USB cameras connected (see [Info](./Information.md)).
**raspiCamSrv** can simultaneously operate two cameras: the *Active Camera* and the *Second Camera*.
If more cameras are connected and available (usually USB cameras), *Active* and *Second* Camera must be selected out of these.
While live streams for both cameras are shown, this dialog allows photo taking and video recording either individually with each of the two cameras or simultaneously with both.

The left side of the page always shows the active camera.
The screenshot, above, shows a configuration with four available cameras.
If more than two cameras are available, the stream titles are dropdown lists from which you can select *Active* or *Second Camera*.
In every case, the other camera is not selectable because one camera cannot have two roles.
If there are just two cameras available, the drop-down lists are replaced by normal text.
When switching the cameras, either with the **Switch Cameras** button on this side or by changing the camera in the [Settings](./Settings.md#switching-the-active-camera), the streams will be exchanged.
### Buttons
#### Photo / Raw / Video
Every camera has an own set of action buttons which apply only to this camera.
Their function is identical to that of the corresponding [buttons on the Live screen](./Phototaking.md)
The resulting photos or place holders will not be shown on this page.
They are stored in camera-specific subfolders and are accessible through the [Photos](./PhotoViewer.md) dialog
For the active camera, the last photo or placeholder is shown in the [Photo Display of the Live screen](./Phototaking.md#photo-display) and can be added to the display buffer for inspection of meta data or histogram..
#### Photo - Both / Raw - Both / Video - Both
When these buttons are pressed, the respective function is applied for both cameras.
The media files will have the same name for both cameras, which is generated from the timestamp of command execution, but are stored in their camera-specific subfolder.
This allows identifying photos which have been synchronously taken and videos which have been synchronously started.
**NOTE**: Currently, the actions on both cameras are executed sequentially, so that there may be a small subsecond delay.
#### Save Active Camera Settings for Camera Switch
This button stores the current [Camera Configuration](./Configuration.md) for all configurations as well as the current [Controls](./CameraControls.md) settings for the active camera in a specific structure (streamingCfg) so that it can be reused for streaming in a case that the other camera has been activated.
In addition, also the camera-related settings of [Trigger](./Trigger.md) ([Trigger/Motion](./TriggerMotion.md) and [Trigger/Camera](./TriggerCameraActions.md)) will be stored in the streamingCfg.
(See also [Configuring MJPEG Stream and jpeg Photo](#configuring-mjpeg-stream-and-jpeg-photo))
#### Synchronize Configurations
This button is disabled if the two cameras are of different model.
If they are the same model, the button can be used to transfer the configuration, controls and camera-related Trigger settings from the active camera to the second camera. This is especially useful in the case of [Stereo Vision](./CamStereo.md) where both cameras should be operated with identical configuration.
**NOTE**: the button does **not** save the settings for the active camera in the *streamingCfg* structure. This must be done explicitly and is recommended to be done before synchronizing.
#### Switch Cameras
With this button, you can switch the cameras so that the one sown on the right side will become the active camera.
In case you have made changes of [Configuration](./Configuration.md), [Controls](./CameraControls.md) or camera-related [Trigger](./Trigger.md) settings ([Trigger/Motion](./TriggerMotion.md) and [Trigger/Camera](./TriggerCameraActions.md)) which have not yet been saved for Camera Switch, there will be a warning:

To make sure your configuration changes survive the camera switxh, push [Save Active Camera Settings for Camera Switch](#save-active-camera-settings-for-camera-switch)
## Process Status Indicators
[Process Status Indicators](./UserGuide.md#process-status-indicators) show whether a camera is currently recording video or not.
This is done independently for the active camera  and for the other camera .
**NOTE** that the recording status indicators are also activated when recording is started through the [API](./API.md)
## Configuring MJPEG Stream and jpeg Photo
With **raspiCamSrv**, [Camera Configuration](./Configuration.md) and [Controls](./CameraControls.md) apply always to the active camera (which camera is the active one, can be selected in the [Settings](./Settings.md)).
When the Flask server starts up without preloading stored configurations, the active camera and, if available, the second camera are preconfigured with parameter defaults.
The entire [Camera Configuration](./Configuration.md) as well as the [Controls](./CameraControls.md) for both cameras are stored in a specific streaming datastructure.
When [Camera Configuration](./Configuration.md) and/or [Controls](./CameraControls.md) for the active camera are modified, these settings will **not** be automatically stored in the streaming configuration.
This must be actively done with the **Save Active Camera Settings for Camera Switch**.
When cameras are switched, configuration and controls for the active camera will be replaced by those from the second camera stored in the streaming datastructure.
In order to configure your camera setup, you can proceed as follows:
1. Select one of the cameras as active camera
2. Adjust the [Camera Configuration](./Configuration.md),
for example *Transform* and/or *Sensor Mode* with *Stream Size*
3. Adjust the [Controls](./CameraControls.md),
for example *focus*/*lensposition*, *zoom*, *AutoExposure* or others
4. When the setup is satisfactory, go to the *Multi-Cam* dialog and press the **Save Active Camera Settings for Camera Switch** button.
5. Then switch cameras with the **<<< Switch Cameras >>>** button.
6. Repeat steps 2. to 4. for the other camera
7. If you now switch cameras, each stream, photo, raw photo and video should show in the way specifically configured for the camera.
8. Now you can go to the [Settings](./Settings.md) screen and push the **Store Configuration** button in order to persist the streaming data along with the other configuration settings.
9. If you want the entire configuration, including the streaming configuration, to be loaded when the server starts up, check the related checkbox in the [Settings](./Settings.md) screen.
================================================
FILE: docs/CamStereo.md
================================================
# Stereo-Cam
[](./Cam.md)
This dialog features [stereo camera](#stereo-camera) capabilities and can be used for visualizing [Depth Maps](#depth-maps) and [3D Video](#3d-video). Both can also be [streamed independently](#streaming).
**NOTE**:The dialog is only accessible if [Stereo Vision](./Settings.md#activating-and-deactivating-stereo-vision) has been activated.

## Stereo Camera
A precondition for Stereo Vision with raspiCamSrv is a system which allows connecting a pair of non-USB cameras of the same model.
These cameras need to be arranged as a stereo system with a typical human eye distance:

For a 3D-printable model, see [Raspberry Pi Camera 3 Stereo Case](https://makerworld.com/en/models/1742837-raspberry-pi-camera-3-stereo-case)
**NOTE**: *Stereo Vision* needs to be activated in the [Settings](./Settings.md#activating-and-deactivating-stereo-vision) dialog.
## Implementation
Stereo Vision in raspiCamSrv is based on [OpenCV](https://opencv.org/) and is inspired by a variety of examples on [LearnOpenCV](https://learnopencv.com/) such as [Making A Low-Cost Stereo Camera Using OpenCV](https://learnopencv.com/making-a-low-cost-stereo-camera-using-opencv/), from which also part of the code has been adapted and integrated with raspiCamSrv.
## Depth Maps
(See [Wikipedia article on Depth Maps](https://en.wikipedia.org/wiki/Depth_map))
The Stereo-Cam dialog usually opens with the following layout:

When opening, the system starts the Live view for both cameras as indicated by the [Process Status indicators](./UserGuide.md#process-status-indicators) and shows the streams of left and right camera in the upper part of the dialog.
The lower left part allows configuration of the intended Stereo Vision:
- *Intent* distinguishes the basic intent and allows selection between **Depth Map** and **3D Video**.
- *Rectified Images*, when activated uses the rectified images (see [Camera Calibration](./CamCalibration.md)) instead of the original ones to construct the stereo image.
- *Algorithm* allows selecting the Open CV algorithm to be used when constructing the depth map.
- *Algorithm Reference* links to the respective references in Open CV ([Stereo Block Matching](https://docs.opencv.org/4.6.0/d9/dba/classcv_1_1StereoBM.html) or [Semi-Global Matching](https://docs.opencv.org/4.6.0/d2/d85/classcv_1_1StereoSGBM.html)) where the parameters for the different algorithms are explained.
Pushing **Start** with *Depth Map* selected as Intent, will start a background process which applies the algorithm to the images of left and right video stream to produce a stream of depth map images:

The activity of the Stereo thread, in addition to the two camera live view threads, is indicated by the different color of the [Process Status indicators](./UserGuide.md#process-status-indicators) for the two cameras.
## Streaming
The Stereo stream can also be accessed through the URL which is shown underneath the stream in the dialog.
This URL, when called independently from the raspiCamSrv UI, will automatically start all necessary streaming processes.
The necessity of authentication can be configured in the [Settings](./Settings.md#configuring-authentication-for-streaming).
## 3D Video
(See [Wikipedia article on 3D Video](https://en.wikipedia.org/wiki/3D_film))
Starting Stereo processing with *Intent* "3D Video" will show the scene as 3D video which needs to be viewed with Red-Cyan color 3D glasses to see the 3D effect:

Here, you also have the possibility to record the stream as video.
Videos, recorded in this way, are stored under ```\static\photos\camera_S``` and can be accessed with the [Photos](./PhotoViewer.md) dialog by selecting the "Stereo" camera:

================================================
FILE: docs/CamWebcam.md
================================================
# Web Cam Access
[](./Cam.md)
**raspiCamSrv** enables webcam functionalities with Raspberry Pi cameras as well as with USB cameras.
For Pi 5 with two camera ports, both cameras can be streamed simultaneously.
Alternatively, you can choose one of the connected USB cameras as *Active* or *Second* camera.
This page shows the URLS for MJPEG streaming as well as for photo snapshots:

The left side of the page always shows the active camera.
If an additional camera is available, video stream and photo are shown on the right side.
When switching the cameras, either with the **Switch Cameras** button in [Multi-Cam](./CamMulticam.md) or by changing the camera in the [Settings](./Settings.md#switching-the-active-camera), the streams will be exchanged.
The *video_feed* endpoint will always refer to the active camera, which is also shown in the title bar.
The *video_feed2* endpoint will always refer to the other camera, if available.
The configuration and camera stream used for video and photo capture are indicated.
The links shown on the page open a new browser window.
## Video Stream
The video stream will always use the LIVE configuration.
By default, this configuration uses the *lores* camera stream.
The camera stream as well as its *stream size* can be configured in the [Configuration](./Configuration.md) screen.
## Photo Snapshot
For the photo snapshot, you can choose between using the [LIVE configuration](./Configuration.md), usually configured with the *lores* stream with low resolution and a snapshot using the [FOTO configuration](./Configuration.md), usually configured with the *main* stream with high resolution.
**NOTE**: Photo snapshots with high resolution assume an active live stream where the *lores* and the *main* streams of the camera are **simultaneously** configured (see [raspiCamSrv Tasks](./Background%20Processes.md)).
If your [configurations](./Configuration.md) for LIVE and FOTO are incompatible (for example using a different *Colour Space* or when both use the *main* stream with different resolutions), the live stream will request exclusive camera access with only the LIVE configuration activated. In this case, the URL for the high resolution photo snapshot will return an image with the resolution configured for LIVE.
If the live stream is active at the time when the photo snapshot is triggered, the snapshot will be taken immediately.
Otherwise, the live stream will be activated before the snapshot is taken. This requres starting the camera and giving it time to gather sufficient information for the auto-algorithms, which results in larger latency (1 to 1.5 sec).
================================================
FILE: docs/CameraControls.md
================================================
# raspiCamSrv Camera Controls
[](./LiveScreen.md)
**NOTE**: The subsequent description is essentially related to CSI cameras. For USB cameras, see [Camera Controls for USB Cameras](./CameraControls_UsbCams.md).
Picamera2 allows for a set of 36 camera control parameters which can be adjusted while the camera is active.
From these, 8 parameters are just part of the image metadata and cannot be applied to the camera.
In principle, the remaining 28 parameters can be applied to the camera at different times
1. As part of the [Camera Configuration](./Configuration.md).
Here **raspiCamSrv** supports adding any of these parameters to the configuration.
Control parameters included in the configuration have precedence over parameters not in the configuration.
2. After camera configuration before camera start.
In **raspiCamSrv**, this applies for all photos and videos taken in a raspiCamSrv session.
3. After the camera has been started.
In **raspiCamSrv**, this is only used for the live stream shown in the upper left quarter.
If controls have been modified and submitted, they will be directly applied to the live stream.
Modification of camera controls does not affect raw photos.
**NOTE**: For USB Cameras, [Handling of Controls](./CameraControls_UsbCams.md) is slightly different.
In **raspiCamSrv** all controls are explained through tooltips on the parameter name:

The texts for the tooltips have been mainly taken from the [Picamera2 Manual](./picamera2-manual.pdf) or the
underlying [libcamera documentation](https://libcamera.org/api-html/index.html).
The controls are grouped into
- [Focus Handling](./FocusHandling.md)
- [Zoom & Pan](./ZoomPan.md)
- [Auto-Exposure](./CameraControls_AutoExposure.md)
- [Exposure](./CameraControls_Exposure.md)
- [Image](./CameraControls_Image.md)
- [Ctrl](./CameraControls_Ctrl.md)
## Basics
All Control Parameter tabs (except Zoom and Ctrl) are structured similarly:
- Every tab is a form. This means that all parameters shown can be modified without any effect.
Only when the form is submitted through the **Submit** button, the settings are saved in the server configuration and directly applied to the live stream.
- Every parameter has a preceeding checkbox, which allows activation/deactivation of the control parameter within the configuration.
Only if the checkbox is checked, the parameter can be modified.
If the checkbox is unchecked, the control is not effective independently from its value.
- Individual parameters may have restictions either as distinct values or ranges of allowed values.
It should normally not be possible to enter a value which will not be accepted by the camera.
- Some camera systems support only a subset of the available control parameters.
For example, Raspberry Pi camera models 1 and 2 have no focus management.
This is recognized by **rapiCamSrv** and these parameters will not be presented to the user.
- All forms for the different parameter groups on different tabs are part of the same web page.
If values are modified without submitting, the modification will be visible even if another tab has been selected in the meantime.
**If modifications are not submitted on their own tab, they will be lost in the next request/response cycle which can be triggered by a submit on another tab**.
================================================
FILE: docs/CameraControls_AutoExposure.md
================================================
# Camera Controls / Auto-Exposure
[](./CameraControls.md)

This tab includes parameters which control the Auto Exposure (AE) algorithm of the camera.
================================================
FILE: docs/CameraControls_Ctrl.md
================================================
# Camera Controls / Ctrl
[](./CameraControls.md)

This tab shows functional buttons which have been configured in [Settings/Live Buttons](./SettingsLButtons.md).
Typically, these buttons will be used for control of devices which affect the camera position, such as servos controlling a Pan/Tilt device or a stepper motor for camera rotation.
You could also switch LEDs for illumination or control a slider motor.
When controlled through buttons on this page, the effect on the camera image can imediately be seen.
================================================
FILE: docs/CameraControls_Exposure.md
================================================
# Camera Controls / Exposure
[](./CameraControls.md)

This tab includes parameters related to exposure control.
================================================
FILE: docs/CameraControls_Image.md
================================================
# Camera Controls / Image
[](./CameraControls.md)

This tab includes parameters controlling the image appearance
================================================
FILE: docs/CameraControls_UsbCams.md
================================================
# Camera Controls for USB Cameras
[](./CameraControls.md)
**raspiCamSrv** supports a limited set of controls for USB Cameras:
- Switch between auto focus and manual focus
- Adjustment of focal distance
- Zoom, pan, tilt
- Enabling/disabling automatic white balance
- Adjusting the color temperature in case of manual white balance
- Adjusting the sharpness
- Adjusting the contrast
- Adjusting color saturation
- adjusting brightness
Whereas zoom/pan/tilt, as well as horizontal and vertical flipping, is controlled through OpenCV by modifying each individual frame delivered by the camera, the other controls are affected through the V4l2 (Video for Linux) interface to the camera.
Every camera advertises the supported controls along with the related range of valid values.
This information is [queried from the USB camera](./Information_Cam.md#determining-supported-controls) while **raspiCamSrv** initializes the camera information.
The list of supported controls as well as their minimum, maximum, step and default values are used tho customize the individual controls screens to the currently active camera.
### Focus Handling USB Cameras

### Image Control USB Cameras

In these dialogs, the input fields have value ranges and defaults appropriate for the active camera type.
Value ranges and default values are also visible in the tooltips.
### Applying Controls to USB Cameras
The supported controls ara applied to USB cameras through v4l2 commands, such as:
```v4l2-ctl --set-ctrl=contrast=50```
================================================
FILE: docs/Configuration.md
================================================
# raspiCamSrv Camera Configuration
Related Topics:
- [AI Camera Configuration](./Configuration_AI.md)
- [Camera Tuning](./Tuning.md)
[](./UserGuide.md)
Configuration parameters are so basic that they need to be applied before the camera is started.
Picamera2 provides three configuration bases which can be taken as is for a specific use case or they can be adjusted in one or several aspects.
These are:
- Preview configuration
for previews on a screen connected to the Raspberry Pi
- Still configuration
for photos
- Video configuration
for videos
**raspiCamSrv** does not make direct use of these configurations.
Instead, the following configurations can be fully configured:
- Live View configuration
which will be applied to the live stream
- Photo configuration
which will be applied when normal photos are taken
- Raw Photo configuration
which will be applied when raw photos are taken
- Video configuration
which will be applied when videos are recorded
Configuration changes may have an impact on the way how tasks and background processes are executed. If specific parameters, such as [Transform](#transform) are changed for a specific use case only, for example for *Video*, video recording will require that the Live Stream is stopped and paused while the video is being recorded.
For more details, see [raspiCamSrv Tasks and Background Processes](./Background%20Processes.md).
#### USB Cameras
The schema of configuration use cases, conceptually originating from Picamera2, is also retained for USB cameras. However, there are specific differences related to *Colour Space*, *Buffer Count*, *Queue* parameters. Also Controls cannot be included in the configuration as with Picamera2.
A major difference is that USB cameras accessed through OpenCV, do not allow using different streams.
As a consequence, live stream in parallel to photo taking or video recording would only be possible with identical configurations.
Since this does not seam to make sense because of performance issues, **raspiCamSrv** always requests exclusive use of the camera when taking photos or recording videos.
[Motion Capturing](./TriggerMotion.md) works in the same way for USB and CSI cameras.
## Configuration Tab
The *Config* submenu includes a tab *Tuning* which is described in [raspiCamSrv Camera Tuning](./Tuning.md) and not here.
An individual configuration tab is available for each use case. All tabs have essentially the same structure:
As a general aspect, the green [Submenu](./UserGuide.md#submenu) bar includes an option to synchronize the aspect ratio of [stream sizes](#stream-size-width-height) across all configurations if this has been changed for the current configuration.
If this option is activated after it was previously deactivated, all aspect ratios will be set to the one of the current configuration.
**NOTE**: For USB cameras this option is unchecked and the checkbox is disabled becaus USB cameras scale and crop with the correct aspect ratio intrinsically.

**As always: any modifications need to be submitted before they can be effective**
### Transform
With *Transform*, you can specify whether the image needs to be flipped horizontally, vertically or both. The latter case is identical to rotation of 180°.
**NOTE:** When this is modified for one configuration, the settings are automatically transferred to all other configurations.<br>
This is necessary because **raspiCamSrv** simultaneously configures all streams (lores, main and raw) in order to allow using these in parallel for different purposes, such as live stream and video recording. The transform settings cannot be different for different streams at the same time.
### Colour Space
This allows selecting one of the supported colour spaces
### Buffer Count
Specifies the number of buffers used by the camera for the specific use case.
Values are preset in accordance with corresponding settings of the Picamera2 standard use cases
### Queue
Specifies whether the camera is allowed to queue up a frame ready for a capture request.
### Sensor Mode
When **raspiCamSrv** starts up, one of the first things is to query the camera system for the available Sensor Modes.
These can be inspected on the [Info](./Information.md) screen.
These modes are offered for selection here.
When a Sensor Mode is selected, its main characteristics are shown to the right.
In addition to the available Sensor Modes, a "Custom" mode can be selected which allows especially to set the intended stream size (width and height if the image in pixels)
For the *Raw Photo* use case, "Custom" cannot be selected. Raw photos will allways use the stream size of the selected Sensor Mode.
### Stream
Specifies the stream to be used for the respective use case.
The camera system supports three streams (see [Picamera2 Manual](./picamera2-manual.pdf)):
- the **main** stream
- the **lowres** stream
- and the **raw** stream
The latter is for raw data output which bypasses the image signal processor.
For the *Raw Photo* use case, this is the only stream which can be selected.
### Stream Size (width, height)
If a standard Sensor Mode has been selected, the size related to the mode is shown.
If "Custom" has been selected as sensor mode, you may enter any size here (except for *Raw Photos*).
Produced photos or videos will then be in the specified format.
If the option to synchronize aspect ratios (right side of green Submenu bar) is selected, the *Stream Size*s for all other configurations will be adjusted to reproduce the aspect ratio of the current configuration.
**NOTE:** If, after submitting a *Live View* configuration, you get an error message ```
lores Stream Size must not exceed main Stream Size (Photo)```, you need to go to the *Photo* configuration and adjust its *Stream Size* to the desired value.
### Stream size aligned with Sensor Modes
If this option is activated, and if a stream size has been specified which is different from stream sizes of the available Sensor Modes, the Picamera2 Configuration will be asked to align the stream size. This may result in slightly different sizes which are, however, in better accordance with available Sensor Modes.
### Stream Format
It can be selected from a number of pixel and image formats supported by Picamera2.
For details, see [Picamera2 Manual](./picamera2-manual.pdf), Appendix A.
Whereas for *Live Stream*, *Photo* and *Video* a format can be selected from the same list, the formats available for *Raw Photo* are different. These are specified in the Sensor Modes (see [Info](./Information.md)).
**raspiCamSrv** queries these from Picamera2 at server startup and offers the found formats in the configuration screen.
### Display
This parameter is just shown for completeness.
It specifies the stream which shall be used for display on a monitor connected to the system.
This is not relevant in the scenario addressed by **raspiCamSrv**, which is usually headless.
### Encode
This specifies the stream which needs to be sent to the encoder.
Settings are preconfigured and cannot be modified.
Encoding is only necessary for the *Live View* (MJPEG encoding) and the *Video* use cases.
For *Video*, the encoder depends on the video format chosen.
## Controls included in Configuration
A configuration for a specific use case may also include Camera Controls.
Actually, Picamera2 requires that at least one control is included in the configuration.
**raspiCamSrv** preconfigurs a control with specific settings in accordance with the Picamera2 standard use case configurations.
In addition, the button **Add Active Ctrls** will include all controls which are currently active in the [Camera Controls](./CameraControls.md) configuration.
Values are taken as configured and cannot be modified here.
In case a control parameter has a wrong value, it can be selected and then removed from the configuration with the **Remove Selected Ctrls** button.
================================================
FILE: docs/Configuration_AI.md
================================================
# raspiCamSrv Camera AI Configuration
[](./Configuration.md)
**NOTE**: This dialog is only available if the Active Camera is a [Raspberry Pi AI Camera](https://www.raspberrypi.com/documentation/accessories/ai-camera.html) and if AI features have been activated in the [Settings Diaolog](./Settings.md#activating-and-deactivating-the-use-of-camera-ai-features)
The IMX500 imaging sensor of the AI Camera can load a neural network model from a location on the Raspberry Pi and apply it to the individual frames delivered by the sensor. Inference data, generated by the model, are supplied to application2 through image meta data. This allows applications to evaluate these data and visualize them in the application context or through overlays on the individual frames.

The dialog has three distinct sections:
## Configuration for AI
Here you specify the neural network file which will be loaded by the AI Camera.
**NOTE**: The model can only be changed if the imx500 camera is currently not open. So, you need to wait until the Live View background process has automatically stopped (within 10 seconds).
You can check the status Live stream of the Active Camera by clicking on the *Config* menu until you see the [Process Status Indicator](./UserGuide.md#process-status-indicators) for the Active Camera change to grey.
Then, the fields for selection of the *AI Model File* will be enabled:
- *Full Path to Folder with Model Files*<br>This is the folder where model files are stored.
<br>With installation of the ```imx500-all``` package, a set of model files will already be available at
<br>```/usr/share/imx500-models```.
<br>Leaving the field empty will automatically set this as the default folder.
- *Task*
<br>Every model file has a specific *Task*.
<br>You can currently choose between
<br>- Classification
<br>- Object Detection
<br>- Pose Estimation
<br>- Segmentation
<br>When choosing one of these tasks, the entry for the *AI Model File* will be cleared to enforce selection.
- *AI Model File*
<br>After a *Task* has been chosen, raspiCamSrv will iterate the available model files in the specified folder and determine the *Task* for which these have been prepared.
<br>Only files having the specified task will be offered for selection.
- *Intrinsics*
<br>Every model fileexposes a set of intrinsics characterizing its capabilities and operational details.
<br>These will be shown here.
Sources and details for various Reference Neural Network Models can be found on [https://github.com/raspberrypi/imx500-models](https://github.com/raspberrypi/imx500-models)
Implementations within **raspiCamSrv** are based on the [Demo Code Examples](https://github.com/raspberrypi/picamera2/tree/main/examples/imx500) coming with [Picamera2](https://github.com/raspberrypi/picamera2).
## Settings
This section includes several parameters by which the visualization of inference data can be adjusted.
Only a subset of these parameters is applicable for a specific model.
Parameters which do not apply, are disabled when a model has been selected.
- *Top K Indices* (Classification)
<br>Only the given number of indices with the highest rating will be visualized.
- *Detection Threshold*
<br>Only detections having a score larger than the given threshold will be visualized.
- *IOU Threshold*
<br>Specifies the IoU (Intersection over Union) threshold for object detection.
- *Max Detections*
<br>specifies the maximum number of detections to be visualized
- *Draw Resulte on Stream lores*
<br>If activated, inference results will be visualized on the *lores* stream which is usually used for the Live Stream [Configuration](./Configuration.md)
- *Draw Resulte on Stream main*
<br>If activated, inference results will be visualized on the *main* stream which is usually used for the Photo and Video [Configuration](./Configuration.md)
**NOTE**: Text sizes and line thickness used for visualization, as used in the Picamera2 demos are optimized for lower resolution previews (e.g. 640x480). If you intend to visualize on photos and/or videos, it is recommended to set the [Stream Size](./Configuration.md#stream-size-width-height) to a 'Custom' size of about the same size as the *lores* stream for *Live View*.
## Enable AI
Here you can enable the selected model together with the visualization parameters. Or you can disable a currently active model.
Either way will require a confirmation.
================================================
FILE: docs/Console.md
================================================
# Console
[](./UserGuide.md)
The Console group of dialogs provides functions for user interactions with the Raspberry Pi.

- [Versatile Buttons](./ConsoleVButtons.md) allow interaction with the Operating System by running OS commands or scripts.
- [Action Buttons](./ConsoleActionButtons.md) allow execution of various types [Actions] for interaction with GPIO-connected output devices or the camera system.
================================================
FILE: docs/ConsoleActionButtons.md
================================================
# Console - Action Buttons
[](./Console.md)
This page shows buttons which have been configured in the [Settings / Action Buttons](./SettingsAButtons.md):

The example layout of this screenshot is based on the example configuration shown for the [Settings / Action Buttons](./SettingsAButtons.md) screen.
## Button Execution
When the [Action](./TriggerActions.md), configured for a button is executed, the behavior for the action is slightly different compared to invocation of an action on behalf of a [Trigger](./TriggerTriggers.md).
- If a device is busy at the time when a button is pressed, the action is not executed. Instead a "Device busy" information is shown in the status line:

- Also, the action is not executed in an own thread but synchronously, so that the user needs to wait for action completion which is confirmed in the message line.
================================================
FILE: docs/ConsoleVButtons.md
================================================
# Console - Versatile Buttons
[](./Console.md)
This page shows buttons which have been configured in the [Settings / Versatile Buttons](./SettingsVButtons.md):

The example layout of this screenshot is based on the example configuration shown for the [Settings / Versatile Buttons](./SettingsVButtons.md) screen.
## Button Execution
When a button is clicked which is configured to require confirmation, a confirmation dialog is shown where execution can be refused:

## Execution Result
In the bottom part of the dialog the result of the command execution is shown:
- *Command*<br>The command configured for the button.
- *Run Arguments*<br>Command execution is done using the Python [subprocess.run](https://docs.python.org/3/library/subprocess.html) method which receives arguments as a list. This list is obtained by parsing the command string with spaces as separators.
- *Return Code*<br>The return code returned from command execution.
- *Stdout*<br>Output which command execution has sent to Stdout.<br>Multiline output can be scrolled.
- *Stderr*<br>Error information which command execution has sent to Stderr.<br>Multiline output can be scrolled.
- Status Line<br>The status line at the bottom shows whether the command could be executed or not, irrespective of errors which might have occurred during command execution.
The last *Execution Result* remains visible within the live time of the Flask server.
Of course, no result will be visible if the Flask server has been restarted or of the Raspberry Pi has been rebooted.
## Interactive Commandline
If the [Settings / Versatile Buttons](./SettingsVButtons.md) have declared the commandline to be interactive, commands can be directly entered on the commandline:

================================================
FILE: docs/FocusHandling.md
================================================
# raspiCamSrv Focus Handling
[](./CameraControls.md)
Focus handling is not supported by camera versions 1 and 2.

This tab includes various controls which affect the Auto Focus (AF) algorithm of the camera.
The **Autofocus Mode** can be set to "Manual", "Auto" or "Continuous"
## Manual Focus
When *Autofocus Mode* "Manual" is chosen, also the *Focal Distance* field must be activated and the distance must be set manually.
Pressing **Submit** will apply the setting to the live stream and the changed focus will be immediately visible.
## Continuous Focus
When *Autofocus Mode* is set to "Continuous", the camera will, after submitting, continuously try to focus under consideration of settings for other focus handling parameters.
## Automatic Focus
When *Autofocus Mode* is set to "Auto", the camera will automatically focus after an autofocus cycle has been triggered.
Before the cycle can be triggered through the **Trigger Autofocus** button, the settings must be applied with the **Submit** button.
Submitting the "Auto" *Autofocus Mode* will have no effect on the live stream.
## Trigger Autofocus
The effect of the autofocus cycle will essentially depend on the settings for the other AF control parameters.
Whether or not the autofocus cycle was successful, will be shown in the message area at the bottom of the application window:

If the autofocus cycle was successful, **raspiCamSrv** will request metadata from the camera and determine the focal distance from the LensPosition.
The Value will be entered in the *Focal Distance* field, which will also be activated automatically.
Also, the *Autofocus Mode* will be automatically set to "Manual" so that the measured *Focal Distance* can be used for future photos.

## Autofocus Windows
These are rectangle areas within the image which will be used by the AF algorithm to focus.
Multiple rectangle areas can be specified.
**raspiCamSrv** supports graphical specification of these areas in the following way.
1. Activate the checkbox for *Autofocus Windows*.
As result, a canvas will be drawn over the live stream area which is visible as thin red border:

2. Now you can use the mouse to draw rectangles on this canvas:
Position the cursor at one corner of the intended rectangle,
press the left mouse button,
and drag with mouse button down to the opposite corner.
3. When the mouse button is released, the rectangle coordinates will be scaled to the current scaler crop settings and entered in the *Autofocus Windows* field.

4. If required, you can draw additional rectangles in the same way.
While drawing rectangles, previously drawn rectangles will vanish without getting lost.
5. Finally, when the mouse pointer leaves the canvas area, all rectangles will be shown over the live stream area.

**Don't forget to push Submit because otherwise, these settings will get lost!**
6. In order to remove all areas, just deactivate the *Autofocus Windows* checkbox and activate it again.
The canvas and the rectangles representing the AF Windows will remain visible as long as the *Autofocus Windows* checkbox is activated and whenever the *Focus* tab is visible.
================================================
FILE: docs/Information.md
================================================
# raspiCamSrv Information
[](./UserGuide.md)

This menu gives access to detailed information on the raspiCamSrv system:
- [System](./Information_Sys.md)
shows detailed information about the Raspberry Pi system as well as on the software stack used by raspiCamSrv.
The following sub-menus are only visible if at least one camera is connected to the system:
- [Cameras](./Information_Cam.md)
shows information on the installed cameras.
- [Camera Properties](./Information_CamPrp.md)
shows detailed information for the **active** camera.
- [Sensor Mode n](./Information_Sensor.md)
This set of tabs shows characteristics for the different sensor modes advertised by the **active** camera.
================================================
FILE: docs/Information_Cam.md
================================================
# raspiCamSrv Info/Camera Information
[](./Information.md)
This screen shows information on the installed cameras.

*Software Stack* shows information on installed packages with Version (*Ver*) and the path from which the packages were loaded (*Loc*).
## Camera x
The tab lists all cameras currently connected to the system.
Each camera has an identifying number (0, 1, ...) shown in the title above each parameter list.
The assignment of camera number to physical camera may change when CSI cameras are plugged into a different CSI port (Pi 5) or when USB cameras are plugged into a different USB port.
When the server starts up, the first camera in the [list of cameras](#detection-of-cameras) is selected as active camera, unless a specific camera is activated when a [stored configuration](./SettingsConfiguration.md) is loaded at startup..
You may later switch to another camera on the [Settings](./Settings.md) screen or the [Multi Cam](./CamMulticam.md) screen
The active camera is indicated in the list.
The active camera will also be shown in the title bar of the application after log-in.
For USB cameras, the device through which the camera is accessible is also shown (See [Detection of Cameras](#detection-of-cameras)).
The information "(Not in use)" for a USB camera indicates that the camera has been detected by **raspiCamSrv** but it is not in use because USB cameras have been deactivated in the [Settings](./Settings_NoCam.md). In this case, the USB camera cannot be selected as active or second camera in the [Settings](./Settings.md) screen or the [Multi Cam](./CamMulticam.md) screen.
### Status
*Current Status* shows the status of the camera:
- open / closed
- started / stopped
- current [Sensor Mode](./Information_Sensor.md)
This is only shown for the currently active camera if it is started.
If the Sensor Mode cannot currently be determined, 'unknown' is shown.
The Sensor Mode is usually automatically selected by the camera and normally corresponds to the largest [Stream Size](./Configuration.md#stream-size-width-height), requested by one of the [Camera Configurations](./Configuration.md).
- inactive<br>is shown for USB cameras which are currently not in use as active or second camera.
- excluded<br>is shown for a USB camera which is, in principle, available for being used with **raspiCamSrv**, but currently excluded in the [Settings](./Settings.md)
- not supported (OpenCV missing)<br>Is shown if a detected USB camera cannot be used within **raspiCamSrv** because OpenCV is not installed.
See [Camera Status and Number of Threads](#camera-status-and-number-of-threads)
Under *Tuning File*, you can see whether the Default or a custom tuning file are currently in use.
See [raspiCamSrv Camera Tuning](./Tuning.md).
### AI Features
This shows whether AI Features of a camera are available and active.
Currently, this applies only to the [Raspberry Pi AI Camera](https://www.raspberrypi.com/documentation/accessories/ai-camera.html) with Sony IMX500 sensor.
- Not Available
<br>Indicates that the camera has no AI capabilities
- Available
<br>Indicates that the camera has AI capabilities and that AI features are enabled in the [Settings](./Settings.md#activating-and-deactivating-the-use-of-camera-ai-features).
<br>Whether or not the camera is currently running a neural network model can be controlled in the [Camera AI Configuration](./Configuration_AI.md)
- Disabled in Settings
<br>Indicates that the camera has AI capabilities. However AI features are disabled in the [Settings](./Settings.md#activating-and-deactivating-the-use-of-camera-ai-features)
### Camera connected but not in the list?
If you have a USB camera connected which does not show up in the list, you may have plugged in the camera while **raspiCamSrv** was running.
In this case, you can use function [Reload Cameras](./SettingsConfiguration.md) to identify hot-plugged cameras.
## Camera Status and Number of Threads
The number of threads used by the server process depends on the status of the camera(s).
- When all cameras are closed, there is just the server process and, in case of Bookworm systems, 2 threads which are started with the import of Picamera2.
Thus, there is a minimum of three threads (1 for Bullseye).
- Opening a camera starts additional threads which remain active while the camera is open.
The number of threads may depend on the camera infrastructure specific for the operating system.
- Starting a camera and/or starting an encoder starts additional threads depending on the chosen camera function and encoder.
- **raspiCamSrv** also uses threads for background processes, such as live stream, video recording, photo series and motion detection. These ramain active while these processes are running.
- Stopping and closing a camera will also stop the dependent threads and thus reduce the number of active threads.
- If .mp4 video is currently recorded ([started manually](./Phototaking.md) or as an action within [motion capturing](./Trigger.md)), there will be an additional ffmpeg process with additional threads.
- In case of .mp4 video recording with H264Encoder and FfmpegOutput there seems to be an issue with threads:
In this case, there may be threads surviving when the encoder is stopped (see [picamera2 Issue #1023](https://github.com/raspberrypi/picamera2/issues/1023)).
So, when .mp4 videos have been recorded, the number of threads may not go down to 3 (1 for Bullseye) after all camaras have been closed.
Experience shows that such threads may survive for a longer time but typically, they show only minor or no CPU utilization.
Often, they vanish after the camera has been closed after live stream has stopped.
**raspiCamSrv** closes the camera in case it is not used:
- When the [live stream](./LiveScreen.md) stops after 10 seconds of inactivity, the camera used for the live stream will be stopped and closed.
- After [photos have been taken or videos have been recorded](Phototaking.md), the camera will be stopped and closed.
- For [Photo Series](./PhotoSeries.md), the camera will be stopped and closed after a shot if the interval to the next shot is >60 sec.
This does not apply to [Exposure Series](./PhotoSeriesExp.md) and [Focus Stacks](./PhotoSeriesFocus.md).
- If [motion detection](./Trigger.md) is active, the live stream is kept activated which keeps the camera open and started.
- In case of [Stereo Vision](./CamStereo.md), the live streams for both cameras are kept active,
## Detection of Cameras
**raspiCamSrv** uses the ```Picamera2.global_camera_info()``` list (see [Picamera2 Manual](https://datasheets.raspberrypi.com/camera/picamera2-manual.pdf), ch. 8.7) to identify the currently connected cameras.
For each camera, the information provided by Picamera2 includes
- ```Num```: The camera number by which a camera is identified within Picamera2 as well as in raspiCamSrv.
- ```Model```: The model name of the camera, as advertised by the camera driver
- ```Location```: A number reporting how the camera is mounted, as reported by libcamera.
- ```Rotation```: How the camera is rotated for normal operation, as reported by libcamera
- ```ID```: An identifier string for the camera, indicating how the camera is connected. <br>You can tell from this value whether the camera is accessed using I2C or USB.
## Identification of USB Cameras
A camera is identified as USB camera, if ```usb``` is found in the ```ID```.
In **raspiCamSrv**, USB cameras are accessed through [OpenCV](https://opencv.org/) rather than through Picamera2, which provides only very limited support for USB cameras.
However, with OpenCV, a camera cannot be accessed through the Picamera2 camera number (```Num```).
Instead, the ```/dev/videoX``` of the Linux kernel must be used.
For mapping of the Picamera2 camera number (```Num```) to the device number, **raspiCamSrv** uses the following algorithm:
Assuming that the ```ID``` is structured in the following way:
e.g.:
```/base/axi/pcie@1000120000/rp1/usb@200000-2:1.0-046d:085c```
| Component | Meaning
|---------------------------------|------------
| ```/base/axi/pcie@1000120000``` | Root of the system-on-chip’s PCIe controller
| ```/rp1/usb@200000``` | The RP1 I/O controller’s USB host controller (i.e. USB root hub)
| ```-2:1.0``` | USB device address and interface: port 2, interface 1.0
| ```-046d:085c``` | Vendor ID : Product ID (046d = Logitech, 085c = C922 Pro Stream Webcam)
Now, with Video for Linux (V4L2), we can list all video devices:
```v4l2-ctl --list-devices``` reveals, for example:
```
...
rpi-hevc-dec (platform:rpi-hevc-dec):
/dev/video19
/dev/media1
Logi 4K Stream Edition (usb-xhci-hcd.0-1):
/dev/video2
/dev/video3
/dev/video4
/dev/video5
/dev/media4
C922 Pro Stream Webcam (usb-xhci-hcd.0-2):
/dev/video0
/dev/video1
/dev/media3
```
Each header within the list shows the camera's model and port (```(usb-xhci-hcd.0-2)``` indicates port 2)
Now, by mapping model and port from the Picamera2 ```ID``` with corresponding information from ```v4l2-ctl```, we can identify the group for each USB camera.
The first entry in the list of devices for this group is assigned to the camera number, assuming that this represents the main camera stream, whereas subsequent entries are for alternative functions.
## Determining Camera Properties for USB Cameras
Whereas camera properties of CSI cameras are directly provided by Picamera2 (see [Picamera2 Manual](https://datasheets.raspberrypi.com/camera/picamera2-manual.pdf), Appendix D), this is not the case for USB cameras.
**raspiCamSrv** maps properties of USB cameras as far as possible to the Picamera2 datastructure for seamless integration of USB cameras.
The USB camera properties are determined with the v4l2 through (e.g.):
```v4l2-ctl --device=/dev/video12 --all```
giving:
```
Driver Info:
Driver name : uvcvideo
Card type : C922 Pro Stream Webcam
Bus info : usb-xhci-hcd.0-2
Driver version : 6.12.47
Capabilities : 0x84a00001
Video Capture
Metadata Capture
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04200001
Video Capture
Streaming
Extended Pix Format
Media Driver Info:
Driver name : uvcvideo
Model : C922 Pro Stream Webcam
Serial : A9382BFF
Bus info : usb-xhci-hcd.0-2
Media version : 6.12.47
Hardware revision: 0x00000016 (22)
Driver version : 6.12.47
Interface Info:
ID : 0x03000002
Type : V4L Video
Entity Info:
ID : 0x00000001 (1)
Name : C922 Pro Stream Webcam
Function : V4L2 I/O
Flags : default
Pad 0x01000007 : 0: Sink
Link 0x0200001f: from remote pad 0x100000a of entity 'Processing 3' (Video Pixel Formatter): Data, Enabled, Immutable
Priority: 2
Video input : 0 (Camera 1: ok)
Format Video Capture:
Width/Height : 640/480
Pixel Format : 'YUYV' (YUYV 4:2:2)
Field : None
Bytes per Line : 1280
Size Image : 614400
Colorspace : sRGB
Transfer Function : Rec. 709
YCbCr/HSV Encoding: ITU-R 601
Quantization : Default (maps to Limited Range)
Flags :
Crop Capability Video Capture:
Bounds : Left 0, Top 0, Width 640, Height 480
Default : Left 0, Top 0, Width 640, Height 480
Pixel Aspect: 1/1
Selection Video Capture: crop_default, Left 0, Top 0, Width 640, Height 480, Flags:
Selection Video Capture: crop_bounds, Left 0, Top 0, Width 640, Height 480, Flags:
Streaming Parameters Video Capture:
Capabilities : timeperframe
Frames per second: 30.000 (30/1)
Read buffers : 0
User Controls
brightness 0x00980900 (int) : min=0 max=255 step=1 default=128 value=128
contrast 0x00980901 (int) : min=0 max=255 step=1 default=128 value=128
saturation 0x00980902 (int) : min=0 max=255 step=1 default=128 value=128
white_balance_automatic 0x0098090c (bool) : default=1 value=1
gain 0x00980913 (int) : min=0 max=255 step=1 default=0 value=0
power_line_frequency 0x00980918 (menu) : min=0 max=2 default=2 value=2 (60 Hz)
0: Disabled
1: 50 Hz
2: 60 Hz
white_balance_temperature 0x0098091a (int) : min=2000 max=6500 step=1 default=4000 value=4000 flags=inactive
sharpness 0x0098091b (int) : min=0 max=255 step=1 default=128 value=128
backlight_compensation 0x0098091c (int) : min=0 max=1 step=1 default=0 value=0
Camera Controls
auto_exposure 0x009a0901 (menu) : min=0 max=3 default=3 value=3 (Aperture Priority Mode)
1: Manual Mode
3: Aperture Priority Mode
exposure_time_absolute 0x009a0902 (int) : min=3 max=2047 step=1 default=250 value=250 flags=inactive
exposure_dynamic_framerate 0x009a0903 (bool) : default=0 value=1
pan_absolute 0x009a0908 (int) : min=-36000 max=36000 step=3600 default=0 value=0
tilt_absolute 0x009a0909 (int) : min=-36000 max=36000 step=3600 default=0 value=0
focus_absolute 0x009a090a (int) : min=0 max=250 step=5 default=0 value=0 flags=inactive
focus_automatic_continuous 0x009a090c (bool) : default=1 value=1
zoom_absolute 0x009a090d (int) : min=100 max=500 step=1 default=100 value=100
```
By parsing this information, relevant data for camera properties can be retrieved and mapped to camera property elements.
The ```PixelArraySize``` is determined as the maximum size of the Sensor Modes found (see [below](#determining-sensor-modes-for-usb-cameras))
## Determining Sensor Modes for USB Cameras
Whereas sensor modes of CSI cameras are directly provided by Picamera2 (see [Picamera2 Manual](https://datasheets.raspberrypi.com/camera/picamera2-manual.pdf), ch. 4.2.2.3), this is not the case for USB cameras.
**raspiCamSrv** maps video formats of USB cameras as far as possible to the Picamera2 sensor mode datastructure for seamless integration of USB cameras.
The USB camera video formats are determined with the v4l2 through (e.g.):
```v4l2-ctl --device=/dev/video12 --list-formats-ext```
giving:
```
ioctl: VIDIOC_ENUM_FMT
Type: Video Capture
[0]: 'YUYV' (YUYV 4:2:2)
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.042s (24.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.133s (7.500 fps)
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 160x90
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.042s (24.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.133s (7.500 fps)
Interval: Discrete 0.200s (5.000 fps)
...
Size: Discrete 2304x1536
Interval: Discrete 0.500s (2.000 fps)
[1]: 'MJPG' (Motion-JPEG, compressed)
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.042s (24.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.133s (7.500 fps)
Interval: Discrete 0.200s (5.000 fps)
...
Size: Discrete 1920x1080
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.042s (24.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.133s (7.500 fps)
Interval: Discrete 0.200s (5.000 fps)
```
From this output the list of sensor modes is generated with information on Size and Format.
The FPS, stored for each sensor mode is the maximum value of fps found for each format.
## Determining supported Controls
Every USB Camera advertises a list of controls which can be used to adjust focus or image appearance.
Supported controls are determined with the v4l2 through (e.g.):
```v4l2-ctl --device=/dev/video12 --list-ctrls```
giving:
```
User Controls
brightness 0x00980900 (int) : min=0 max=255 step=1 default=128 value=128
contrast 0x00980901 (int) : min=0 max=255 step=1 default=128 value=128
saturation 0x00980902 (int) : min=0 max=255 step=1 default=128 value=128
white_balance_automatic 0x0098090c (bool) : default=1 value=0
gain 0x00980913 (int) : min=0 max=255 step=1 default=0 value=0
power_line_frequency 0x00980918 (menu) : min=0 max=2 default=2 value=2 (60 Hz)
white_balance_temperature 0x0098091a (int) : min=2000 max=7500 step=10 default=4000 value=3000
sharpness 0x0098091b (int) : min=0 max=255 step=1 default=128 value=128
backlight_compensation 0x0098091c (int) : min=0 max=1 step=1 default=1 value=1
Camera Controls
auto_exposure 0x009a0901 (menu) : min=0 max=3 default=3 value=3 (Aperture Priority Mode)
exposure_time_absolute 0x009a0902 (int) : min=3 max=2047 step=1 default=250 value=312 flags=inactive
exposure_dynamic_framerate 0x009a0903 (bool) : default=0 value=0
pan_absolute 0x009a0908 (int) : min=-36000 max=36000 step=3600 default=0 value=0
tilt_absolute 0x009a0909 (int) : min=-36000 max=36000 step=3600 default=0 value=0
focus_absolute 0x009a090a (int) : min=0 max=255 step=5 default=0 value=10 flags=inactive
focus_automatic_continuous 0x009a090c (bool) : default=1 value=1
zoom_absolute 0x009a090d (int) : min=100 max=500 step=1 default=100 value=100
```
**raspiCamSrv** analyzes this list with respect to a limited set of controls and registers
- control name
- value data type
- minimum value
- maximum value
- default value
For the active camera, this information is appended to the Camera Controls data structure (see [Server Configuration Storage](./SettingsConfiguration.md#server-configuration-storage)), which will also be transferred to the Streaming Configuration in case of multiple cameras.
In order to establish this data structure, USB cameras need to be activated once as *Active Camera*.
The controls information is cused to customize the [Camera Controls](./CameraControls_UsbCams.md) screens when a USB camera is the *Active Camera*.
================================================
FILE: docs/Information_CamPrp.md
================================================
# raspiCamSrv Info/Camera Properties
[](./Information.md)
This screen shows properties of the active camera.

See also [Determining Camera Properties for USB Cameras](./Information_Cam.md#determining-camera-properties-for-usb-cameras)
================================================
FILE: docs/Information_Sensor.md
================================================
# raspiCamSrv Info/Sensor Mode
[](./Information.md)
The camera system advertises the supported Sensor Modes with their characteristics.
These are referred to within the [Camera Configuration](./Configuration.md).
The characteristics for every Sensor Mode are shown on an individual tab:

USB cameras may advertise a large number of sensor modes. In this case, the remaining buttons for sensor mode selection can be found in a drop-down list:

================================================
FILE: docs/Information_Sys.md
================================================
# raspiCamSrv Info/System Information
[](./Information.md)
This screen shows information on the Raspberry Pi system as well as on the software stack required by raspiCamSrv.

### Hardware and OS
This section shows information on the server hardware and operating system
- *Model*
Raspberry Pi model frpm ```/proc/device-tree/model```
- *Board Revision*
Board revision from ```/proc/cpuinfo```
- *Kernel Version*
Kernel Version as reported by ```uname -r```
- *Debian Version*
Information on the operating system:
.. *Description* from ```lsb_release -a```
.. *Version* from ```/etc/debian_version```
.. 32-bit/64-bit from ```dpkg-architecture --query DEB_HOST_ARCH```
### Processes
This section informs about active processes related to raspiCamSrv.
#### Environment
shows whether the raspiCamSrv server process is running
- directly on the "Host System"
- or in a "Docker Container"
#### Server Process
shows how the server process has been started:
- "Server started via systemd system service"
in this case, audio cannot be recorded along with video.
- "Server started via systemd user service"
in this case, audio can be recorded along with video.
- "Server started via command line"
#### WSGI Server
raspiCamSrv is based on [Flask](https://flask.palletsprojects.com/en/stable/), which is a WSGI (Web Server Gateway Interface) application.
A WSGI server is required to run the application.
The server which is currently active is shown here.
Standard [raspiCamSrv installations](./installation.md) support the following alternatives:
- *gunicorn*
[Gunicorn](https://gunicorn.org/) is a mature, stable and widely used WSGI server for production use.
For Gunicorn, also the number of threads, configured for the worker process, are shown.
The number of threads limit the number of simultaneous MJPEG streams (See [Gunicorn Settings](./installation_man.md#gunicorn-settings)).
- *werkzeug*
[Werkzeug](https://werkzeug.palletsprojects.com/en/stable/) is the WSGI server integrated in Flask for development and testing purposes.
On start, a warning is shown:
```Do not use it in a production deployment. Use a production WSGI server instead.```
#### Process Info
shows current process information for the raspiCamSrv server process (result of Linux ```ps -eLf``` command)
- *PID*
Process ID of WSGI server running Flask.
In case of *werkzeug*, there is just one process.
For *gunicorn*, there are two processes, where the first is the Master process with typically 2 threads which control a single worker process (restricted through ```-w 1``` option at startup) which is running the Flask application.
- *Start*
Process start time (STIME): either start time (HH:MM) at current day or day (MonDD) when process was started.
- *#Threads*
Number of threads (NLWP)
- *CPU Process*
CPU time of process (TIME for LWP == PID) in HH:MM:SS
- *CPU Threads*
Sum of CPU time for threads ((TIME for LWP != PID)) in %H:MM:SS
#### FFmpeg Info
shows information on an ffmpeg process if encoding of .mp4 videos is currently active.
Recording of .mp4 videos may have been [started manually](./Phototaking.md) or as an action within [motion capturing](./Trigger.md)
#### raspiCamSrv Start
shows the time when the raspiCamSrv server has been started.
At server start, raspiCamSrv checks whether or not the Raspberry Pi system time is synchronized with the time server.
When the device is booted and raspiCamSrv is automatically started, the time synchronization will occasionally be done after the Flask server has already been started.
In this case, in order to avoid timing issues, raspiCamSrv will wait at startup until time synchronization is completed.
The time shown here is the system time at the moment when the check for time synchronization was successful.
raspiCamSrv analyzes the output of command ```timedatectl``` to check the system clock synchronization status.
If this check fails or times out (60 sec), raspiCamSrv will start nevertheless.
In this case, the information "System time not synced at raspiCamSrv start" will be shown here.
If the server is running in a Docker container (see [Running raspiCamSrv as Docker Container](./SetupDocker.md)), the time is assumed to be synchronized and the check will be skipped.
This is indicated through

### Software Stack
In this section, information on installed packages is shown.
- *Ver*
is the package version
- *Loc*
is the path from which the packages were loaded.
### Streaming Clients

The tab lists the clients which are currently using one of the camera streams.
Along with the IP address of the client, a list of streams is shown which the client is using:
- *live_view*<br> [The Live View](./LiveScreen.md) stream<br>indicated by [Process Status Indicator](./UserGuide.md#process-status-indicators) 
- *video_feed*<br>The [video Stream](./CamWebcam.md#video-stream) for the active camera<br>indicated by [Process Status Indicator](./UserGuide.md#process-status-indicators) 
- *video_feed2*<br>The [video Stream](./CamWebcam.md#video-stream) for the second camera, if available<br>indicated by [Process Status Indicator](./UserGuide.md#process-status-indicators) 
================================================
FILE: docs/LiveDirectControl.md
================================================
# raspiCamSrv Live Direct Control
[](./LiveScreen.md)
This screen is opened by clicking on the [Live Stream area](./LiveScreen.md#accessing-the-direct-control-panel). It allows direct control of selected control parameters.
Control parameters with numeric values are accessible if they have been activated on the [Camera Controls](./CameraControls.md) screens.
When finished with parameter tuning, return to the [Live](./LiveScreen.md) screen or select any other menu option.

## Focal Distance
The slider for *Focal Distance* is mapped to a range from 0 to 1.
If you drag the slider to a value below the minimum focal distance, it will snap back to the minimum.
Scaling uses an x**3 behavior so that lower values can be selected with higher precision.
## Left and Right Sliders
The sliders for all parameters are mapped to a range from -1 to 1 with the default at 0, following an x**3 function:

Therefore, values closer to the default value can be selected with higher precision.
Because of the mapping, you will always see the same sliders, independently from the real value ranges which are significantly different for CSI and USB cameras and which can also vary between different USB camera models.
For some parameters, e.g. *Analogue Gain*, the default value is at the minimum of the parameter range.
In this case, negative slider positions can not be set; the slider will snap back to 0.
## Zoom Factor
The slider for the *Zoom Factor* directly shows the *Zoom Factor* with linear scaling.
If you previously have selected a specific image region (Scaler Crop) with the [Zoom and Pan](./ZoomPan.md) dialog, the resulting *Zoom Factor* will be the maximum which ca be set with the slider. Selecting a larger value will always snap back to this maximum.
However, you can zoom into this area until the lowest zoom factor is reached.
================================================
FILE: docs/LiveScreen.md
================================================
# raspiCamSrv Live Screen
[](./UserGuide.md)
The **Live** screen is the central part of the application.
After photos or videos have been taken in the current session, its layout is as shown below:

## Layout
### Top Left Quarter
This is the area where a Live stream is shown, except for phases when videos are recorded and when [Configuration](./Configuration.md) for Live View and Video are not compatible..
### Top Right Quarter
This area allows selecting and configuration of all [Camera Controls](./CameraControls.md) supported by Picamera2. These are parameters which affect the characteristics of images and outputs of the camera and which can be modified while the camera is running.
The menu row of this section groups the controls into several categories.
### Bottom Left Quarter
The bottom part of the screen is only shown if a Photo or video has been taken within the server's life time and if the user did not decide to hide this area.
The bottom left quarter presents function buttons for [Photo/Video taking](./Phototaking.md)
In addition, there are also buttons controlling the photo buffer to which users can add or remove individual photos and navigate between them.
Raw photos or videos are not shown directly. Instead a placeholder in the configured photo format is shown.
### Bottom Right Quarter
Here, the metadata of the currently visible photo/video are shown.
The metadata are captured within the same **Capturing Request** together with the photo itself.
In the case of videos, the metadata are captured immediately before recording starts.
Alternatively to metadata, the histogram of the photo can be shown.
## Accessing the Direct Control Panel
For fine tuning all numeric control parameters (e.g. *Focal Distance*, *Zoom Factor*, *Contrast*, etc.), you can use the [Direct Control Panel](./LiveDirectControl.md).
When hovering with the mouse over the Live Stream area, you will get a hint:

Before clicking on the Live Stream, you will need to activate those control parameters which you want to adjust:
- [Focal Distance](./FocusHandling.md)
- [Zoom Factor](./ZoomPan.md) (does not require activation)
- [Exposure Time](./CameraControls_Exposure.md)
- [Exposure Value](./CameraControls_Exposure.md)
- [Analogue Gain](./CameraControls_Exposure.md)
- [Colour Gain](./CameraControls_Exposure.md)
- [Sharpness](./CameraControls_Image.md)
- [Contrast](./CameraControls_Image.md)
- [Saturation](./CameraControls_Image.md)
- [Brightness](./CameraControls_Image.md)
Some of these parameters might not be available if the Active Camera is a USB camera.
Furthermore, if you want to restrict to a specific image section, you need specify this on the [Zoom](./ZoomPan.md) window first.
The [Direct Control Panel](./LiveDirectControl.md) allows only zooming into that window but not changing the window itself.
================================================
FILE: docs/PhotoSeries.md
================================================
# raspiCamSrv Photo Series
[](./UserGuide.md)
The *Photo Series* screen allows the management of different kinds of Photo Series and includes means for series configuration, lifecycle management, photo shooting and supervision.
A series is a sequence of photos taken with specific time intervals. Special kinds of series are [Timelapse Series](./PhotoSeriesTimelapse.md), [Exposure Series](./PhotoSeriesExp.md) and [Focus Stacks](./PhotoSeriesFocus.md).

## Creation of a new Series
When the *Photo Series* screen is opened for the first time, it offers the option to create a new series:

You need to enter a unique name for the series. Since the name will be used as folder name and as part of the filename for photos, you need to consider any restrictions for systems where you want to store and process these files.
Linux is quite tolerant in this aspect but it is recommended using only letters, numbers and underscore characters.
## Series Configuration
When a series is initially created, some parameters are predefined which later need to be configured:

- The lifecycle of a Photo Series is represented as its **Status**.
Transitions between different states can be initiated by one or two buttons at the right of the series selection combo box.
For details see the [Series State Chart](#photo-series-state-chart).
- If multiple series have been created, the **active series** can be selected with a combo box showing the series names.
- The *Series Type* distinguishes "Normal" series without special characteristics from specialized series, such as "Exposure Series", "Focus Stacks" or "Timelapse Series".
- The *Path* is the path where all resources for the series are located.
For details see [Photo Series in the File System](#photo-series-in-the-file-system)
- The system has also initialized a [Series Configuration File](#series-configuration-file) a [Series Log File](#series-log-file) and a [Camera Settings File](#series-camera-file).
- In addition, a "hist" subdirectory has been created where histogram images will be stored (currently only for *Exposure Series*).
- Under *Photo Type*, it can be selected whether only ```jpg``` or ```raw+jpg``` photos shall be taken.
- The *Start* time is initiated with the current time.
This needs to be set to the time when the series shall start.
- The *End* time can be set explicitly if a specific end time is required.
If this is done, the number of shots will be calculated based on the specified *Interval*
- As *Interval* , the time difference (in seconds) between successive shots can be specified.
From experience, the system will observe the given value within a tolerance of about 30 ms.
- *On Dial Marks* specifies whether the shots shall be taken on whole hours, quarters, minutes, ..., depending on the intarval.<br>For example, if the interval is 900 sec, photos will be taken exactly (within tolerances) at :00, :15, :30, :45, or if the interval is 3600 sec, photos will be taken every full hour.
- The *Number of Shosts* specifies the numper of photos intended for the series.
If the *End* time has not been explicitly specified, it will be calculated from *Interval* and *Number of Shots* considering the specified *Start* time.
- The checkbox *Cont. on Server Start* allows to automatically continue an active series in case of a server restart.
Such a situation may happen if the server is stopped (explicitly or implicitly with a device shutdown) while a series is active.
For example, if you have a long running timelapse series, there might be power outages forcing a system reboot. If you have set the series to automatic continuation it will be continued as soon as the server is restarted. Otherwise, it will be in status PAUSED.
Automatic continuation is not used for [Exposure Series](./PhotoSeriesExp.md) or [Focus Stack](./PhotoSeriesFocus.md) series because these series are typically not running for a longer time.
After the values have been entered, pressing the *Submit* button will calculate dependent parameters an change the [status](#photo-series-state-chart) of the series to "READY".
**For Photo Series of type [Exposure Series](./PhotoSeriesExp.md), [Focus Stack](./PhotoSeriesFocus.md) and [Timelapse Series](./PhotoSeriesTimelapse.md), additional configurations are required.**
## Series Start
A series in state "READY" can be started with the *Start* button.
This will execute the following steps:
1. Set the status to "ACTIVE"
2. Configure the camera with the active [Configuratien](./Configuration.md) for "Photo" or "Raw Photo", depending on the selected *Photo Type*
3. Apply the active [Camera Controls](./CameraControls.md)<br>For [Exposure Series](./PhotoSeriesExp.md) and [Focus Stack](./PhotoSeriesFocus.md), specific controls will be adjusted or varied for each photo.
4. Start the camera
5. Wait until the start time
6. Execute the necessary capture request (jpg, dng, metadata)
7. Store the metadata in the [Series Log File](#series-log-file)
8. Store the camera configuration as well as the controls parameters, which have been applied before request execution, in the [Camera Settings File](#series-camera-file)
9. Wait until the next interval and repeat steps from 6. until either the configured *Number of Shots* or the configured *End* time has been reached.
10. Finally, the series status will be "FINISHED".
While the series is "ACTIVE", this is shown by the Series status indicator and the screen will show the progress:

In the *Preview* area, the time for the next photo to be taken is shown and the progress bar shows the time remaining.
When the photo time is reached, the page will be reloaded and the latest photo will be shown on top. The last 20 photos are available in the scroll area.
## Downloading a Series
A series can be downloaded at any time after it has been created.
Whether or not a series has been downloaded is shown under *Downloaded* which is either "Never" or the time of the last download.
Pushing the *Download* button will require a confirmation before download will be executed.
The download will be named ```raspiCamSrvSeries_<name>_<YYYYMMDDHHMMSS>``` with the timestamp of the download.
The download is a zip archive including the entire folder structure of the series (see [Photo Series in the File System](#photo-series-in-the-file-system)):
- All photos taken until the time of download
- The [Series Cofiguration file](#series-configuration-file)
- The [Series Camera File](#series-camera-file) (which will be empty if no camera configuration has been attached to the series)
- The [Series Log File](#series-log-file) (which will be empty if the series has not yet been started)
- A subfolder ```hist``` containing histograms, in case the series has been an [Exposure Series](./PhotoSeriesExp.md)
## Finished Series
When a series has ended or after it has been actively finished with the *Finish* button, its status is shown as "FINISHED":

If the series has been downloaded after it had ended, can be seen by comparing the respective timestamps.
## Live Stream
### Active Live Stream
If the [Configuration](./Configuration.md) for the *Photo* and *Raw Photo* use cases are compliant with the configuration for *Live View*, the Live Stream will not be interrupted while the series is ACTIVE.
For more details, see [raspiCamSrv Tasks and Background Processes](./Background%20Processes.md)
Simultaneous activity of Live Stream and Photo Series is indicated by the process status indicators:

If the series is an [Exposure Series](./PhotoSeriesExp.md) or a [Focus Stack](./PhotoSeriesFocus.md) Series, [Camera Controls](./CameraControls.md) will be modified while the series is active.
*Auto Exposure* and *Auto White Balance* will be deactivated and other parameters, such as *Exposure Time*, *Analogue Gain* or *Focal Distance*/*Lens Position* will vary from photo to photo.
These variations will be visible in the Live Stream.
After the series is FINISHED, the original control parameters will be restored.
### Paused Live Stream
If the Live Stream is paused because photo taking requires exclusive camera access because of specific [Configuration](./Configuration.md) (see [raspiCamSrv Tasks and Background Processes](./Background%20Processes.md)), this is indicated by the process status indicators:

and a placeholder image will be schown instead of the Live Stream:

## Interrupting an ACTIVE Series
While a Photo Series is ACTIVE, photo- and video taking is disabled:

The thread in which the Photo Series is executed, checks every 2 seconds whether a request to pause or stop has been issued.
If the series shall be paused and (possibly) continued later, the *Pause* button in the *Series* screen can be used.
If the series shall be interrupted and terminated, the *Finish* button can be used.
## Attaching Camara Configuration to a Photo Series
Before a Photo Series is started, normally the camera [configuration](./Configuration.md) and [controls](./CameraControls.md) will manually be adjusted for optimal photo quality.
These settings (configuration **and** controls) can be attached to a Photo Series with the *Attach Camera Config* button.
These will be persisted in the [series configuration file](#series-configuration-file)
If this has been done, the system offers to activate these settings at a later time:

So, if another series shall be run with the same or a similar setup, the camera configuration and control settings can be reused after they have been activated.
This feature can also be used to persist specific settings under an indicative name (the series name), also if it is not intended to really run such a series.
## Photo Series State Chart

## Photo Series in the File System
All resources related to a Photo Series are stored in the file system under
```/home/<user>/prg/raspi-cam-srv/RaspiCamSrv/static/photoseries/<name>```
where ```<user>``` is the user ID specified during [system setup](./system_setup.md) and ```<name>``` is the name of the series.
After [Creation of a new Series](#creation-of-a-new-series), the folder has been created and a [Series Configuration File](#series-configuration-file), a [Series Log File](#series-log-file) and a [Series Camera File](#series-camera-file) have been initiated:
.
After the series has been [started](#series-start), also all photos (.jpg) and, if selected, also the raw photos (.dng) can be found in this folder:
.
Typically, photo series will be processed on another system, especially if they have been taken with a Raspberry Pi Zero system.
**RaspiCamSrv** does not provide any means to download or transfer these data. There are numerous tools to achieve this (e.g. scp, Samba)
### Series Configuration File
The file ```<name>_cfg.json``` contains the entire configuration of a series, including, if attached, the camera configuration and camera controls.

When the server starts up, all folders under ```.../photoseries``` are searched for a configuration file and series configurations are created from their contents. These will then be available in the **raspiCamSrv** *Photo Series* dialog.
### Series Log File
The file ```<name>_log.csv``` contains log entries for each photo of the series:

Bisides the name of the photo and the time of creation, the most important metadata are included which have been captured in the same request as the Raw Photo and / or jpg Photo.
### Series Camera File
The file ```<name>_cam.json``` contains a JSON structure with the [camara configuration](./Configuration.md) and the [camera controls](./CameraControls.md) applied for each photo of the series. This is available only for [Exposure Series](./PhotoSeriesExp.md) and [Focus Stack Series](./PhotoSeriesFocus.md).

================================================
FILE: docs/PhotoSeriesExp.md
================================================
# Photo Series of type "Exposure Series"
[](./PhotoSeries.md)
Exposure series iterate through a specified range of an exposure parameter, keeping all other exposure parameters constant.
In general, exposure is controlled by three parameters: aperture, exposure time and ISO value.
Raspberry Pi cameras have a fixed or manually controlled aperture and ISO values are not standardized.
Instead of ISO values, the Analogue gaing can be set. Roughly, the relation is *ISO* = 100 * *AnalogueGain*.
The *Exposure Series* subdialog allows specifying necessary parameters for series where either *Exposure Time* or *Analogue Gain* is varied.
**NOTE**: This function is not available for USB cameras.

The dialog references the active Photo Series which is managed in the [Series](./PhotoSeries.md) subdialog of the *Photo Series* dialog.
The *Number of Shots* is shown here, because it will be affected by the chosen *Start*, *Stop* and *Interval* values.
To configure the active Photo Series as *Exposure Series*, proceed as follows
1. Activate the *Exposure Series* checkbox
2. Select the exposure parameter which shall be kept at a fixed value by checking one of the check boxes under *Exposure Time* or *Analogue Gain*
3. For the selected parameter, enter the intended value in the *Start* field.
4. Now, specify *Start* and *Stop* values for the variable parameter
5. The interval is specified in terms of photographic [Exposure Values](https://en.wikipedia.org/wiki/Exposure_value) (EV)<br>With a value of 1/3 EV the series is obtained by multiplying the last value of *Exposure Time* or *Analogue Gain* by 2**(1/3) to get the next value.<br>With a value of 1 EV, the factor is 2**(1)=2<br>and with 2 EV, the factor is 2**(2)=4.<br>1/3 EV is the typical raster value for commercial cameras when modifying either aperture, exposure time or ISO.
Finally push the **Submit** button to store the specified value.
This will recalculate the *Number of Shots* required for the series.
To start photoshooting, go to the [Series](./PhotoSeries.md) subdialog
## Result
After the series has finished, the results can be inspected on the *Exposure Series* subscreen:

Together with each photo, the screen shows a histogram and characteristic metadata:
- Exp: Exposure Time in seconds
- Gain: Analogue Gain
- Lux: An estimation of the brightness
More information can be gained from
- the [Series Camera File](./PhotoSeries.md#series-camera-file) which lists the configuration and control parameters applied before shooting a photo
- the [Series Log File](./PhotoSeries.md#series-log-file) which lists the metadata captured together with each photo.
## Parameter Table (1/3 EV)
The following table contains systematic values for Exposure Time and Analogue Gain with 1/3 EV, corresponding roughly to commercial camera settings

## Parameter Table (1 EV)
The following table contains systematic values for Exposure Time and Analogue Gain with 1 EV, corresponding roughly to commercial camera settings

================================================
FILE: docs/PhotoSeriesFocus.md
================================================
# Photo Series of Type "Focus Stack"
[](./PhotoSeries.md)
A Focus Stack series iterates the Lens Position (or Focal Distance).
With suitable software, such a stack can be combined to achieve a large Depth of Field (DoF).
**NOTE**: This function is not available for USB cameras.

To create a focus stack, you can proceed as follows:
1. In the [Live Screen](./LiveScreen.md) use [Focus Handling](./FocusHandling.md) to determine the Focal Distance for the nearest and the furthest point of the scene.
2. After initializing a Photo Series in the [Series](./PhotoSeries.md) subscreen, open the *Photo Stack* subscreen and check *Focus Stacking Series*
3. Then enter the nearest and furthest Focal Distance as *Start* and *Stop* values and choose a suitable *Interval*
4. Push **Submit** to configure the series
5. In the [Series](./PhotoSeries.md) subscreen, start the Photo Series
The result will be shown in the *Focus Stack* subdialog:

Together with each photo, characteristic metadata are shown:
- The *Lens Position* with which the photo was taken<br>(reciprocal of Focal Distance)
- The *Focal Distance* which was varied within the series
- The *Focus FoM*, a Figure of Merit (FoM) to indicate how in-focus the frame is. A larger FocusFoM value indicates a more in-focus frame.
More information can be gained from
- the [Series Camera File](./PhotoSeries.md#series-camera-file) which lists the configuration and control parameters applied before shooting a photo
- the [Series Log File](./PhotoSeries.md#series-log-file) which lists the metadata captured together with each photo.
================================================
FILE: docs/PhotoSeriesTimelapse.md
================================================
# Photo Series of Type "Timelapse"
[](./PhotoSeries.md)
This screen allows special configurations for Photo Series in the Timelapse domain.
Of course, every normal Photo Series can be used for Timelapse purposes. However, users often require specific features like specific time slots for multi-day series or automatic exposure adjustment during sunset/sunrise phases (Autoramping / "Timelapse Holy Grail").
This page is dedicated to this kind of configuration settings.
Currently, raspiCamSrv supports the following *Sun-control Mode*s:
- *Sunrise/Sunset*
<br>limiting photo shooting to configurable periods depending on sunrise and sunset.
- *Azimuth*
<br>taking photos at specific azimuth values over a period of days so that photos are taken with the same horizontal direction of sun.
Usage of this feature requires calculation of sunrise and sunset, depending on date.
The algorithm (see [Sunrise Equation](#sunrise-equation)) requires information about the geografic coordinates of the camera position.
These need to be specified on the [Settings](./Settings.md) screen before a Series can be classified as "Sun-controlled".
It is recommended to [store the configuration](./SettingsConfiguration.md#server-configuration-storage) in order to have these settings available after a server restart.
## Sunrise/Sunset Mode
When this screen is activated after a [new Series](./PhotoSeries.md#creation-of-a-new-series) has been created, it will be initialized with *Sunrise/Sunset* mode:

- The fields **Series**Name, **Interval** and **Number of Shots** refer to the same parameters as screen [Series](./PhotoSeries.md).
- Activating the checkbox **Sun-controlled Series** will activate selective photo shooting in periods depending on sunrise and/or sunset.
- You can specify the **Number of Days** for which the series shall be active
- The fields **Sunrise** and **Sunset** will show values for the current day.<br>If the series will be running for several days, sunrise and sunset will be calculated individually for every day.
- The system allows the definition of two periods per day during which photos will be shot with the given **Interval**:<br>These are named **Period 1** and **Period 2**
- At least for **Period 1**, you need to specify **Start** and **End**<br>If only one is specified, the system reports an error and does not persist the specified data.<br>**Start** and **End** are specified if the **Reference** is not "Unused".
- The **Reference** specifies whether "Sunrise" or "Sunset" will be used to limit the intended period.
- For each **Period**s **Start** and **End**, you can specify a time **Shift** in Minutes by which the start or the end of the period will be shifted with respect to the selected **Reference**.<br>The **Shift** can be positive or negative.
- After **Submit**, the system will calculate **Todays Values** for **Start** and **End**.
- Also the time for the **Next Shot** will be shown.
When submitting entries with a reasonable interval and Number of Days, the system will recalculate the required **Number of Shots** as well as the expected **End** of the Series, shown on the [Series](./PhotoSeries.md) screen.

### Example: Single Period for Daylight Photos

### Example: Two Periods around Sunrise and Sunset

## Azimuth Mode
When choosing *Sun-Control Mode* "Azimuth", the screen layout will change to

- *Time for Azimuth*
<br>can be used to calculate the azimuth at a specific time.
<br>When its value is not explicitely set, it will be updated with the current date/time.
- *Azimuth [°]*
<br>is the azimuth at the given time
- *Elevation [°]*
<br>is the elevation of the sun above horizon at the given time
- *Azimuth 1*, ... *Azimuth 4*
<br>Here, you can specify up to 4 azimuth values for which photos shall be taken at every day within the specified number of days from series start.
<br>For each value the *Todays Time* at the current day will be calculated when the sun position will have this azimuth.
<br>The system will also verify that azimuth values are valid for the entire period of the series. If this is not the case, an error message will be shown.
<br>When entering more than one azimuth value, these will be sorted with increasing times.

### Series Log File
For photo series using *Azimuth* Mode, the [Series Log File](./PhotoSeries.md#series-log-file) will include the Azimuth value for each photo:

## Sunrise Equation
The algorithm for the sunrise/sunset equation has been taken from Wikipedia:
[https://en.wikipedia.org/wiki/Sunrise_equation](https://en.wikipedia.org/wiki/Sunrise_equation)
This article also publishes Python code which has been taken as is (version from August 11, 2024, 14:18) and integrated with minor technical adjustments into the RaspiCamSrv Flask server code.
Comparison of the results from this algorithm with those from the "NOAA Solar Calculator" ([https://gml.noaa.gov/grad/solcalc/](https://gml.noaa.gov/grad/solcalc/)) for the time of writing at the author's location showed a deviation of -2 Minutes for sunrise and +3 Minutes for sunset.
However, the NOAA Calculator does not seem to take elevation into account.
================================================
FILE: docs/PhotoViewer.md
================================================
# raspiCamSrv Photo Viewer
[](./UserGuide.md)
All photos, raw photos or videos taken wit **raspiCamSrv** are stored in a camera-specific folder on the server.
Currently, the folder is located within the folder where Flask expects static content
(```~/home/prgraspi-cam-srv/raspiCamSrv/static/photos/camera_n``` (n=0, 1)).
The full path of the folder for the active camera is shown in the [Settings](./Settings.md) screen.
The current implementation of **raspiCamSrv** includes a very simple viewer which allows inspecting the available photos and videos as well as downloading and deleting selected files:

On the left side, a selection of photos (.jpg placeholders for raw and video) are shown in a scroll area in reverse order with the newest one on top.
The file name in the photo (or placeholder) shows the correct filename of the resource represented by the picture.
A large view of the photo or a video player is presented when a specific picture has been clicked on.
- You need to select the **Camera** for which photos shall be shown.<br>In systems with multiple cameras, photos taken with a camera are stored in a camera-specific folder.
- **From** and **To** date selectors allow restricting photos to a specific range of dates<br>When initially starting the dialog, the current day is selected.<br>Internally, **From** has time 00:00:00 and **To** 23:59:59.
- Button **Today** restricts the time range to the current date
- Button **All** sets **From** to January 1st, 1970 and **To** to today.
- On the left of each thumbnail picture, there is a **checkbox** where you can select photos or videos for download or for deletion.
- Buttons **Select all** and **Deselect all** apply to all photos currently shown in the scrolling area.
- With button **Delete** you can delete all selected photos<br>Before deletion is executed, a confirmation is required.<br>If a specific media (e.g. video or raw photo) incudes the media file itself, a jpg placeholder and an optional histogram file, all are deleted.<br>Deletion of photos also clears the [Photo Display Buffer](./Phototaking.md#photo-display).
- With the **Download** button, you can download the selected files.<br>Also here, a confirmation is required.<br>If more than one file has been selected, the selected files will be zipped into a file named *raspiCamSrvMedia_YYYYMMDD_HHMMSS.zip*<br>If a single file is selected, it will be downloades as is.<br>Placeholders for raw and videos as well as histogram are not included in the download.
================================================
FILE: docs/Phototaking.md
================================================
# raspiCamSrv Photo Taking and Video Recording
[](./LiveScreen.md)
The *Live* tab of **raspiCamSrv** provides functionality to take photos, raw photos and videos.
In all cases, the predefined [Camara Configuration](./Configuration.md) for the specific use case is applied together with the currently activated [Camera Controls](./CameraControls.md).
As long as no photo has been taken, the *Live* screen will show like below:

Now, you can use
- the **Photo** button to take a photo,
where the file type can be selected in the [Settings](./Settings.md) screen. ("jpg" is recommended)
- the **Raw** button to take a raw photo.
Currently only the *.dng* format is supported.
- the **Video** button to record a video,
where for the video format you may choose between *.mp4* and *.h264* in the [Settings](./Settings.md). Recommended is *.mp4*
## Photo / Raw Photo
If the *Photo*/*Raw Photo* [Configuration](./Configuration.md) is not compliant with the *Live View* configuration, the live stream will be shortly interrupted in order to allow the system to apply the [Camera Configuration](./Configuration.md) for these use cases.
For more details, see [raspiCamSrv Tasks and Background Processes](./Background%20Processes.md)
The photo (in the case of raw photos a placeholder photo) will be shown in the bottom area of the screen together with the Metadata.
## Video
### With active Live Stream
When video recording is started, the system will first check whether the required [Camera Configuration](./Configuration.md) is compliant with the configuration of the active Live Stream.
If this is the case, first a normal photo of the scene will be taken, which will be used as placeholder. This will be shown in the bottom area.

The **Video** button has changed to **Stop** which must be used to stop video recording.
If audio is recorded along with video (see [Settings](./Settings.md#recording-audio-along-with-video)), this will be indicated by the process indicator:

### With paused Live Stream
If video recording requires exclusive camera access because of specific configuration (see [raspiCamSrv Tasks and Background Processes](./Background%20Processes.md)), the live stream will be paused and a placeholder is shown instead:

## Photo Display
When a photo, raw photo or video has been taken, the bottom area will show the photo together with its Metadata or its histogram:

The file name for the photo, raw photo or video has been generated automatically based on system date/time when the request is issued to the camera.
Above the photo, some buttons are shown which allow manipulation of a display buffer:

- Pressing the **-** button will remove the photo from display.
It will not be removed from the file system.
- The active **+** button shows that the photo is not yet a member of the display buffer.
Pressing this button will add it to the buffer.
This is shown as:

The indicator (x/y) above the **+** button shows the position of the Photo within the buffer as the left number and the total number of photos in the buffer as the right number.
With the larger number of photos within the buffer, navigation buttons **<** and **>** allow navigation within the buffer:

Additional buttons are available:
- **Hide** / **Show** can be used to hide or show the bottom area with the display buffer
- **Clr(x)** will clear the entire buffer.
The number in brackets is the total number of elements in the buffer.
- **<** will display the previous photo in the buffer
- **>** will display the next photo within the buffer
- **-** when applied to a member of the buffer, will remove it from the buffer
## Metadata
Along with a photo, also its metadata will be shown.
Metadata and photo have been captured within the same capturing request.
For the metadata, tooltips on the metadata properties explain the respective parameter.
**Previous** and **Next** buttons allow scrolling the list of metadata if it does not fit on the screen.


## Histogram
Alternatively to the metadata, you may also switch to Histogram if usage of histograms has been activated in the [Settings](./Settings.md).

The setting whether metadata or histogram are shown, is kept and remains active also when the next photo is taken or when scrolling through the Photo Buffer.
Histogram graphics are calculated on the fly when they are requested for the first time.
They are stored in a "hist" subfolder under the *Path for Photos/Videos* (see [Settings](./Settings.md))
================================================
FILE: docs/ReleaseNotes.md
================================================
# Release Notes
[](./index.md)
## V4.10.0
### New Features
- [Photo Series of Type "Timelapse"](./PhotoSeriesTimelapse.md) were extended with a new [Azimuth Mode](./PhotoSeriesTimelapse.md#azimuth-mode). This allows taking multi-day photo series where photos are taken at times when the sun position has specific azimuth values.
- Extended capabilities of ```GET api probe``` [API](./API.md) WebService endpoint:
Now, the ```PhotoSeriesCfg``` object and its properties are accessible which represents the settings for photo series.
- [Information / Software Stack](./Information_Sys.md) now also shows version of libcamera.
- A tutorial has been added which shows how to enable [Neural Network-based Automatic White Balance](./tutorials/AWB_with_neural_networks.md)
### Bugfixes
- Empty *ID* is no longer possible when creating a new [Device](./SettingsDevices.md)
- Fixed error ```AttributeError: 'Picamera2' object has no attribute 'allocator'``` which could occur when the Flask server was started or restarted with an active [Photo Series](./PhotoSeries.md) for which *Cont. on Server Start* was active.
- Fixed errors which could occur when creating Histograms ([Photo Taking on Live screen](./Phototaking.md#histogram) or [Exposure Series](./PhotoSeriesExp.md))
<br>This resolves [raspi.cam-srv Issue #89](https://github.com/signag/raspi-cam-srv/discussions/89).
## V4.9.0
### New Features
- New [Actions](./TriggerActions.md) can now be immediately [tested](./TriggerActions.md#testing-an-action) before they are used in a [Trigger assignment](./TriggerTriggerActions.md) or in an assignment to an [Action Button](./SettingsAButtons.md) or a [Live Button](./SettingsLButtons.md).
- [Device Type Configuration](./SettingsDevices.md#device-type-configuration) for [gpiozero Output Devices](https://gpiozero.readthedocs.io/en/stable/api_output.html#regular-classes) has been extended to allow [Action Configuration](./TriggerActions.md) for more action methods:
<br>LED : toggle, blink, value
<br>PWMLED: toggle, blink, pulse, value
<br>RGBLED: on, off, toggle, blink, pulse
<br>Buzzer: toggle, beep, value
<br>Motor : reverse
## V4.8.0
### New Features
- Added [Ctrl Pane](./CameraControls_Ctrl.md) to [Live Screen](./LiveScreen.md) for which you can [configure buttons](./SettingsLButtons.md) for execution of OS commands or [Actions](./TriggerActions.md) for control of various devices such as servos for Pan/Tilt control.
- Added [ServoPWM](./gpioDevices/ServoPWM.md) as new [Device Type](./SettingsDevices.md).
<br>This can be used as alternative to [gpiozero Servo](https://gpiozero.readthedocs.io/en/stable/api_output.html#servo), which uses software PWM (pigpio is currently not available under Trixie) resulting in significant jitter and is, therefore, not suitable to be used as device for camera positioning.
<br>ServoPWM is based on the [rpi_hardware_pwm](https://github.com/Pioreactor/rpi_hardware_pwm) library and assures jitter-free servo control.
- The [installation](./installation.md) has been extended with installation of [rpi_hardware_pwm](https://github.com/Pioreactor/rpi_hardware_pwm) required for [ServoPWM](./gpioDevices/ServoPWM.md)
- Git now ignores a folder ```prg/raspi-cam-srv/user_code``` and any sub-folders.
<br>This allows putting any bash scripts or python programs in this location for use with [Versatile Buttons](./SettingsVButtons.md) or [Live Buttons](./SettingsLButtons.md).
### Bugfixes
- Fixed ```TypeError: object of type 'CompletedProcess' has no len()``` which could occur when the server was restarted with button *Restart Server* in [Settings / Configuration](./SettingsConfiguration.md)
- Fixed command execution from [Interactive Commandline](./ConsoleVButtons.md#interactive-commandline): In some situations it could happen that after command execution a different dialog was shown.
- Created clearer error message in [Settings/Devices](./SettingsDevices.md) when test or calibration was started while [Event Handling](./TriggerControl.md) is active. Active event handling may have exclusive access on devices.
- If a [Device Configuration](./SettingsDevices.md) has been modified while [Event Handling](./TriggerControl.md) is active, a hint to restart Event Handling is now displayed.
- Fixed missing values for *Number of Rows* and *Number of Columns* in dialog [Settings/Action Buttons](./SettingsAButtons.md)
- Fixed error ```Error in None: Error <class 'TypeError'> while executing action STP1-0: StepperMotor.rotate_to() got an unexpected keyword argument 'angle'```
## V4.7.1
### Bugfix
- Fixed issue with checkboxes in dialog [Photos](./PhotoViewer.md).
<br>For images where the descriptive text (filename) was larger than the image width, the checkbox was covered and could not be individually selected.
<br>Resolves [raspi-cam-srv Issue #86](https://github.com/signag/raspi-cam-srv/issues/86)
## V4.7.0
### New Features
- As an alternative to the Flask buil-in WSGI server (werkzeug), for publicly accessible systems, now [Gunicorn](https://gunicorn.org/) ('Green Unicorn') is supported.
Gunicorn is now default for the [Automatic Installer](./installation.md) as well as for the [Docker Image](./SetupDocker.md).
If you want to switch your existing installation to run with Gunicorn, just run the [Installer](./installation.md#installer) over your existing installation and confirm to use Gunicorn.
- [Info/System](./Information_Sys.md) now includes information on the [WSGI server running](./Information_Sys.md#wsgi-server)
### Changes
- The [Info](./Information.md) screens were restructured. [System](./Information_Sys.md) and [Cameras](./Information_Cam.md) are now separated.
### Bugfixes
- Fixed error ```TypeError: CameraController.requestStop() got an unexpected keyword argument 'forCam2'``` which could occur in specific cases when a video was recorded.
- Fixed error ```Camera.framesUsb - Exception: cannot access local variable 'cfg' where it is not associated with a value``` which could occur in specific situations if a USB camera could not be opened.
- Fixed issue in [Settings (No Camera)](./Settings_NoCam.md) where an error occurred when *Use USB Camera* is activated.
## V4.6.1
### Bugfixes
- Fixed deactivation of [Settings / *Use Camera AI*](./Settings.md#activating-and-deactivating-the-use-of-camera-ai-features):
If a live stream is active with activated AI, the live stream is now restarted without AI.
- Fixed [Config](./Configuration.md) for the case when the last active tab was *AI Configuration* and *Use Camera AI* was deactivated in [Settings](./Settings.md). In this case, the [Configuration for AI](./Configuration_AI.md) section was erronously visible.
- Fixed errors which occurred during Docker container startup in case of [Running raspiCamSrv as Docker Container](./SetupDocker.md) (resolves [raspi-cam-srv Issue #83](https://github.com/signag/raspi-cam-srv/issues/83)):
.. Added ```dpkg-dev``` to the ```Dockerfile```
.. Skipping check of time sync in case raspiCamSrv is running in a container (see hint in [Info dialog](./Z_Legacy_Information.md#raspberry-pi))
- Fixed support of USB WebCams when [Running raspiCamSrv as Docker Container](./SetupDocker.md).
.. Added ```v4l-utils``` to the ```Dockerfile```
- Fixed error ```FileNotFoundError: [Errno 2] No such file or directory: '/sys/kernel/debug/imx500-fw:11-001a/fw_progress'``` for [AI Camera Support](./AiCameraSupport.md) in the case when [Running raspiCamSrv as Docker Container](./SetupDocker.md).
.. Extended ```docker-compose.yml``` to expose ```/sys/kernel/debug/imx500-fw``` to the container.
## V4.6.0
### New Features
- Support of AI features for the [Raspberry Pi AI Camera](https://www.raspberrypi.com/documentation/accessories/ai-camera.html):
<br>You can specify the neural network model to be used by the camera (see [Camera AI Configuration](./Configuration_AI.md)) and see inference information visualized in the Live stream or on photos or videos.
See [AI Camera Support](./AiCameraSupport.md)
### Changes
- The behavior of the Live view at camera start has been changed. Especially, in order to avoid irritation about long startup times for the imx500 [AI Camera](https://www.raspberrypi.com/documentation/accessories/ai-camera.html), **raspiCamSrv** shows an [animation while the camera is starting](./UserGuide.md#live-stream-at-camera-start).
- Maximum for [Buffer Count](./Configuration.md#buffer-count) in [Camera Configurations](./Configuration.md#configuration-tab) is increased from 6 to 12. The larger value has been used in the [imx500 examples of Picamera2](https://github.com/raspberrypi/picamera2/tree/main/examples/imx500)
## V4.5.0
### New Features
- [Direct Control Panel](./LiveDirectControl.md) added to [Live View](./LiveScreen.md#accessing-the-direct-control-panel) for fine tuning of numeric [Camera Control](./CameraControls.md) parameters.
- Added additional endpoints for photo snapshots with high resolution. Previews are available in the [Cam/WebCam](./CamWebcam.md) dialog. Please note the [special restrictions](./CamWebcam.md#photo-snapshot).
Covers [raspi-cam-srv Issue #79](https://github.com/signag/raspi-cam-srv/issues/79)
### Changes
- Style sheet switched to [W3.CSS](https://www.w3schools.com/w3css) 5.02
### Bugfixes
- Fixed ```TypeError: stat: path should be string, bytes, os.PathLike or integer, not NoneType``` which could occur after a [Reset Server](./Settings.md#configuration)
## V4.4.1
### Bugfix
- Fixed the update procedure with dialog [Settings/Update](./SettingsUpdate.md).
The procedure implemented in V4.3.2 did not work correctly.
Although it confirmed that the update was successful, the version remained at the old version after restart.
If you were running into that issue, you should
-- ```ssh``` to the server
-- ```cd prg/raspi-cam-srv```
-- ```git reset --hard origin/main```
The [Update Procedure](./updating_raspiCamSrv.md) has been modified, accordingly.
For versions 4.4.1 and later, the [Settings/Update](./SettingsUpdate.md) procedure should work correctly.
## V4.4.0
### New Feature
- [Media Viewer](./UserGuide.md#media-viewer) added to all images and videos in the UI.
## V4.3.2
### New Feature
- [raspiCamSrv Version Updates](./SettingsUpdate.md) supports periodical search for updates on GitHub with indication of new versions and version update as well as server restart from the UI.
## V4.3.1
### Bugfix
- Fixed the issue with bad Live Stream quality for Raspberry Pi models ```<``` 5.
When starting the live stream, raspiCamSrv usually configurs the camera with all 3 streams (lowres, main, raw), so that the live stream (lowres) can remain active while photos (main), raw photos (raw) or videos (main) are taken.
For Raspberry Pi Zero and other models ```<``` 5, it turned out that the stream quality is bad when the raw stream is included in the configuration.
Now, for models ```<``` 5, the raw stream is excluded from the configuration for the live stream, resulting in better quality.
For these models, when a raw photo is taken, the live stream will be temporarily stopped and reactivated without raw stream configuration after the raw photo has been stored.
## V4.3.0
### Changes
- Documentation has been moved to [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/).
The entire documentation will be versioned with the software and Online Help links will point to documentation with the version of the software, rather than to the latest version.
## V4.2.0
### New Features
- For [Motion Detection](./TriggerMotion.md), *Regions of Interest* as well as *Regions of NO Interest* can be specified.
These are respected during Motion Detection for CSI as well as USB cameras and for all *Motion Detection Algorithms*
- In case of multiple cameras, the camera-related [Ttigger](./Trigger.md) settings ([Trigger/Motion](./TriggerMotion.md) and [Trigger/Camera](./TriggerCameraActions.md)) are now camera-specific.
When the active camera is switched, these settings are replaced by those which had been defined and [saved for camera switch](./CamMulticam.md#save-active-camera-settings-for-camera-switch) for the new camera, before.
This is especially important when regions of interest are used for motion detection. These settings will not be lost when cameras are switched.
- [Backup and Restorage](./SettingsConfiguration.md) of configuration and other stored data.
### Bugfixes
- For USB cameras an error occurred when *Focus* was set to 0.0 with *Autofocus Mode* "Manual". This is now fixed.
- For [Motion Capturing](./TriggerMotion.md) with USB cameras, the frame rate for video recording was increased from 14.5 to 30. With this frame rate, the video length is in better accord with the configured duration.
## V4.1.0
### New Features
- [Zoom and Pan](./ZoomPan.md) are now also available for USB Cameras.
- [Focus handling and Image Controls](./CameraControls_UsbCams.md) are now available for USB Cameras.
**NOTE** These features have currently been tested with different Logitech cameras. Please notify if other cameras show unexpected behavior.
### Changes
- For USB cameras, it is no longer possible to choose *Sensor Mode* "Custom" for the different [Configuration](./Configuration.md) scenarios. Practical experience with web cams has shown that these do not support other image sizes as those defined in the discrete formats (sensor modes). The camera would always use the smallest standard format which entirely contains the specified area. Therefore, it does not make sense allowing the specification of a custom format, if the camera will not use it.
- For USB cameras, the aspect ratio for *Stream Size* of different [Configuration](./Configuration.md) use cases is not synchronized. For these cameras, the checkbox [Sync Aspect Ratio](./Configuration.md#configuration-tab) is unchecked and disabled.
## V4.0.3
### Extension
- In the [Info](./Z_Legacy_Information.md) dialog, the section [Raspberry Pi](./Z_Legacy_Information.md#installed-cameras) was extended with information on the software stack, which can be helpful analyzing errors which could occur with specific versions or installation details.
## V4.0.2
### Bugfixes
- Fixed error which occurred when changing the *Active Camera* in [Settings](./Settings.md) to a USB camera
## V4.0.1
### Bugfixes
- Fixed error "Error ```<class 'ValueError'>``` : Class Camera has no element when_motion_detected"
Cause of the error was a wrong configuration for [Triggers](./TriggerTriggers.md) with *Source* 'Camera', which had included an event 'when_motion_detected'. This event is only available for *Source* 'MotionDetector'.
The wrong configuration is now corrected.
If you have configured a Trigger for event 'when_motion_detected' with *Source* 'Camera', you need to delete it and replace it with a trigger with *Source* 'MotionDetector'
This covers part of [raspi-cam-srv Discussion #77](https://github.com/signag/raspi-cam-srv/discussions/77).
## V4.0.0
### New Features
- Seamless integration of **USB cameras** with CSI cameras (see [Info](./Z_Legacy_Information.md) and [Multi Cam](./CamMulticam.md))<br>USB cameras are accessed through OpenCV which must have been installed (see [Installation](./installation.md) Step 11.).<br>The use of USB cameras can be activated or deactivated in the [Settings](./Settings.md).<br>USB cameras are handled in exactly the same way as CSI cameras and they can be used in all operational functions, except [Focus Stacks](./PhotoSeriesFocus.md) and [Exposure Series](./PhotoSeriesExp.md).<br>**NOTE**: Currently [Controls](./CameraControls.md) (Focus, Zooming, Ecposure and Image control) cannot be used with USB cameras. However, images can be flipped and resolution can be
gitextract_uzgjfrtj/
├── .dockerignore
├── .gitignore
├── .vscode/
│ └── launch.json
├── Dockerfile
├── LICENSE
├── README.md
├── config/
│ ├── raspiCamSrv.service
│ └── raspiCamSrv_gunicorn.service
├── docker-compose.yml
├── docs/
│ ├── API.md
│ ├── AiCameraSupport.md
│ ├── Authentication.md
│ ├── Background Processes.md
│ ├── Cam.md
│ ├── CamCalibration.md
│ ├── CamMulticam.md
│ ├── CamStereo.md
│ ├── CamWebcam.md
│ ├── CameraControls.md
│ ├── CameraControls_AutoExposure.md
│ ├── CameraControls_Ctrl.md
│ ├── CameraControls_Exposure.md
│ ├── CameraControls_Image.md
│ ├── CameraControls_UsbCams.md
│ ├── Configuration.md
│ ├── Configuration_AI.md
│ ├── Console.md
│ ├── ConsoleActionButtons.md
│ ├── ConsoleVButtons.md
│ ├── FocusHandling.md
│ ├── Information.md
│ ├── Information_Cam.md
│ ├── Information_CamPrp.md
│ ├── Information_Sensor.md
│ ├── Information_Sys.md
│ ├── LiveDirectControl.md
│ ├── LiveScreen.md
│ ├── PhotoSeries.md
│ ├── PhotoSeriesExp.md
│ ├── PhotoSeriesFocus.md
│ ├── PhotoSeriesTimelapse.md
│ ├── PhotoViewer.md
│ ├── Phototaking.md
│ ├── ReleaseNotes.md
│ ├── ScalerCrop.md
│ ├── Settings.md
│ ├── SettingsAButtons.md
│ ├── SettingsAPI.md
│ ├── SettingsConfiguration.md
│ ├── SettingsConfiguration_NoCam.md
│ ├── SettingsDevices.md
│ ├── SettingsLButtons.md
│ ├── SettingsUpdate.md
│ ├── SettingsUsers.md
│ ├── SettingsVButtons.md
│ ├── Settings_NoCam.md
│ ├── SetupDocker.md
│ ├── Trigger.md
│ ├── TriggerActions.md
│ ├── TriggerActive.md
│ ├── TriggerCalendar.md
│ ├── TriggerCameraActions.md
│ ├── TriggerControl.md
│ ├── TriggerEventViewer.md
│ ├── TriggerMotion.md
│ ├── TriggerNotification.md
│ ├── TriggerOverview.md
│ ├── TriggerTriggerActions.md
│ ├── TriggerTriggers.md
│ ├── Troubelshooting.md
│ ├── Tuning.md
│ ├── UserGuide.md
│ ├── UserGuide_NoCam.md
│ ├── Z_Legacy_Information.md
│ ├── ZoomPan.md
│ ├── api/
│ │ └── postman/
│ │ └── raspiCamSrv.postman_collection.json
│ ├── bp_Hotspot_Bookworm.md
│ ├── bp_Hotspot_Bullseye.md
│ ├── bp_Hotspot_Trixie.md
│ ├── bp_PiZero_Standalone.md
│ ├── features.md
│ ├── getting_started_overview.md
│ ├── gpioDevices/
│ │ ├── ServoPWM.md
│ │ └── StepperMotor.md
│ ├── img/
│ │ └── TLSeriesStateChart.vsdx
│ ├── index.md
│ ├── installation.md
│ ├── installation_man.md
│ ├── picamera2_manual.md
│ ├── requirements.md
│ ├── service_configuration.md
│ ├── system_setup.md
│ ├── tutorials/
│ │ ├── AWB_with_neural_networks.md
│ │ └── Tutorials_Overview.md
│ └── updating_raspiCamSrv.md
├── mkdocs.yml
├── raspiCamSrv/
│ ├── __init__.py
│ ├── api.py
│ ├── auth.py
│ ├── auth_su.py
│ ├── camCfg.py
│ ├── camera_pi.py
│ ├── config.py
│ ├── console.py
│ ├── db.py
│ ├── dbx.py
│ ├── gpioDeviceTypes.py
│ ├── gpioDevices.py
│ ├── home.py
│ ├── images.py
│ ├── info.py
│ ├── motionAlgoIB.py
│ ├── motionDetector.py
│ ├── photoseries.py
│ ├── photoseriesCfg.py
│ ├── schema.sql
│ ├── settings.py
│ ├── static/
│ │ └── w3.css
│ ├── stereoCam.py
│ ├── sun.py
│ ├── templates/
│ │ ├── auth/
│ │ │ ├── login.html
│ │ │ ├── password.html
│ │ │ └── register.html
│ │ ├── base.html
│ │ ├── config/
│ │ │ └── main.html
│ │ ├── console/
│ │ │ └── console.html
│ │ ├── home/
│ │ │ ├── index.html
│ │ │ └── liveDirectPanel.html
│ │ ├── images/
│ │ │ └── main.html
│ │ ├── info/
│ │ │ └── info.html
│ │ ├── media_viewer.html
│ │ ├── photoseries/
│ │ │ └── main.html
│ │ ├── settings/
│ │ │ └── main.html
│ │ ├── trigger/
│ │ │ └── trigger.html
│ │ └── webcam/
│ │ └── webcam.html
│ ├── trigger.py
│ ├── triggerHandler.py
│ ├── version.py
│ ├── versionDoc.py
│ └── webcam.py
├── requirements.txt
└── scripts/
├── install_raspiCamSrv.sh
└── uninstall_raspiCamSrv.sh
SYMBOL INDEX (1970 symbols across 25 files)
FILE: raspiCamSrv/__init__.py
function create_app (line 15) | def create_app(test_config=None):
FILE: raspiCamSrv/api.py
function login (line 32) | def login():
function refresh (line 67) | def refresh():
function protected (line 74) | def protected():
function take_photo (line 80) | def take_photo():
function take_photo2 (line 102) | def take_photo2():
function take_photo_both (line 125) | def take_photo_both():
function take_raw_photo (line 164) | def take_raw_photo():
function take_raw_photo2 (line 187) | def take_raw_photo2():
function take_raw_photo_both (line 211) | def take_raw_photo_both():
function start_triggered_capture (line 251) | def start_triggered_capture():
function stop_triggered_capture (line 286) | def stop_triggered_capture():
function info (line 311) | def info():
function switch_cameras (line 354) | def switch_cameras():
function record_video (line 411) | def record_video():
function stop_video (line 454) | def stop_video():
function record_video2 (line 472) | def record_video2():
function stop_video2 (line 513) | def stop_video2():
function record_video_both (line 535) | def record_video_both():
function stop_video_both (line 599) | def stop_video_both():
function propGen (line 636) | def propGen(property):
function probeTerm (line 662) | def probeTerm(property):
function probe (line 720) | def probe():
FILE: raspiCamSrv/auth.py
function register (line 27) | def register():
function login (line 102) | def login():
function password (line 141) | def password():
function load_logged_in_user (line 207) | def load_logged_in_user():
function logout (line 252) | def logout():
function login_required (line 256) | def login_required(view):
function login_for_streaming (line 277) | def login_for_streaming(view):
FILE: raspiCamSrv/auth_su.py
function superuser_required (line 16) | def superuser_required(view):
FILE: raspiCamSrv/camCfg.py
class GPIODevice (line 29) | class GPIODevice():
method __init__ (line 30) | def __init__(self):
method id (line 48) | def id(self) -> str:
method id (line 52) | def id(self, value: str):
method usage (line 57) | def usage(self) -> str:
method usage (line 61) | def usage(self, value: str):
method type (line 65) | def type(self) -> str:
method type (line 69) | def type(self, value: str):
method params (line 73) | def params(self) -> dict:
method params (line 77) | def params(self, value: dict):
method usedPins (line 81) | def usedPins(self) -> str:
method usedPins (line 85) | def usedPins(self, value: str):
method isOk (line 89) | def isOk(self) -> bool:
method isOk (line 93) | def isOk(self, value: bool):
method docUrl (line 97) | def docUrl(self) -> str:
method docUrl (line 104) | def docUrl(self, value: str):
method isCalibrating (line 108) | def isCalibrating(self) -> bool:
method isCalibrating (line 112) | def isCalibrating(self, value: bool):
method needsCalibration (line 116) | def needsCalibration(self) -> bool:
method needsCalibration (line 120) | def needsCalibration(self, value: bool):
method trackState (line 123) | def trackState(self, devObject:object) ->bool:
method setState (line 151) | def setState(self, devObject:object) ->bool:
method getState (line 181) | def getState(self) -> dict:
method getUncalibratedState (line 205) | def getUncalibratedState(self) -> dict:
method initFromDict (line 240) | def initFromDict(cls, dict:dict):
class Trigger (line 257) | class Trigger():
method __init__ (line 258) | def __init__(self):
method id (line 269) | def id(self) -> str:
method id (line 273) | def id(self, value: str):
method source (line 277) | def source(self) -> str:
method source (line 281) | def source(self, value: str):
method device (line 285) | def device(self) -> str:
method device (line 289) | def device(self, value: str):
method event (line 293) | def event(self) -> str:
method event (line 297) | def event(self, value: str):
method params (line 301) | def params(self) -> dict:
method params (line 305) | def params(self, value: dict):
method control (line 309) | def control(self) -> dict:
method control (line 313) | def control(self, value: dict):
method isActive (line 317) | def isActive(self) -> bool:
method isActive (line 321) | def isActive(self, value: bool):
method actions (line 325) | def actions(self) -> dict:
method actions (line 329) | def actions(self, value: dict):
method initFromDict (line 333) | def initFromDict(cls, dict:dict):
class Action (line 373) | class Action():
method __init__ (line 374) | def __init__(self):
method id (line 384) | def id(self) -> str:
method id (line 388) | def id(self, value: str):
method isActive (line 392) | def isActive(self) -> bool:
method isActive (line 396) | def isActive(self, value: bool):
method source (line 400) | def source(self) -> str:
method source (line 404) | def source(self, value: str):
method device (line 408) | def device(self) -> str:
method device (line 412) | def device(self, value: str):
method method (line 416) | def method(self) -> str:
method method (line 420) | def method(self, value: str):
method params (line 424) | def params(self) -> dict:
method params (line 428) | def params(self, value: dict):
method control (line 432) | def control(self) -> dict:
method control (line 436) | def control(self, value: dict):
method initFromDict (line 440) | def initFromDict(cls, dict:dict):
class TriggerConfig (line 465) | class TriggerConfig():
method __init__ (line 469) | def __init__(self):
method logFileName (line 533) | def logFileName(self) -> str:
method logFilePath (line 537) | def logFilePath(self) -> str:
method operationStartMinute (line 541) | def operationStartMinute(self) -> int:
method operationStartMinute (line 545) | def operationStartMinute(self, value: int):
method operationStartStr (line 549) | def operationStartStr(self) -> str:
method operationStartStr (line 555) | def operationStartStr(self, value: str):
method operationEndMinute (line 565) | def operationEndMinute(self) -> int:
method operationEndMinute (line 569) | def operationEndMinute(self, value: int):
method operationEndStr (line 573) | def operationEndStr(self) -> str:
method operationEndStr (line 579) | def operationEndStr(self, value: str):
method operationWeekdays (line 589) | def operationWeekdays(self) -> dict:
method operationWeekdays (line 593) | def operationWeekdays(self, value: dict):
method operationAutoStart (line 597) | def operationAutoStart(self) -> bool:
method operationAutoStart (line 601) | def operationAutoStart(self, value: bool):
method detectionDelaySec (line 605) | def detectionDelaySec(self) -> int:
method detectionDelaySec (line 609) | def detectionDelaySec(self, value: int):
method detectionPauseSec (line 613) | def detectionPauseSec(self) -> int:
method detectionPauseSec (line 617) | def detectionPauseSec(self, value: int):
method triggeredByMotion (line 621) | def triggeredByMotion(self) -> bool:
method triggeredByMotion (line 625) | def triggeredByMotion(self, value: bool):
method triggeredBySound (line 629) | def triggeredBySound(self) -> bool:
method triggeredBySound (line 633) | def triggeredBySound(self, value: bool):
method triggeredByEvents (line 637) | def triggeredByEvents(self) -> bool:
method triggeredByEvents (line 641) | def triggeredByEvents(self, value: bool):
method motionDetectAlgo (line 645) | def motionDetectAlgo(self) -> int:
method motionDetectAlgo (line 649) | def motionDetectAlgo(self, value: int):
method motionRefTit (line 653) | def motionRefTit(self) -> str:
method motionRefTit (line 657) | def motionRefTit(self, value: str):
method motionRefURL (line 661) | def motionRefURL(self) -> str:
method motionRefURL (line 665) | def motionRefURL(self, value: str):
method actionVideo (line 669) | def actionVideo(self) -> bool:
method actionVideo (line 673) | def actionVideo(self, value: bool):
method actionPhoto (line 677) | def actionPhoto(self) -> bool:
method actionPhoto (line 681) | def actionPhoto(self, value: bool):
method actionNotify (line 685) | def actionNotify(self) -> bool:
method actionNotify (line 689) | def actionNotify(self, value: bool):
method msdThreshold (line 693) | def msdThreshold(self) -> int:
method msdThreshold (line 697) | def msdThreshold(self, value: int):
method bboxThreshold (line 701) | def bboxThreshold(self) -> int:
method bboxThreshold (line 705) | def bboxThreshold(self, value: int):
method nmsThreshold (line 710) | def nmsThreshold(self) -> int:
method nmsThreshold (line 714) | def nmsThreshold(self, value: int):
method motionThreshold (line 718) | def motionThreshold(self) -> int:
method motionThreshold (line 722) | def motionThreshold(self, value: int):
method useRoI (line 726) | def useRoI(self) -> bool:
method useRoI (line 730) | def useRoI(self, value: bool):
method regionOfNoInterest (line 734) | def regionOfNoInterest(self) -> tuple:
method regionOfNoInterest (line 738) | def regionOfNoInterest(self, value: tuple):
method regionOfNoInterestStr (line 742) | def regionOfNoInterestStr(self) -> str:
method regionOfNoInterestStr (line 752) | def regionOfNoInterestStr(self, value: str):
method regionOfInterest (line 765) | def regionOfInterest(self) -> tuple:
method regionOfInterest (line 769) | def regionOfInterest(self, value: tuple):
method regionOfInterestStr (line 773) | def regionOfInterestStr(self) -> str:
method regionOfInterestStr (line 783) | def regionOfInterestStr(self, value: str):
method _getRectangleFromCrop (line 795) | def _getRectangleFromCrop(self, crop: tuple) -> tuple:
method checkRoisAgainstScalerCropLiveView (line 820) | def checkRoisAgainstScalerCropLiveView(self, scalerCrop:tuple) -> bool:
method backSubModel (line 866) | def backSubModel(self) -> str:
method backSubModel (line 870) | def backSubModel(self, value: str):
method videoBboxes (line 874) | def videoBboxes(self) -> bool:
method videoBboxes (line 878) | def videoBboxes(self, value: bool):
method photoRois (line 882) | def photoRois(self) -> bool:
method photoRois (line 886) | def photoRois(self, value: bool):
method motionTestFrame1Title (line 890) | def motionTestFrame1Title(self) -> str:
method motionTestFrame1Title (line 894) | def motionTestFrame1Title(self, value: str):
method motionTestFrame2Title (line 898) | def motionTestFrame2Title(self) -> str:
method motionTestFrame2Title (line 902) | def motionTestFrame2Title(self, value: str):
method motionTestFrame3Title (line 906) | def motionTestFrame3Title(self) -> str:
method motionTestFrame3Title (line 910) | def motionTestFrame3Title(self, value: str):
method motionTestFrame4Title (line 914) | def motionTestFrame4Title(self) -> str:
method motionTestFrame4Title (line 918) | def motionTestFrame4Title(self, value: str):
method motionTestFramerate (line 922) | def motionTestFramerate(self) -> float:
method motionTestFramerate (line 926) | def motionTestFramerate(self, value: str):
method actionVR (line 930) | def actionVR(self) -> int:
method actionVR (line 934) | def actionVR(self, value: int):
method actionCircSize (line 938) | def actionCircSize(self) -> int:
method actionCircSize (line 942) | def actionCircSize(self, value: int):
method actionPath (line 946) | def actionPath(self) -> str:
method actionPath (line 950) | def actionPath(self, value: str):
method actionVideoDuration (line 954) | def actionVideoDuration(self) -> int:
method actionVideoDuration (line 958) | def actionVideoDuration(self, value: int):
method actionPhotoBurst (line 962) | def actionPhotoBurst(self) -> int:
method actionPhotoBurst (line 966) | def actionPhotoBurst(self, value: int):
method actionPhotoBurstDelaySec (line 970) | def actionPhotoBurstDelaySec(self) -> int:
method actionPhotoBurstDelaySec (line 974) | def actionPhotoBurstDelaySec(self, value: int):
method notifyHost (line 978) | def notifyHost(self) -> str:
method notifyHost (line 982) | def notifyHost(self, value: str):
method notifyPort (line 986) | def notifyPort(self) -> int:
method notifyPort (line 990) | def notifyPort(self, value: int):
method notifyUseSSL (line 994) | def notifyUseSSL(self) -> bool:
method notifyUseSSL (line 998) | def notifyUseSSL(self, value: bool):
method notifyAuthenticate (line 1002) | def notifyAuthenticate(self) -> bool:
method notifyAuthenticate (line 1006) | def notifyAuthenticate(self, value: bool):
method notifyConOK (line 1010) | def notifyConOK(self) -> bool:
method notifyConOK (line 1014) | def notifyConOK(self, value: bool):
method notifyPause (line 1018) | def notifyPause(self) -> int:
method notifyPause (line 1022) | def notifyPause(self, value: int):
method notifyIncludeVideo (line 1026) | def notifyIncludeVideo(self) -> bool:
method notifyIncludeVideo (line 1030) | def notifyIncludeVideo(self, value: bool):
method notifyIncludePhoto (line 1034) | def notifyIncludePhoto(self) -> bool:
method notifyIncludePhoto (line 1038) | def notifyIncludePhoto(self, value: bool):
method notifySavePwd (line 1042) | def notifySavePwd(self) -> bool:
method notifySavePwd (line 1046) | def notifySavePwd(self, value: bool):
method notifyPwdPath (line 1050) | def notifyPwdPath(self) -> str:
method notifyPwdPath (line 1054) | def notifyPwdPath(self, value: str):
method notifyFrom (line 1058) | def notifyFrom(self) -> str:
method notifyFrom (line 1062) | def notifyFrom(self, value: str):
method notifyTo (line 1066) | def notifyTo(self) -> str:
method notifyTo (line 1070) | def notifyTo(self, value: str):
method notifySubject (line 1074) | def notifySubject(self) -> str:
method notifySubject (line 1078) | def notifySubject(self, value: str):
method retentionPeriod (line 1082) | def retentionPeriod(self) -> int:
method retentionPeriod (line 1086) | def retentionPeriod(self, value: int):
method retentionPeriodStr (line 1090) | def retentionPeriodStr(self) -> str:
method evStart (line 1094) | def evStart(self) -> datetime:
method evStart (line 1098) | def evStart(self, value: datetime):
method evStartDateStr (line 1106) | def evStartDateStr(self) -> str:
method evStartDateStr (line 1110) | def evStartDateStr(self, value: str):
method evStartTimeStr (line 1119) | def evStartTimeStr(self) -> str:
method evStartTimeStr (line 1123) | def evStartTimeStr(self, value: str):
method evStartIso (line 1132) | def evStartIso(self) -> str:
method evStartMidnight (line 1135) | def evStartMidnight(self):
method evIncludePhoto (line 1139) | def evIncludePhoto(self) -> bool:
method evIncludePhoto (line 1143) | def evIncludePhoto(self, value: bool):
method evIncludeVideo (line 1147) | def evIncludeVideo(self) -> bool:
method evIncludeVideo (line 1151) | def evIncludeVideo(self, value: bool):
method evAutoRefresh (line 1155) | def evAutoRefresh(self) -> bool:
method evAutoRefresh (line 1159) | def evAutoRefresh(self, value: bool):
method calStart (line 1163) | def calStart(self) -> datetime:
method calStart (line 1167) | def calStart(self, value: datetime):
method calStartDateStr (line 1175) | def calStartDateStr(self) -> str:
method calStartDateStr (line 1179) | def calStartDateStr(self, value: str):
method error (line 1188) | def error(self) -> str:
method error (line 1192) | def error(self, value: str):
method error2 (line 1199) | def error2(self) -> str:
method error2 (line 1203) | def error2(self, value: str):
method errorSource (line 1207) | def errorSource(self) -> str:
method errorSource (line 1211) | def errorSource(self, value: str):
method triggers (line 1215) | def triggers(self) -> list[Trigger]:
method triggers (line 1219) | def triggers(self, value: list[Trigger]):
method actions (line 1223) | def actions(self) -> list:
method actions (line 1227) | def actions(self, value: list):
method eventList (line 1231) | def eventList(self) -> list:
method getEventList (line 1234) | def getEventList(self) -> list:
method calendar (line 1330) | def calendar(self) -> list:
method calendarMonthStr (line 1334) | def calendarMonthStr(self) -> str:
method getCalendar (line 1337) | def getCalendar(self)-> list:
method cleanupEvents (line 1373) | def cleanupEvents(self):
method _parseWindows (line 1421) | def _parseWindows(wins: str) -> list:
method _parseRectTuple (line 1445) | def _parseRectTuple(stuple: str) -> tuple:
method checkNotificationRecipient (line 1459) | def checkNotificationRecipient(self, user=None, pwd=None) -> tuple:
method triggerSources (line 1615) | def triggerSources(self) -> list[str]:
method actionSources (line 1631) | def actionSources(self) -> list[str]:
method triggerDevices (line 1647) | def triggerDevices(self, source:str) -> list[str]:
method actionDevices (line 1680) | def actionDevices(self, source:str) -> list[str]:
method triggerEvents (line 1708) | def triggerEvents(self, source:str, device:str) -> tuple[list[str], di...
method actionTargets (line 1767) | def actionTargets(self, source:str, device:str) -> list[str]:
method getTrigger (line 1847) | def getTrigger(self, id:str) -> Trigger:
method getAction (line 1863) | def getAction(self, id:str) -> Action:
method cameraSettings (line 1880) | def cameraSettings(self) -> dict:
method cameraSettings (line 1903) | def cameraSettings(self, value: dict):
method setCameraSettingsToDefault (line 1941) | def setCameraSettingsToDefault(self):
method cameraDefaultSettings (line 1962) | def cameraDefaultSettings(self) -> dict:
method initFromDict (line 1985) | def initFromDict(cls, dict:dict):
class CameraInfo (line 2020) | class CameraInfo():
method __init__ (line 2021) | def __init__(self):
method model (line 2033) | def model(self) -> str:
method model (line 2037) | def model(self, value: str):
method isUsb (line 2041) | def isUsb(self) -> bool:
method isUsb (line 2045) | def isUsb(self, value: bool):
method hasAi (line 2049) | def hasAi(self) -> bool:
method hasAi (line 2053) | def hasAi(self, value: bool):
method usbDev (line 2057) | def usbDev(self) -> str:
method usbDev (line 2061) | def usbDev(self, value: str):
method location (line 2065) | def location(self) -> int:
method location (line 2069) | def location(self, value: int):
method rotation (line 2073) | def rotation(self) -> int:
method rotation (line 2077) | def rotation(self, value: int):
method id (line 2081) | def id(self) -> str:
method id (line 2085) | def id(self, value: str):
method num (line 2089) | def num(self) -> int:
method num (line 2093) | def num(self, value: int):
method status (line 2097) | def status(self) -> str:
method status (line 2101) | def status(self, value: str):
method setUsbDev (line 2104) | def setUsbDev(self):
class CameraControls (line 2163) | class CameraControls():
method __init__ (line 2164) | def __init__(self):
method dict (line 2223) | def dict(self) -> dict:
method aeConstraintMode (line 2256) | def aeConstraintMode(self) -> int:
method aeConstraintMode (line 2260) | def aeConstraintMode(self, value: int):
method aeConstraintMode (line 2270) | def aeConstraintMode(self):
method aeEnable (line 2274) | def aeEnable(self) -> bool:
method aeEnable (line 2278) | def aeEnable(self, value: bool):
method aeEnable (line 2282) | def aeEnable(self):
method aeExposureMode (line 2286) | def aeExposureMode(self) -> int:
method aeExposureMode (line 2290) | def aeExposureMode(self, value: int):
method aeExposureMode (line 2300) | def aeExposureMode(self):
method aeFlickerMode (line 2304) | def aeFlickerMode(self) -> int:
method aeFlickerMode (line 2308) | def aeFlickerMode(self, value: int):
method aeFlickerMode (line 2317) | def aeFlickerMode(self):
method aeFlickerPeriod (line 2321) | def aeFlickerPeriod(self) -> int:
method aeFlickerPeriod (line 2325) | def aeFlickerPeriod(self, value: int):
method aeFlickerPeriod (line 2332) | def aeFlickerPeriod(self):
method aeMeteringMode (line 2336) | def aeMeteringMode(self) -> int:
method aeMeteringMode (line 2340) | def aeMeteringMode(self, value: int):
method aeMeteringMode (line 2350) | def aeMeteringMode(self):
method afMode (line 2354) | def afMode(self) -> int:
method afMode (line 2358) | def afMode(self, value: int):
method afMode (line 2367) | def afMode(self):
method lensPosition (line 2371) | def lensPosition(self) -> float:
method lensPosition (line 2375) | def lensPosition(self, value: float):
method lensPosition (line 2379) | def lensPosition(self):
method focalDistance (line 2383) | def focalDistance(self) -> float:
method focalDistance (line 2392) | def focalDistance(self, value: float):
method afMetering (line 2402) | def afMetering(self) -> int:
method afMetering (line 2406) | def afMetering(self, value: int):
method afMetering (line 2414) | def afMetering(self):
method afPause (line 2418) | def afPause(self) -> int:
method afPause (line 2422) | def afPause(self, value: int):
method afPause (line 2431) | def afPause(self):
method afRange (line 2435) | def afRange(self) -> int:
method afRange (line 2439) | def afRange(self, value: int):
method afRange (line 2448) | def afRange(self):
method afSpeed (line 2452) | def afSpeed(self) -> int:
method afSpeed (line 2456) | def afSpeed(self, value: int):
method afSpeed (line 2464) | def afSpeed(self):
method scalerCrop (line 2468) | def scalerCrop(self) -> tuple:
method scalerCrop (line 2472) | def scalerCrop(self, value: tuple):
method scalerCrop (line 2476) | def scalerCrop(self):
method scalerCropStr (line 2480) | def scalerCropStr(self) -> str:
method scalerCropStr (line 2484) | def scalerCropStr(self, value: str):
method afTrigger (line 2488) | def afTrigger(self) -> int:
method afTrigger (line 2492) | def afTrigger(self, value: int):
method afTrigger (line 2500) | def afTrigger(self):
method afWindows (line 2504) | def afWindows(self) -> tuple:
method afWindows (line 2508) | def afWindows(self, value: tuple):
method afWindows (line 2512) | def afWindows(self):
method afWindowsStr (line 2516) | def afWindowsStr(self) -> str:
method afWindowsStr (line 2526) | def afWindowsStr(self, value: str):
method analogueGain (line 2539) | def analogueGain(self) -> float:
method analogueGain (line 2543) | def analogueGain(self, value: float):
method analogueGain (line 2550) | def analogueGain(self):
method awbEnable (line 2554) | def awbEnable(self) -> bool:
method awbEnable (line 2558) | def awbEnable(self, value: bool):
method awbEnable (line 2562) | def awbEnable(self):
method awbMode (line 2566) | def awbMode(self) -> int:
method awbMode (line 2570) | def awbMode(self, value: int):
method awbMode (line 2583) | def awbMode(self):
method brightness (line 2587) | def brightness(self) -> float:
method brightness (line 2591) | def brightness(self, value: float):
method brightness (line 2595) | def brightness(self):
method colourGains (line 2599) | def colourGains(self) -> tuple:
method colourGains (line 2603) | def colourGains(self, value: tuple):
method colourGains (line 2616) | def colourGains(self):
method colourGainRed (line 2620) | def colourGainRed(self) -> float:
method colourGainBlue (line 2624) | def colourGainBlue(self) -> float:
method contrast (line 2628) | def contrast(self) -> float:
method contrast (line 2632) | def contrast(self, value: float):
method contrast (line 2636) | def contrast(self):
method exposureTime (line 2640) | def exposureTime(self) -> int:
method exposureTime (line 2644) | def exposureTime(self, value: int):
method exposureTime (line 2651) | def exposureTime(self):
method exposureTimeSec (line 2655) | def exposureTimeSec(self) -> float:
method exposureTimeSec (line 2659) | def exposureTimeSec(self, value: float):
method exposureValue (line 2666) | def exposureValue(self) -> float:
method exposureValue (line 2670) | def exposureValue(self, value: float):
method exposureValue (line 2678) | def exposureValue(self):
method frameDurationLimits (line 2682) | def frameDurationLimits(self) -> tuple:
method frameDurationLimits (line 2686) | def frameDurationLimits(self, value: tuple):
method frameDurationLimits (line 2694) | def frameDurationLimits(self):
method frameDurationLimitMax (line 2698) | def frameDurationLimitMax(self) -> int:
method frameDurationLimitMin (line 2702) | def frameDurationLimitMin(self) -> int:
method hdrMode (line 2706) | def hdrMode(self) -> int:
method hdrMode (line 2710) | def hdrMode(self, value: int):
method hdrMode (line 2721) | def hdrMode(self):
method noiseReductionMode (line 2725) | def noiseReductionMode(self) -> int:
method noiseReductionMode (line 2729) | def noiseReductionMode(self, value: int):
method noiseReductionMode (line 2738) | def noiseReductionMode(self):
method saturation (line 2742) | def saturation(self) -> float:
method saturation (line 2746) | def saturation(self, value: float):
method saturation (line 2750) | def saturation(self):
method sharpness (line 2754) | def sharpness(self) -> float:
method sharpness (line 2758) | def sharpness(self, value: float):
method sharpness (line 2762) | def sharpness(self):
method usbCamControls (line 2766) | def usbCamControls(self) -> dict:
method usbCamControls (line 2770) | def usbCamControls(self, value: dict):
method usbCamControls (line 2774) | def usbCamControls(self):
method _parseWindows (line 2778) | def _parseWindows(wins: str) -> list:
method _parseRectTuple (line 2802) | def _parseRectTuple(stuple: str) -> tuple:
method initFromDict (line 2817) | def initFromDict(cls, dict:dict):
class SensorMode (line 2841) | class SensorMode():
method __init__ (line 2844) | def __init__(self):
method id (line 2855) | def id(self) -> int:
method id (line 2859) | def id(self, value: int):
method format (line 2863) | def format(self) -> str:
method format (line 2867) | def format(self, value: str):
method unpacked (line 2871) | def unpacked(self) -> str:
method unpacked (line 2875) | def unpacked(self, value: str):
method bit_depth (line 2879) | def bit_depth(self) -> int:
method bit_depth (line 2883) | def bit_depth(self, value: int):
method size (line 2887) | def size(self) -> tuple[int, int]:
method size (line 2891) | def size(self, value: tuple[int, int]):
method fps (line 2895) | def fps(self) -> float:
method fps (line 2899) | def fps(self, value: float):
method crop_limits (line 2903) | def crop_limits(self) -> tuple:
method crop_limits (line 2907) | def crop_limits(self, value: tuple):
method exposure_limits (line 2911) | def exposure_limits(self) -> tuple:
method exposure_limits (line 2915) | def exposure_limits(self, value: tuple):
method tabId (line 2919) | def tabId(self) -> str:
method tabButtonId (line 2923) | def tabButtonId(self) -> str:
method tabTitle (line 2927) | def tabTitle(self) -> str:
class TuningConfig (line 2930) | class TuningConfig():
method __init__ (line 2931) | def __init__(self):
method loadTuningFile (line 2938) | def loadTuningFile(self) -> bool:
method loadTuningFile (line 2942) | def loadTuningFile(self, value: bool):
method tuningFolderDef (line 2946) | def tuningFolderDef(self) -> str:
method tuningFolder (line 2950) | def tuningFolder(self) -> str:
method tuningFolder (line 2954) | def tuningFolder(self, value: str):
method tuningFile (line 2958) | def tuningFile(self) -> str:
method tuningFile (line 2962) | def tuningFile(self, value: str):
method tuningFilePath (line 2966) | def tuningFilePath(self) -> str:
method isDefaultFolder (line 2973) | def isDefaultFolder(self) -> bool:
method initFromDict (line 2977) | def initFromDict(cls, dict:dict):
class AiConfig (line 2986) | class AiConfig():
method __init__ (line 2987) | def __init__(self):
method enable (line 3004) | def enable(self) -> bool:
method enable (line 3008) | def enable(self, value: bool):
method task (line 3012) | def task(self) -> str:
method task (line 3016) | def task(self, value: str):
method modelFolder (line 3020) | def modelFolder(self) -> str:
method modelFolder (line 3024) | def modelFolder(self, value: str):
method modelFiles (line 3028) | def modelFiles(self) -> list[str]:
method modelFiles (line 3032) | def modelFiles(self, value: list[str]):
method modelFile (line 3036) | def modelFile(self) -> str:
method modelFile (line 3040) | def modelFile(self, value: str):
method modelIntrinsics (line 3044) | def modelIntrinsics(self) -> dict:
method modelIntrinsics (line 3048) | def modelIntrinsics(self, value: dict):
method drawOnLores (line 3052) | def drawOnLores(self) -> bool:
method drawOnLores (line 3056) | def drawOnLores(self, value: bool):
method drawOnMain (line 3060) | def drawOnMain(self) -> bool:
method drawOnMain (line 3064) | def drawOnMain(self, value: bool):
method topK (line 3068) | def topK(self) -> int:
method topK (line 3072) | def topK(self, value: int):
method detectionThreshold (line 3076) | def detectionThreshold(self) -> float:
method detectionThreshold (line 3080) | def detectionThreshold(self, value: float):
method iouThreshold (line 3084) | def iouThreshold(self) -> float:
method iouThreshold (line 3088) | def iouThreshold(self, value: float):
method maxDetections (line 3092) | def maxDetections(self) -> int:
method maxDetections (line 3096) | def maxDetections(self, value: int):
method initFromDict (line 3100) | def initFromDict(cls, dict:dict):
class CameraConfig (line 3109) | class CameraConfig():
method __init__ (line 3110) | def __init__(self):
method id (line 3128) | def id(self) -> str:
method id (line 3132) | def id(self, value: str):
method use_case (line 3136) | def use_case(self) -> str:
method use_case (line 3140) | def use_case(self, value: str):
method transform_hflip (line 3144) | def transform_hflip(self) -> bool:
method transform_hflip (line 3148) | def transform_hflip(self, value: bool):
method transform_vflip (line 3152) | def transform_vflip(self) -> bool:
method transform_vflip (line 3156) | def transform_vflip(self, value: bool):
method colour_space (line 3160) | def colour_space(self) -> str:
method colour_space (line 3164) | def colour_space(self, value: str):
method buffer_count (line 3168) | def buffer_count(self) -> int:
method buffer_count (line 3172) | def buffer_count(self, value: int):
method queue (line 3176) | def queue(self) -> bool:
method queue (line 3180) | def queue(self, value: bool):
method display (line 3184) | def display(self) -> str:
method display (line 3188) | def display(self, value: str):
method encode (line 3192) | def encode(self) -> str:
method encode (line 3196) | def encode(self, value: str):
method sensor_mode (line 3208) | def sensor_mode(self) -> str:
method sensor_mode (line 3212) | def sensor_mode(self, value: str):
method stream (line 3216) | def stream(self) -> str:
method stream (line 3220) | def stream(self, value: str):
method stream_size (line 3229) | def stream_size(self) -> tuple[int, int]:
method stream_size (line 3233) | def stream_size(self, value: tuple[int, int]):
method stream_size_align (line 3237) | def stream_size_align(self) -> bool:
method stream_size_align (line 3241) | def stream_size_align(self, value: bool):
method format (line 3245) | def format(self) -> str:
method format (line 3249) | def format(self, value: str):
method controls (line 3253) | def controls(self) -> dict:
method controls (line 3257) | def controls(self, value: dict):
method tabId (line 3261) | def tabId(self) -> str:
method tabButtonId (line 3265) | def tabButtonId(self) -> str:
method tabTitle (line 3269) | def tabTitle(self) -> str:
method initFromDict (line 3273) | def initFromDict(cls, dict:dict):
class CameraProperties (line 3305) | class CameraProperties():
method __init__ (line 3306) | def __init__(self):
method hasFocus (line 3323) | def hasFocus(self) -> bool:
method hasFocus (line 3327) | def hasFocus(self, value: bool):
method hasFocus (line 3331) | def hasFocus(self):
method hasFlicker (line 3335) | def hasFlicker(self) -> bool:
method hasFlicker (line 3339) | def hasFlicker(self, value: bool):
method hasFlicker (line 3343) | def hasFlicker(self):
method hasHdr (line 3347) | def hasHdr(self) -> bool:
method hasHdr (line 3351) | def hasHdr(self, value: bool):
method hasHdr (line 3355) | def hasHdr(self):
method model (line 3359) | def model(self):
method model (line 3363) | def model(self, value: str):
method model (line 3367) | def model(self):
method unitCellSize (line 3371) | def unitCellSize(self):
method unitCellSize (line 3375) | def unitCellSize(self, value: str):
method unitCellSize (line 3379) | def unitCellSize(self):
method location (line 3383) | def location(self):
method location (line 3387) | def location(self, value: str):
method location (line 3391) | def location(self):
method rotation (line 3395) | def rotation(self):
method rotation (line 3399) | def rotation(self, value: str):
method rotation (line 3403) | def rotation(self):
method pixelArraySize (line 3407) | def pixelArraySize(self):
method pixelArraySize (line 3411) | def pixelArraySize(self, value: str):
method pixelArraySize (line 3415) | def pixelArraySize(self):
method pixelArrayActiveAreas (line 3419) | def pixelArrayActiveAreas(self):
method pixelArrayActiveAreas (line 3423) | def pixelArrayActiveAreas(self, value: str):
method pixelArrayActiveAreas (line 3427) | def pixelArrayActiveAreas(self):
method colorFilterArrangement (line 3431) | def colorFilterArrangement(self):
method colorFilterArrangement (line 3435) | def colorFilterArrangement(self, value: str):
method colorFilterArrangement (line 3439) | def colorFilterArrangement(self):
method scalerCropMaximum (line 3443) | def scalerCropMaximum(self):
method scalerCropMaximum (line 3447) | def scalerCropMaximum(self, value: str):
method scalerCropMaximum (line 3451) | def scalerCropMaximum(self):
method systemDevices (line 3455) | def systemDevices(self):
method systemDevices (line 3459) | def systemDevices(self, value: str):
method systemDevices (line 3463) | def systemDevices(self):
method sensorSensitivity (line 3467) | def sensorSensitivity(self) -> float:
method sensorSensitivity (line 3471) | def sensorSensitivity(self, value: float):
method colorSpace (line 3475) | def colorSpace(self):
method colorSpace (line 3479) | def colorSpace(self, value: str):
method colorSpace (line 3483) | def colorSpace(self):
method initFromDict (line 3487) | def initFromDict(cls, dict:dict):
class vButton (line 3507) | class vButton():
method __init__ (line 3511) | def __init__(self) -> None:
method row (line 3522) | def row(self) -> int:
method row (line 3526) | def row(self, value: int):
method col (line 3530) | def col(self) -> int:
method col (line 3534) | def col(self, value: int):
method isVisible (line 3538) | def isVisible(self) -> bool:
method isVisible (line 3542) | def isVisible(self, value: bool):
method needsConfirm (line 3546) | def needsConfirm(self) -> bool:
method needsConfirm (line 3550) | def needsConfirm(self, value: bool):
method buttonColor (line 3554) | def buttonColor(self) -> str:
method buttonColor (line 3558) | def buttonColor(self, value: str):
method buttonShape (line 3562) | def buttonShape(self) -> str:
method buttonShape (line 3566) | def buttonShape(self, value: str):
method buttonText (line 3570) | def buttonText(self) -> str:
method buttonText (line 3574) | def buttonText(self, value: str):
method buttonExec (line 3578) | def buttonExec(self) -> str:
method buttonExec (line 3582) | def buttonExec(self, value: str):
method initFromDict (line 3586) | def initFromDict(cls, dict:dict):
class ActionButton (line 3595) | class ActionButton():
method __init__ (line 3599) | def __init__(self) -> None:
method row (line 3610) | def row(self) -> int:
method row (line 3614) | def row(self, value: int):
method col (line 3618) | def col(self) -> int:
method col (line 3622) | def col(self, value: int):
method isVisible (line 3626) | def isVisible(self) -> bool:
method isVisible (line 3630) | def isVisible(self, value: bool):
method needsConfirm (line 3634) | def needsConfirm(self) -> bool:
method needsConfirm (line 3638) | def needsConfirm(self, value: bool):
method buttonColor (line 3642) | def buttonColor(self) -> str:
method buttonColor (line 3646) | def buttonColor(self, value: str):
method buttonShape (line 3650) | def buttonShape(self) -> str:
method buttonShape (line 3654) | def buttonShape(self, value: str):
method buttonText (line 3658) | def buttonText(self) -> str:
method buttonText (line 3662) | def buttonText(self, value: str):
method buttonAction (line 3666) | def buttonAction(self) -> str:
method buttonAction (line 3670) | def buttonAction(self, value: str):
method initFromDict (line 3674) | def initFromDict(cls, dict:dict):
class LiveButton (line 3683) | class LiveButton():
method __init__ (line 3687) | def __init__(self) -> None:
method row (line 3700) | def row(self) -> int:
method row (line 3704) | def row(self, value: int):
method col (line 3708) | def col(self) -> int:
method col (line 3712) | def col(self, value: int):
method isVisible (line 3716) | def isVisible(self) -> bool:
method isVisible (line 3720) | def isVisible(self, value: bool):
method needsConfirm (line 3724) | def needsConfirm(self) -> bool:
method needsConfirm (line 3728) | def needsConfirm(self, value: bool):
method buttonColor (line 3732) | def buttonColor(self) -> str:
method buttonColor (line 3736) | def buttonColor(self, value: str):
method buttonShape (line 3740) | def buttonShape(self) -> str:
method buttonShape (line 3744) | def buttonShape(self, value: str):
method buttonText (line 3748) | def buttonText(self) -> str:
method buttonText (line 3752) | def buttonText(self, value: str):
method isAction (line 3756) | def isAction(self) -> bool:
method isAction (line 3760) | def isAction(self, value: bool):
method buttonAction (line 3764) | def buttonAction(self) -> str:
method buttonAction (line 3768) | def buttonAction(self, value: str):
method buttonExec (line 3772) | def buttonExec(self) -> str:
method buttonExec (line 3776) | def buttonExec(self, value: str):
method initFromDict (line 3780) | def initFromDict(cls, dict:dict):
class StereoConfig (line 3789) | class StereoConfig():
method __init__ (line 3803) | def __init__(self):
method calibPhotosOK (line 3844) | def calibPhotosOK(self) -> dict:
method calibPhotosOK (line 3848) | def calibPhotosOK(self, value: dict):
method calibShowCorners (line 3855) | def calibShowCorners(self) -> bool:
method calibShowCorners (line 3859) | def calibShowCorners(self, value: bool):
method isCalibPhotosOK (line 3862) | def isCalibPhotosOK(self, camL: str, camR: str) -> bool:
method isCalibCamerasOK (line 3876) | def isCalibCamerasOK(self, camL: str, camR: str) -> bool:
method calibPhotos (line 3891) | def calibPhotos(self) -> dict:
method calibPhotos (line 3895) | def calibPhotos(self, value: dict):
method calibPhotosCrn (line 3902) | def calibPhotosCrn(self) -> dict:
method calibPhotosCrn (line 3906) | def calibPhotosCrn(self, value: dict):
method calibPhotosCount (line 3913) | def calibPhotosCount(self) -> dict:
method calibPhotosCount (line 3917) | def calibPhotosCount(self, value: dict):
method getCalibPhotosCount (line 3923) | def getCalibPhotosCount(self, cam: str) -> int:
method hasCalibPhotos (line 3932) | def hasCalibPhotos(self, camL: str, camR: str) -> bool:
method calibPhotosPath (line 3946) | def calibPhotosPath(self) -> str:
method calibPhotosPath (line 3950) | def calibPhotosPath(self, value: str):
method calibPhotosSubPath (line 3957) | def calibPhotosSubPath(self) -> str:
method calibPhotosSubPath (line 3961) | def calibPhotosSubPath(self, value: str):
method calibPhotosIdx (line 3968) | def calibPhotosIdx(self) -> dict:
method calibPhotosIdx (line 3972) | def calibPhotosIdx(self, value: dict):
method getCalibPhotosIdx (line 3978) | def getCalibPhotosIdx(self, cam: str) -> int:
method calibCameraOK (line 3987) | def calibCameraOK(self) -> dict:
method calibCameraOK (line 3991) | def calibCameraOK(self, value: dict):
method calibRmsReproError (line 3998) | def calibRmsReproError(self) -> dict:
method calibRmsReproError (line 4002) | def calibRmsReproError(self, value: dict):
method calibStereoOK (line 4009) | def calibStereoOK(self) -> bool:
method calibStereoOK (line 4013) | def calibStereoOK(self, value: bool):
method rectifyScale (line 4020) | def rectifyScale(self) -> int:
method rectifyScale (line 4024) | def rectifyScale(self, value: int):
method stereoRectifyOK (line 4031) | def stereoRectifyOK(self) -> bool:
method stereoRectifyOK (line 4035) | def stereoRectifyOK(self, value: bool):
method calibDataSubPath (line 4042) | def calibDataSubPath(self) -> str:
method calibDataSubPath (line 4046) | def calibDataSubPath(self, value: str):
method calibDataFile (line 4053) | def calibDataFile(self) -> str:
method calibDataFile (line 4057) | def calibDataFile(self, value: str):
method calibDate (line 4064) | def calibDate(self) -> str:
method calibDate (line 4068) | def calibDate(self, value: datetime):
method calibDataOK (line 4082) | def calibDataOK(self) -> bool:
method calibDataOK (line 4086) | def calibDataOK(self, value: bool):
method calibPatternIdx (line 4093) | def calibPatternIdx(self) -> int:
method calibPatternIdx (line 4097) | def calibPatternIdx(self, value: int):
method calibPattern (line 4104) | def calibPattern(self) -> str:
method calibPatternRef (line 4108) | def calibPatternRef(self) -> str:
method calibPatternSize (line 4115) | def calibPatternSize(self) -> tuple:
method calibPatternSize (line 4119) | def calibPatternSize(self, value: tuple):
method calibPhotosTarget (line 4129) | def calibPhotosTarget(self) -> int:
method calibPhotosTarget (line 4133) | def calibPhotosTarget(self, value: int):
method calibPhotoRecording (line 4140) | def calibPhotoRecording(self) -> bool:
method calibPhotoRecording (line 4144) | def calibPhotoRecording(self, value: bool):
method calibPhotoRecordingMsg (line 4151) | def calibPhotoRecordingMsg(self) -> str:
method calibPhotoRecordingMsg (line 4155) | def calibPhotoRecordingMsg(self, value: str):
method applyCalibRectify (line 4162) | def applyCalibRectify(self) -> bool:
method applyCalibRectify (line 4166) | def applyCalibRectify(self, value: bool):
method intentIdx (line 4173) | def intentIdx(self) -> int:
method intentIdx (line 4177) | def intentIdx(self, value: int):
method intent (line 4184) | def intent(self) -> str:
method intentName (line 4188) | def intentName(self) -> str:
method intentAlgoIdx (line 4192) | def intentAlgoIdx(self) -> int:
method intentAlgoIdx (line 4196) | def intentAlgoIdx(self, value: int):
method intentAlgo (line 4203) | def intentAlgo(self) -> str:
method intentAlgoName (line 4207) | def intentAlgoName(self) -> str:
method bm_numDisparitiesFactor (line 4211) | def bm_numDisparitiesFactor(self) -> int:
method bm_numDisparitiesFactor (line 4215) | def bm_numDisparitiesFactor(self, value: int):
method bm_blockSize (line 4222) | def bm_blockSize(self) -> int:
method bm_blockSize (line 4226) | def bm_blockSize(self, value: int):
method sgbm_minDisparity (line 4233) | def sgbm_minDisparity(self) -> int:
method sgbm_minDisparity (line 4237) | def sgbm_minDisparity(self, value: int):
method sgbm_numDisparitiesFactor (line 4244) | def sgbm_numDisparitiesFactor(self) -> int:
method sgbm_numDisparitiesFactor (line 4248) | def sgbm_numDisparitiesFactor(self, value: int):
method sgbm_blockSize (line 4255) | def sgbm_blockSize(self) -> int:
method sgbm_blockSize (line 4259) | def sgbm_blockSize(self, value: int):
method sgbm_P1 (line 4266) | def sgbm_P1(self) -> int:
method sgbm_P1 (line 4270) | def sgbm_P1(self, value: int):
method sgbm_P2 (line 4277) | def sgbm_P2(self) -> int:
method sgbm_P2 (line 4281) | def sgbm_P2(self, value: int):
method sgbm_disp12MaxDiff (line 4288) | def sgbm_disp12MaxDiff(self) -> int:
method sgbm_disp12MaxDiff (line 4292) | def sgbm_disp12MaxDiff(self, value: int):
method sgbm_preFilterCap (line 4299) | def sgbm_preFilterCap(self) -> int:
method sgbm_preFilterCap (line 4303) | def sgbm_preFilterCap(self, value: int):
method sgbm_uniquenessRatio (line 4310) | def sgbm_uniquenessRatio(self) -> int:
method sgbm_uniquenessRatio (line 4314) | def sgbm_uniquenessRatio(self, value: int):
method sgbm_speckleWindowSize (line 4321) | def sgbm_speckleWindowSize(self) -> int:
method sgbm_speckleWindowSize (line 4325) | def sgbm_speckleWindowSize(self, value: int):
method sgbm_speckleRange (line 4332) | def sgbm_speckleRange(self) -> int:
method sgbm_speckleRange (line 4336) | def sgbm_speckleRange(self, value: int):
method sgbm_mode (line 4343) | def sgbm_mode(self) -> int:
method sgbm_mode (line 4347) | def sgbm_mode(self, value: int):
method getNextPhotoIdx (line 4353) | def getNextPhotoIdx(self) -> int:
method initFromDict (line 4392) | def initFromDict(cls, dict:dict):
class ServerConfig (line 4404) | class ServerConfig():
method __init__ (line 4405) | def __init__(self):
method serverStartTime (line 4579) | def serverStartTime(self) -> datetime:
method serverStartTime (line 4583) | def serverStartTime(self, value: datetime):
method serverStartTimeStr (line 4587) | def serverStartTimeStr(self) -> str:
method unsavedChanges (line 4594) | def unsavedChanges(self) -> bool:
method unsavedChanges (line 4598) | def unsavedChanges(self, value: bool):
method changeLog (line 4602) | def changeLog(self) -> list[dict]:
method changeLog (line 4606) | def changeLog(self, value: list):
method addChangeLogEntry (line 4609) | def addChangeLogEntry(self, entry: str):
method clearChangeLog (line 4617) | def clearChangeLog(self):
method error (line 4623) | def error(self) -> str:
method error (line 4627) | def error(self, value: str):
method error2 (line 4634) | def error2(self) -> str:
method error2 (line 4638) | def error2(self, value: str):
method errorSource (line 4642) | def errorSource(self) -> str:
method errorSource (line 4646) | def errorSource(self, value: str):
method errorc2 (line 4650) | def errorc2(self) -> str:
method errorc2 (line 4654) | def errorc2(self, value: str):
method errorc22 (line 4661) | def errorc22(self) -> str:
method errorc22 (line 4665) | def errorc22(self, value: str):
method errorc2Source (line 4669) | def errorc2Source(self) -> str:
method errorc2Source (line 4673) | def errorc2Source(self, value: str):
method database (line 4677) | def database(self) -> str:
method database (line 4681) | def database(self, value: str):
method raspiModelFull (line 4685) | def raspiModelFull(self) -> str:
method raspiModelFull (line 4689) | def raspiModelFull(self, value: str):
method raspiModelLower5 (line 4693) | def raspiModelLower5(self) -> bool:
method raspiModelLower5 (line 4697) | def raspiModelLower5(self, value: bool):
method boardRevision (line 4701) | def boardRevision(self) -> str:
method boardRevision (line 4705) | def boardRevision(self, value: str):
method kernelVersion (line 4709) | def kernelVersion(self) -> str:
method kernelVersion (line 4713) | def kernelVersion(self, value: str):
method debianVersion (line 4717) | def debianVersion(self) -> str:
method debianVersion (line 4721) | def debianVersion(self, value: str):
method noCamera (line 4725) | def noCamera(self) -> bool:
method noCamera (line 4729) | def noCamera(self, value: bool):
method supportedCameras (line 4733) | def supportedCameras(self) -> list:
method supportedCameras (line 4737) | def supportedCameras(self, value: list):
method usbCamAvailable (line 4741) | def usbCamAvailable(self) -> bool:
method usbCamAvailable (line 4745) | def usbCamAvailable(self, value: bool):
method aiCamAvailable (line 4749) | def aiCamAvailable(self) -> bool:
method aiCamAvailable (line 4753) | def aiCamAvailable(self, value: bool):
method noCamera (line 4757) | def noCamera(self, value: bool):
method piCameras (line 4761) | def piCameras(self) -> list:
method piCameras (line 4765) | def piCameras(self, value: list):
method activeCamera (line 4769) | def activeCamera(self) -> int:
method activeCamera (line 4773) | def activeCamera(self, value: int):
method activeCameraIsUsb (line 4777) | def activeCameraIsUsb(self) -> bool:
method activeCameraIsUsb (line 4781) | def activeCameraIsUsb(self, value: bool):
method activeCameraHasAi (line 4785) | def activeCameraHasAi(self) -> bool:
method activeCameraHasAi (line 4789) | def activeCameraHasAi(self, value: bool):
method activeCameraUsbDev (line 4793) | def activeCameraUsbDev(self) -> str:
method activeCameraUsbDev (line 4797) | def activeCameraUsbDev(self, value: str):
method activeCameraInfo (line 4801) | def activeCameraInfo(self) -> str:
method activeCameraInfo (line 4805) | def activeCameraInfo(self, value: str):
method activeCameraModel (line 4809) | def activeCameraModel(self) -> str:
method activeCameraModel (line 4813) | def activeCameraModel(self, value: str):
method secondCamera (line 4817) | def secondCamera(self) -> int:
method secondCamera (line 4821) | def secondCamera(self, value: int):
method secondCameraIsUsb (line 4825) | def secondCameraIsUsb(self) -> bool:
method secondCameraIsUsb (line 4829) | def secondCameraIsUsb(self, value: bool):
method secondCameraHasAi (line 4833) | def secondCameraHasAi(self) -> bool:
method secondCameraHasAi (line 4837) | def secondCameraHasAi(self, value: bool):
method secondCameraUsbDev (line 4841) | def secondCameraUsbDev(self) -> str:
method secondCameraUsbDev (line 4845) | def secondCameraUsbDev(self, value: str):
method secondCameraInfo (line 4849) | def secondCameraInfo(self) -> str:
method secondCameraInfo (line 4853) | def secondCameraInfo(self, value: str):
method secondCameraModel (line 4857) | def secondCameraModel(self) -> str:
method secondCameraModel (line 4861) | def secondCameraModel(self, value: str):
method hasMicrophone (line 4865) | def hasMicrophone(self) -> bool:
method hasMicrophone (line 4869) | def hasMicrophone(self, value: bool):
method defaultMic (line 4873) | def defaultMic(self) -> str:
method defaultMic (line 4877) | def defaultMic(self, value: str):
method isMicMuted (line 4881) | def isMicMuted(self) -> bool:
method isMicMuted (line 4885) | def isMicMuted(self, value: bool):
method recordAudio (line 4889) | def recordAudio(self) -> bool:
method recordAudio (line 4893) | def recordAudio(self, value: bool):
method audioSync (line 4897) | def audioSync(self) -> float:
method audioSync (line 4901) | def audioSync(self, value: float):
method photoRoot (line 4905) | def photoRoot(self):
method photoRoot (line 4909) | def photoRoot(self, value: str):
method cameraPhotoSubPath (line 4913) | def cameraPhotoSubPath(self):
method cameraPhotoSubPath (line 4917) | def cameraPhotoSubPath(self, value: str):
method prgOutputPath (line 4921) | def prgOutputPath(self):
method prgOutputPath (line 4925) | def prgOutputPath(self, value: str):
method cameraHistogramSubPath (line 4929) | def cameraHistogramSubPath(self):
method photoType (line 4933) | def photoType(self) -> str:
method photoType (line 4937) | def photoType(self, value: str):
method rawPhotoType (line 4948) | def rawPhotoType(self) -> str:
method rawPhotoType (line 4952) | def rawPhotoType(self, value: str):
method videoType (line 4959) | def videoType(self) -> str:
method videoType (line 4963) | def videoType(self, value: str):
method isZoomModeDraw (line 4971) | def isZoomModeDraw(self) -> bool:
method isZoomModeDraw (line 4975) | def isZoomModeDraw(self, value: bool):
method zoomFactor (line 4979) | def zoomFactor(self):
method zoomFactor (line 4983) | def zoomFactor(self, value: int):
method zoomFactorStep (line 4991) | def zoomFactorStep(self):
method zoomFactorStep (line 4995) | def zoomFactorStep(self, value: int):
method scalerCropLiveView (line 5003) | def scalerCropLiveView(self) -> tuple:
method scalerCropLiveView (line 5007) | def scalerCropLiveView(self, value: tuple):
method scalerCropLiveViewStr (line 5011) | def scalerCropLiveViewStr(self) -> str:
method scalerCropLiveViewStr (line 5015) | def scalerCropLiveViewStr(self, value: str):
method scalerCropMin (line 5019) | def scalerCropMin(self) -> tuple:
method scalerCropMin (line 5023) | def scalerCropMin(self, value: tuple):
method scalerCropMax (line 5027) | def scalerCropMax(self) -> tuple:
method scalerCropMax (line 5031) | def scalerCropMax(self, value: tuple):
method scalerCropDef (line 5035) | def scalerCropDef(self) -> tuple:
method scalerCropDef (line 5039) | def scalerCropDef(self, value: tuple):
method syncAspectRatio (line 5043) | def syncAspectRatio(self) -> bool:
method syncAspectRatio (line 5047) | def syncAspectRatio(self, value: bool):
method curMenu (line 5051) | def curMenu(self) -> str:
method curMenu (line 5055) | def curMenu(self, value: str):
method lastLiveTab (line 5059) | def lastLiveTab(self):
method lastLiveTab (line 5063) | def lastLiveTab(self, value: str):
method lastConfigTab (line 5067) | def lastConfigTab(self):
method lastConfigTab (line 5071) | def lastConfigTab(self, value: str):
method lastInfoTab (line 5075) | def lastInfoTab(self):
method lastInfoTab (line 5079) | def lastInfoTab(self, value: str):
method lastPhotoSeriesTab (line 5083) | def lastPhotoSeriesTab(self):
method lastPhotoSeriesTab (line 5087) | def lastPhotoSeriesTab(self, value: str):
method lastTriggerTab (line 5091) | def lastTriggerTab(self):
method lastTriggerTab (line 5095) | def lastTriggerTab(self, value: str):
method lastCamTab (line 5099) | def lastCamTab(self):
method lastCamTab (line 5103) | def lastCamTab(self, value: str):
method lastConsoleTab (line 5107) | def lastConsoleTab(self):
method lastConsoleTab (line 5111) | def lastConsoleTab(self, value: str):
method lastSettingsTab (line 5115) | def lastSettingsTab(self):
method lastSettingsTab (line 5119) | def lastSettingsTab(self, value: str):
method isDisplayHidden (line 5123) | def isDisplayHidden(self) -> bool:
method isDisplayHidden (line 5127) | def isDisplayHidden(self, value: bool):
method isLiveStream (line 5131) | def isLiveStream(self) -> bool:
method isLiveStream (line 5135) | def isLiveStream(self, value: bool):
method isLiveStream2 (line 5139) | def isLiveStream2(self) -> bool:
method isLiveStream2 (line 5143) | def isLiveStream2(self, value: bool):
method isVideoRecording (line 5147) | def isVideoRecording(self) -> bool:
method isVideoRecording (line 5151) | def isVideoRecording(self, value: bool):
method isVideoRecording2 (line 5155) | def isVideoRecording2(self) -> bool:
method isVideoRecording2 (line 5159) | def isVideoRecording2(self, value: bool):
method isStereoCamActive (line 5163) | def isStereoCamActive(self) -> bool:
method isStereoCamActive (line 5167) | def isStereoCamActive(self, value: bool):
method isStereoCamRecording (line 5171) | def isStereoCamRecording(self) -> bool:
method isStereoCamRecording (line 5175) | def isStereoCamRecording(self, value: bool):
method isAudioRecording (line 5179) | def isAudioRecording(self) -> bool:
method isAudioRecording (line 5183) | def isAudioRecording(self, value: bool):
method isPhotoSeriesRecording (line 5187) | def isPhotoSeriesRecording(self) -> bool:
method isPhotoSeriesRecording (line 5191) | def isPhotoSeriesRecording(self, value: bool):
method isTriggerRecording (line 5195) | def isTriggerRecording(self) -> bool:
method isTriggerRecording (line 5199) | def isTriggerRecording(self, value: bool):
method isTriggerWaiting (line 5203) | def isTriggerWaiting(self) -> bool:
method isTriggerWaiting (line 5207) | def isTriggerWaiting(self, value: bool):
method isTriggerTesting (line 5211) | def isTriggerTesting(self) -> bool:
method isTriggerTesting (line 5215) | def isTriggerTesting(self, value: bool):
method isEventhandling (line 5219) | def isEventhandling(self) -> bool:
method isEventhandling (line 5223) | def isEventhandling(self, value: bool):
method isEventsWaiting (line 5227) | def isEventsWaiting(self) -> bool:
method isEventsWaiting (line 5231) | def isEventsWaiting(self, value: bool):
method buttonClear (line 5235) | def buttonClear(self) -> str:
method displayPhoto (line 5239) | def displayPhoto(self):
method displayPhoto (line 5243) | def displayPhoto(self, value: str):
method displayFile (line 5247) | def displayFile(self):
method displayFile (line 5251) | def displayFile(self, value: str):
method displayMeta (line 5255) | def displayMeta(self):
method displayMeta (line 5259) | def displayMeta(self, value: str):
method displayMetaFirst (line 5263) | def displayMetaFirst(self):
method displayMetaFirst (line 5267) | def displayMetaFirst(self, value: int):
method displayMetaLast (line 5271) | def displayMetaLast(self):
method displayMetaLast (line 5275) | def displayMetaLast(self, value: int):
method displayHistogram (line 5279) | def displayHistogram(self) -> str:
method displayHistogram (line 5283) | def displayHistogram(self, value: str):
method displayContent (line 5287) | def displayContent(self) -> str:
method displayContent (line 5291) | def displayContent(self, value: str):
method cv2Available (line 5299) | def cv2Available(self) -> bool:
method cv2Available (line 5303) | def cv2Available(self, value: bool):
method numpyAvailable (line 5307) | def numpyAvailable(self) -> bool:
method numpyAvailable (line 5311) | def numpyAvailable(self, value: bool):
method matplotlibAvailable (line 5315) | def matplotlibAvailable(self) -> bool:
method matplotlibAvailable (line 5319) | def matplotlibAvailable(self, value: bool):
method flaskJwtLibAvailable (line 5323) | def flaskJwtLibAvailable(self) -> bool:
method flaskJwtLibAvailable (line 5327) | def flaskJwtLibAvailable(self, value: bool):
method imx500Available (line 5331) | def imx500Available(self) -> bool:
method imx500Available (line 5335) | def imx500Available(self, value: bool):
method munkresAvailable (line 5339) | def munkresAvailable(self) -> bool:
method munkresAvailable (line 5343) | def munkresAvailable(self, value: bool):
method useUsbCameras (line 5347) | def useUsbCameras(self) -> bool:
method useUsbCameras (line 5353) | def useUsbCameras(self, value: bool):
method useStereo (line 5357) | def useStereo(self) -> bool:
method useStereo (line 5363) | def useStereo(self, value: bool):
method useHistograms (line 5367) | def useHistograms(self) -> bool:
method useHistograms (line 5371) | def useHistograms(self, value: bool):
method useCameraAi (line 5375) | def useCameraAi(self) -> bool:
method useCameraAi (line 5379) | def useCameraAi(self, value: bool):
method supportsExtMotionDetection (line 5383) | def supportsExtMotionDetection(self) -> bool:
method supportsHistograms (line 5390) | def supportsHistograms(self) -> bool:
method supportsStereo (line 5397) | def supportsStereo(self) -> bool:
method supportsAPI (line 5404) | def supportsAPI(self) -> bool:
method supportsUsbCamera (line 5409) | def supportsUsbCamera(self) -> bool:
method whyNotSupportsHistograms (line 5414) | def whyNotSupportsHistograms(self) -> str:
method whyNotsupportsExtMotionDetection (line 5427) | def whyNotsupportsExtMotionDetection(self) -> str:
method whyNotSupportsStereo (line 5440) | def whyNotSupportsStereo(self) -> str:
method whyNotSupportsAPI (line 5456) | def whyNotSupportsAPI(self) -> str:
method whyNotSupportsUsbCamera (line 5465) | def whyNotSupportsUsbCamera(self) -> str:
method whyNotSupportsAiCamera (line 5474) | def whyNotSupportsAiCamera(self) -> str:
method requireAuthForStreaming (line 5496) | def requireAuthForStreaming(self) -> bool:
method requireAuthForStreaming (line 5500) | def requireAuthForStreaming(self, value: bool):
method locLongitude (line 5504) | def locLongitude(self) -> float:
method locLongitude (line 5508) | def locLongitude(self, value: float):
method locLatitude (line 5512) | def locLatitude(self) -> float:
method locLatitude (line 5516) | def locLatitude(self, value: float):
method locElevation (line 5520) | def locElevation(self) -> float:
method locElevation (line 5524) | def locElevation(self, value: float):
method locTzKey (line 5528) | def locTzKey(self) -> str:
method locTzKey (line 5532) | def locTzKey(self, value: str):
method timeZoneKeys (line 5535) | def timeZoneKeys(self) -> list:
method pvCamera (line 5544) | def pvCamera(self) -> int:
method pvCamera (line 5548) | def pvCamera(self, value: int):
method pvFrom (line 5552) | def pvFrom(self) -> date:
method pvFrom (line 5556) | def pvFrom(self, value: date):
method pvFromStr (line 5560) | def pvFromStr(self) -> str:
method pvFromStr (line 5564) | def pvFromStr(self, value: str):
method pvTo (line 5573) | def pvTo(self) -> date:
method pvTo (line 5577) | def pvTo(self, value: date):
method pvToStr (line 5581) | def pvToStr(self) -> str:
method pvToStr (line 5585) | def pvToStr(self, value: str):
method pvList (line 5594) | def pvList(self) -> list:
method pvList (line 5598) | def pvList(self, value: list):
method jwtAuthenticationActive (line 5602) | def jwtAuthenticationActive(self) -> bool:
method jwtAuthenticationActive (line 5606) | def jwtAuthenticationActive(self, value: bool):
method jwtKeyStore (line 5610) | def jwtKeyStore(self) -> str:
method jwtKeyStore (line 5614) | def jwtKeyStore(self, value: str):
method jwtAccessTokenExpirationMin (line 5618) | def jwtAccessTokenExpirationMin(self) -> int:
method jwtAccessTokenExpirationMin (line 5622) | def jwtAccessTokenExpirationMin(self, value: int):
method jwtRefreshTokenExpirationDays (line 5626) | def jwtRefreshTokenExpirationDays(self) -> int:
method jwtRefreshTokenExpirationDays (line 5630) | def jwtRefreshTokenExpirationDays(self, value: int):
method streamingClients (line 5634) | def streamingClients(self) -> list:
method streamingClients (line 5638) | def streamingClients(self, value: list):
method registerStreamingClient (line 5641) | def registerStreamingClient(self, ipaddr: str, stream: str, thread: int):
method unregisterStreamingClient (line 5671) | def unregisterStreamingClient(self, ipaddr: str, stream: str, thread: ...
method streamingClientStreams (line 5691) | def streamingClientStreams(self, ipaddr: str) -> str:
method updateStreamingClients (line 5704) | def updateStreamingClients(self):
method vButtonsRows (line 5715) | def vButtonsRows(self) -> int:
method vButtonsRows (line 5719) | def vButtonsRows(self, value: int):
method vButtonsCols (line 5723) | def vButtonsCols(self) -> int:
method vButtonsCols (line 5727) | def vButtonsCols(self, value: int):
method vButtons (line 5731) | def vButtons(self) -> list[list[vButton]]:
method vButtons (line 5735) | def vButtons(self, value: list):
method vButtonCommand (line 5739) | def vButtonCommand(self) -> str:
method vButtonCommand (line 5743) | def vButtonCommand(self, value: str):
method vButtonArgs (line 5747) | def vButtonArgs(self) -> list:
method vButtonArgs (line 5751) | def vButtonArgs(self, value: list):
method vButtonReturncode (line 5755) | def vButtonReturncode(self) -> int:
method vButtonReturncode (line 5759) | def vButtonReturncode(self, value: int):
method vButtonStdout (line 5763) | def vButtonStdout(self) -> str:
method vButtonStdout (line 5767) | def vButtonStdout(self, value: str):
method vButtonStderr (line 5771) | def vButtonStderr(self) -> str:
method vButtonStderr (line 5775) | def vButtonStderr(self, value: str):
method vButtonHasCommandLine (line 5779) | def vButtonHasCommandLine(self) -> bool:
method vButtonHasCommandLine (line 5783) | def vButtonHasCommandLine(self, value: bool):
method aButtonsRows (line 5787) | def aButtonsRows(self) -> int:
method aButtonsRows (line 5791) | def aButtonsRows(self, value: int):
method aButtonsCols (line 5795) | def aButtonsCols(self) -> int:
method aButtonsCols (line 5799) | def aButtonsCols(self, value: int):
method aButtons (line 5803) | def aButtons(self) -> list[list[ActionButton]]:
method aButtons (line 5807) | def aButtons(self, value: list):
method aButtonAction (line 5811) | def aButtonAction(self) -> str:
method aButtonAction (line 5815) | def aButtonAction(self, value: str):
method lButtonsRows (line 5819) | def lButtonsRows(self) -> int:
method lButtonsRows (line 5823) | def lButtonsRows(self, value: int):
method lButtonsCols (line 5827) | def lButtonsCols(self) -> int:
method lButtonsCols (line 5831) | def lButtonsCols(self, value: int):
method lButtons (line 5835) | def lButtons(self) -> list[list[LiveButton]]:
method lButtons (line 5839) | def lButtons(self, value: list):
method curDeviceId (line 5843) | def curDeviceId(self) -> str:
method curDeviceId (line 5847) | def curDeviceId(self, value: str):
method curDevice (line 5851) | def curDevice(self) -> GPIODevice:
method curDevice (line 5855) | def curDevice(self, value: GPIODevice):
method curDeviceType (line 5859) | def curDeviceType(self) -> dict:
method curDeviceType (line 5863) | def curDeviceType(self, value: dict):
method gpioDevices (line 5867) | def gpioDevices(self) ->list[GPIODevice]:
method gpioDevices (line 5871) | def gpioDevices(self, value: list[GPIODevice]):
method cfgPath (line 5875) | def cfgPath(self) -> str:
method cfgPath (line 5879) | def cfgPath(self, value: str):
method cfgBackupPath (line 5883) | def cfgBackupPath(self) -> str:
method cfgBackupPath (line 5887) | def cfgBackupPath(self, value: str):
method versionCurrent (line 5891) | def versionCurrent(self) -> str:
method versionLatest (line 5895) | def versionLatest(self) -> str:
method versionLatest (line 5901) | def versionLatest(self, value: str):
method versionCheckTime (line 5905) | def versionCheckTime(self) -> datetime:
method versionCheckTime (line 5909) | def versionCheckTime(self, value: datetime):
method versionCheckTimeIso (line 5914) | def versionCheckTimeIso(self) -> str:
method versionCheckIntervalHours (line 5921) | def versionCheckIntervalHours(self) -> int:
method versionCheckIntervalHours (line 5925) | def versionCheckIntervalHours(self, value: int):
method versionCheckEnabled (line 5929) | def versionCheckEnabled(self) -> bool:
method versionCheckEnabled (line 5933) | def versionCheckEnabled(self, value: bool):
method versionCheckFrom (line 5937) | def versionCheckFrom(self) -> str:
method versionCheckFrom (line 5945) | def versionCheckFrom(self, value: str):
method getLatestVersion (line 5948) | def getLatestVersion(self, now: bool = False) -> str:
method canUpdate (line 5993) | def canUpdate(self) -> bool:
method isLaterVersion (line 6021) | def isLaterVersion(self, v1: str, v2: str) -> bool:
method updateDone (line 6047) | def updateDone(self) -> bool:
method updateDone (line 6051) | def updateDone(self, value: bool):
method webCamActiveCamPhotoCfg (line 6055) | def webCamActiveCamPhotoCfg(self) -> str:
method webCamActiveCamPhotoCfg (line 6059) | def webCamActiveCamPhotoCfg(self, value: str):
method webCamSecondCamPhotoCfg (line 6063) | def webCamSecondCamPhotoCfg(self) -> str:
method webCamSecondCamPhotoCfg (line 6067) | def webCamSecondCamPhotoCfg(self, value: str):
method API_active (line 6071) | def API_active(self) -> bool:
method API_active (line 6075) | def API_active(self, value: bool):
method useAPI (line 6079) | def useAPI(self) -> bool:
method useAPI (line 6083) | def useAPI(self, value: bool):
method processInfo (line 6087) | def processInfo(self) -> str:
method ffmpegProcessInfo (line 6095) | def ffmpegProcessInfo(self) -> str:
method deviceTypes (line 6103) | def deviceTypes(self) -> list:
method getDevice (line 6106) | def getDevice(self, id: str) -> GPIODevice:
method getDeviceType (line 6114) | def getDeviceType(self, id: str) -> dict:
method freeGpioPins (line 6123) | def freeGpioPins(self) -> list[int]:
method pythonInfo (line 6147) | def pythonInfo(self) -> str:
method flaskInfo (line 6164) | def flaskInfo(self) -> str:
method libcameraInfo (line 6184) | def libcameraInfo(self) -> str:
method picamera2Info (line 6223) | def picamera2Info(self) -> str:
method openCvInfo (line 6243) | def openCvInfo(self) -> str:
method numpyInfo (line 6261) | def numpyInfo(self) -> str:
method matplotlibInfo (line 6281) | def matplotlibInfo(self) -> str:
method flask_jwt_extended (line 6301) | def flask_jwt_extended(self) -> str:
method imx500Info (line 6321) | def imx500Info(self) -> str:
method munkresInfo (line 6338) | def munkresInfo(self) -> str:
method gunicornInfo (line 6358) | def gunicornInfo(self) -> str:
method wsgiInfo (line 6378) | def wsgiInfo(self) -> str:
method startupInfo (line 6398) | def startupInfo(self) -> str:
method environmentInfo (line 6411) | def environmentInfo(self) -> str:
method _checkModule (line 6421) | def _checkModule(self, moduleName: str):
method checkEnvironment (line 6440) | def checkEnvironment(self):
method _get_dpkg_info (line 6468) | def _get_dpkg_info(self, package: str) -> dict:
method is_time_synchronized (line 6504) | def is_time_synchronized(self) -> tuple[bool, bool]:
method runningInContainer (line 6524) | def runningInContainer(self):
method wait_for_time_sync (line 6534) | def wait_for_time_sync(self, timeout:int=60, interval:int=2) -> bool:
method displayBufferCount (line 6560) | def displayBufferCount(self) -> int:
method displayBufferIndex (line 6566) | def displayBufferIndex(self) -> str:
method isDisplayBufferIn (line 6578) | def isDisplayBufferIn(self) -> bool:
method displayBufferAdd (line 6586) | def displayBufferAdd(self):
method displayBufferRemove (line 6600) | def displayBufferRemove(self):
method displayBufferClear (line 6655) | def displayBufferClear(self):
method displayBufferCheck (line 6666) | def displayBufferCheck(self):
method isDisplayBufferFirst (line 6688) | def isDisplayBufferFirst(self) -> bool:
method isDisplayBufferLast (line 6700) | def isDisplayBufferLast(self) -> bool:
method displayBufferFirst (line 6711) | def displayBufferFirst(self):
method displayBufferNext (line 6729) | def displayBufferNext(self):
method displayBufferPrev (line 6754) | def displayBufferPrev(self):
method _lineGen (line 6773) | def _lineGen(self, s):
method _checkMicrophoneNoJson (line 6789) | def _checkMicrophoneNoJson(self):
method checkMicrophone (line 6843) | def checkMicrophone(self):
method getPiModel (line 6904) | def getPiModel() -> str:
method getBoardRevision (line 6921) | def getBoardRevision():
method getDebianVersion (line 6940) | def getDebianVersion(self):
method getOSArch (line 6958) | def getOSArch(self):
method getKernelVersion (line 6982) | def getKernelVersion(self):
method getOsName (line 6999) | def getOsName(self):
method checkJwtSettings (line 7033) | def checkJwtSettings(self) -> tuple:
method detect_startup_source (line 7103) | def detect_startup_source(self) -> int:
method _lineGen (line 7136) | def _lineGen(s):
method _countThreads (line 7152) | def _countThreads(self, process: str=None):
method getBaseHelpUrl (line 7259) | def getBaseHelpUrl(self) -> str:
method initFromDict (line 7269) | def initFromDict(cls, dict:dict):
method sliderPosToCtrlVal (line 7481) | def sliderPosToCtrlVal(self, min:float, max:float, default:float, pos:...
method ctrlValToSliderPos (line 7499) | def ctrlValToSliderPos(self, min:float, max:float, default:float, val:...
class Secrets (line 7524) | class Secrets():
method __init__ (line 7527) | def __init__(self) -> None:
method notifyUser (line 7533) | def notifyUser(self) -> str:
method notifyUser (line 7537) | def notifyUser(self, value: str):
method notifyPwd (line 7541) | def notifyPwd(self) -> str:
method notifyPwd (line 7545) | def notifyPwd(self, value: str):
method jwtSecretKey (line 7549) | def jwtSecretKey(self) -> str:
method jwtSecretKey (line 7553) | def jwtSecretKey(self, value: str):
class CameraCfg (line 7556) | class CameraCfg():
method __new__ (line 7558) | def __new__(cls):
method cameras (line 7616) | def cameras(self) -> list:
method cameras (line 7620) | def cameras(self, value: list):
method controls (line 7624) | def controls(self) -> CameraControls:
method controls (line 7628) | def controls(self, value: CameraControls):
method tuningConfig (line 7632) | def tuningConfig(self) -> TuningConfig:
method tuningConfig (line 7636) | def tuningConfig(self, value: TuningConfig):
method aiConfig (line 7640) | def aiConfig(self) -> AiConfig:
method aiConfig (line 7644) | def aiConfig(self, value: AiConfig):
method controlsBackup (line 7648) | def controlsBackup(self) -> CameraControls:
method controlsBackup (line 7652) | def controlsBackup(self, value: CameraControls):
method cameraProperties (line 7656) | def cameraProperties(self) -> CameraProperties:
method cameraProperties (line 7660) | def cameraProperties(self, value: CameraProperties):
method sensorModes (line 7664) | def sensorModes(self) -> list:
method sensorModes (line 7668) | def sensorModes(self, value: list):
method rawFormats (line 7672) | def rawFormats(self) -> list:
method rawFormats (line 7676) | def rawFormats(self, value: list):
method nrSensorModes (line 7680) | def nrSensorModes(self) -> int:
method liveViewConfig (line 7684) | def liveViewConfig(self) -> CameraConfig:
method liveViewConfig (line 7688) | def liveViewConfig(self, value: CameraConfig):
method photoConfig (line 7692) | def photoConfig(self) -> CameraConfig:
method photoConfig (line 7696) | def photoConfig(self, value: CameraConfig):
method rawConfig (line 7700) | def rawConfig(self) -> CameraConfig:
method rawConfig (line 7704) | def rawConfig(self, value: CameraConfig):
method videoConfig (line 7708) | def videoConfig(self) -> CameraConfig:
method videoConfig (line 7712) | def videoConfig(self, value: CameraConfig):
method cameraConfigs (line 7716) | def cameraConfigs(self) -> list:
method cameraConfigs (line 7720) | def cameraConfigs(self, value: list):
method triggerConfig (line 7724) | def triggerConfig(self) -> TriggerConfig:
method triggerConfig (line 7728) | def triggerConfig(self, value: TriggerConfig):
method serverConfig (line 7732) | def serverConfig(self) -> ServerConfig:
method serverConfig (line 7736) | def serverConfig(self, value: ServerConfig):
method streamingCfg (line 7740) | def streamingCfg(self) -> dict:
method streamingCfg (line 7744) | def streamingCfg(self, value: dict):
method streamingCfgInvalid (line 7748) | def streamingCfgInvalid(self) -> dict:
method streamingCfgInvalid (line 7752) | def streamingCfgInvalid(self, value: dict):
method stereoCfg (line 7756) | def stereoCfg(self) -> StereoConfig:
method stereoCfg (line 7760) | def stereoCfg(self, value: StereoConfig):
method secrets (line 7764) | def secrets(self) -> Secrets:
method secrets (line 7768) | def secrets(self, value: Secrets):
method setSupportedCameras (line 7771) | def setSupportedCameras(self):
method setPiCameras (line 7800) | def setPiCameras(self):
method resetActiveCameraSettings (line 7809) | def resetActiveCameraSettings(self):
method _persistCl (line 7855) | def _persistCl(self, cl, fn: str, cfgPath: str):
method persist (line 7865) | def persist(self, cfgPath: str):
method _toJson (line 7888) | def _toJson(self, cl):
method _loadConfigCl (line 7891) | def _loadConfigCl(self, cl, fn: str, cfgPath: str):
method _initStreamingConfigFromDisc (line 7906) | def _initStreamingConfigFromDisc(self, fn: str, cfgPath: str) -> dict:
method _initGpioDevicesFromDisc (line 7944) | def _initGpioDevicesFromDisc(self, fn: str, cfgPath: str) -> list:
method loadConfig (line 7963) | def loadConfig(self, cfgPath):
method _lineGen (line 7993) | def _lineGen(s):
method setUsbCameraProperties (line 8008) | def setUsbCameraProperties(self) -> bool:
method getUsbPixelArraySize (line 8073) | def getUsbPixelArraySize(self) -> tuple:
method setUsbSensorModes (line 8111) | def setUsbSensorModes(self) -> bool:
method setUsbCamControls (line 8187) | def setUsbCamControls(self):
FILE: raspiCamSrv/camera_pi.py
class CameraStopError (line 75) | class CameraStopError(RuntimeError):
class UsbCameraOpenError (line 78) | class UsbCameraOpenError(RuntimeError):
class UsbCameraNoFrameReceivedError (line 87) | class UsbCameraNoFrameReceivedError(RuntimeError):
class Classification (line 95) | class Classification:
method __init__ (line 96) | def __init__(self, idx: int, score: float):
class Detection (line 102) | class Detection:
method __init__ (line 103) | def __init__(self, coords, category, conf, metadata):
class Cam2Detection (line 123) | class Cam2Detection:
method __init__ (line 124) | def __init__(self, coords, category, conf, metadata):
class StreamingOutput (line 140) | class StreamingOutput(io.BufferedIOBase):
method __init__ (line 141) | def __init__(self):
method write (line 147) | def write(self, buf):
class CameraController (line 157) | class CameraController:
method __init__ (line 160) | def __init__(self, isUsb: bool = False, usbDev: str = None, forActiveC...
method configuration (line 181) | def configuration(self) -> CameraConfiguration:
method isUsb (line 185) | def isUsb(self) -> bool:
method usbDev (line 189) | def usbDev(self) -> str:
method requestCameraForConfig (line 192) | def requestCameraForConfig(
method restoreLivestream (line 332) | def restoreLivestream(self, cam, exclusive: bool):
method restoreLivestream2 (line 370) | def restoreLivestream2(self, cam, exclusive: bool):
method requestStart (line 408) | def requestStart(
method requestStop (line 632) | def requestStop(self, cam, close=False):
method requestConfig (line 768) | def requestConfig(
method codeGenConfig (line 1065) | def codeGenConfig(self, cfg: CameraConfiguration):
method copyConfig (line 1141) | def copyConfig(self, cfg: CameraConfiguration) -> CameraConfiguration:
method compareConfig (line 1210) | def compareConfig(
method clearConfig (line 1406) | def clearConfig(self):
method registerEncoder (line 1411) | def registerEncoder(self, task: str, encoder):
method stopEncoder (line 1418) | def stopEncoder(self, cam, task: str):
class CameraEvent (line 1431) | class CameraEvent(object):
method __init__ (line 1436) | def __init__(self):
method wait (line 1440) | def wait(self):
method set (line 1455) | def set(self):
method clear (line 1480) | def clear(self):
method toDict (line 1487) | def toDict(self):
class Camera (line 1503) | class Camera:
method __new__ (line 1623) | def __new__(cls):
method isCamera2Available (line 1723) | def isCamera2Available(cls) -> bool:
method initCamera (line 1742) | def initCamera(cls):
method getActiveCamera (line 1972) | def getActiveCamera() -> tuple:
method switchCamera (line 2126) | def switchCamera(cls):
method startLiveStream (line 2387) | def startLiveStream(cls):
method startLiveStream2 (line 2444) | def startLiveStream2(cls):
method stopLiveStream (line 2513) | def stopLiveStream(cls):
method stopLiveStream2 (line 2548) | def stopLiveStream2(cls):
method restartLiveStream (line 2586) | def restartLiveStream():
method restartLiveStream2 (line 2606) | def restartLiveStream2():
method getLiveViewImageForMotionDetection (line 2627) | def getLiveViewImageForMotionDetection(self):
method getLeftImageForStereo (line 2645) | def getLeftImageForStereo(self):
method getRightImageForStereo (line 2653) | def getRightImageForStereo(self):
method startAnimation (line 2663) | def startAnimation(self):
method startAnimation2 (line 2707) | def startAnimation2(self):
method get_frame (line 2751) | def get_frame(self):
method get_frame2 (line 2775) | def get_frame2(self):
method get_photoFrame (line 2801) | def get_photoFrame(self):
method get_photoFrame_hr (line 2818) | def get_photoFrame_hr(self):
method get_photoFrame2 (line 2842) | def get_photoFrame2(self):
method get_photoFrame2_hr (line 2864) | def get_photoFrame2_hr(self):
method loadCameraSpecifics (line 2901) | def loadCameraSpecifics():
method loadUsbCameraSpecifics (line 3029) | def loadUsbCameraSpecifics() -> bool:
method setSecondCamera (line 3132) | def setSecondCamera(cls):
method setStreamingConfigs (line 3290) | def setStreamingConfigs(cls):
method restoreConfigFromStreamingConfig (line 3649) | def restoreConfigFromStreamingConfig(cls):
method configure (line 3745) | def configure(cfg: CameraConfig, cfgPhoto: CameraConfig):
method requiresTimeForAutoAlgos (line 3826) | def requiresTimeForAutoAlgos() -> bool:
method applyMappedControlToUsbCamera (line 3843) | def applyMappedControlToUsbCamera(
method applyDirectControlToUsbCamera (line 3902) | def applyDirectControlToUsbCamera(
method applyControlsToUsbCamera (line 3953) | def applyControlsToUsbCamera(
method usbFrameApplyControls (line 4003) | def usbFrameApplyControls(
method applyControls (line 4118) | def applyControls(
method applyControlsForAfCycle (line 4390) | def applyControlsForAfCycle(camCfg: CameraConfig):
method applyControlsForLivestream (line 4441) | def applyControlsForLivestream(wait: float = None):
method stopCameraSystem (line 4456) | def stopCameraSystem():
method _thread (line 4576) | def _thread(cls):
method _thread2 (line 4709) | def _thread2(cls):
method framesUsb (line 4811) | def framesUsb():
method frames (line 4914) | def frames():
method frames2Usb (line 4989) | def frames2Usb():
method frames2 (line 5042) | def frames2():
method getUsbScalerCrop (line 5098) | def getUsbScalerCrop(width: int, height: int, log=True, forCam2=None) ...
method getUsbCamMetadata (line 5151) | def getUsbCamMetadata(cam, log=True) -> dict:
method takeImage (line 5219) | def takeImage(
method takeImage2 (line 5358) | def takeImage2(
method quickPhoto (line 5477) | def quickPhoto(fp: str, saveImage: bool = True) -> tuple:
method quickUsbVideoThread (line 5524) | def quickUsbVideoThread(out):
method quickVideoStart (line 5560) | def quickVideoStart(fp: str) -> tuple:
method quickVideoStop (line 5631) | def quickVideoStop(encoder) -> tuple:
method startCircular (line 5671) | def startCircular(buffersizeSec=5) -> tuple:
method stopCircular (line 5707) | def stopCircular(encoder) -> tuple:
method recordCircular (line 5731) | def recordCircular(circ: CircularOutput, fp: str) -> tuple:
method stopRecordingCircular (line 5756) | def stopRecordingCircular(circ: CircularOutput) -> tuple:
method takeRawImage (line 5780) | def takeRawImage(
method takeRawImage2 (line 5915) | def takeRawImage2(
method _videoThreadUsb (line 6034) | def _videoThreadUsb():
method _videoThread (line 6151) | def _videoThread():
method _videoThread2Usb (line 6282) | def _videoThread2Usb():
method _videoThread2 (line 6407) | def _videoThread2():
method recordVideo (line 6530) | def recordVideo(
method recordVideo2 (line 6598) | def recordVideo2(
method stopVideoRecording (line 6667) | def stopVideoRecording(noEvents: bool = False):
method stopVideoRecording2 (line 6690) | def stopVideoRecording2(noEvents: bool = False):
method isVideoRecording (line 6711) | def isVideoRecording() -> bool:
method isVideoRecording2 (line 6715) | def isVideoRecording2() -> bool:
method getLensPosition (line 6719) | def getLensPosition() -> float:
method getMetaData (line 6727) | def getMetaData() -> dict:
method _photoSeriesThread (line 6735) | def _photoSeriesThread():
method startPhotoSeries (line 7160) | def startPhotoSeries(ser: Series):
method stopPhotoSeries (line 7179) | def stopPhotoSeries():
method cameraStatus (line 7199) | def cameraStatus(cls, camNum) -> str:
method resetScalerCrop (line 7253) | def resetScalerCrop(cls):
method resetScalerCropUsb (line 7274) | def resetScalerCropUsb(cls):
method resetAiCache (line 7297) | def resetAiCache():
method resetAiCache2 (line 7310) | def resetAiCache2():
method get_label (line 7324) | def get_label(request: CompletedRequest, idx: int) -> str:
method parse_and_draw_classification_results (line 7335) | def parse_and_draw_classification_results(request: CompletedRequest):
method parse_classification_results (line 7341) | def parse_classification_results(request: CompletedRequest) -> List[Cl...
method draw_classification_results (line 7358) | def draw_classification_results(request: CompletedRequest, results: Li...
method ai_output_tensor_parse (line 7403) | def ai_output_tensor_parse(metadata: dict):
method ai_output_tensor_draw (line 7422) | def ai_output_tensor_draw(request: CompletedRequest, boxes, scores, ke...
method picamera2_pre_callback (line 7437) | def picamera2_pre_callback(request: CompletedRequest):
method set_drawer (line 7444) | def set_drawer():
method parse_detections (line 7452) | def parse_detections(metadata: dict):
method get_labels (line 7499) | def get_labels():
method draw_detections (line 7509) | def draw_detections(request, stream="main"):
method create_and_draw_masks (line 7569) | def create_and_draw_masks(request: CompletedRequest):
method create_masks (line 7579) | def create_masks(request: CompletedRequest) -> Dict[int, np.ndarray]:
method compose_overlay (line 7603) | def compose_overlay(masks):
method draw_masks (line 7613) | def draw_masks(request: CompletedRequest, overlay: np.ndarray):
method cam2_get_label (line 7633) | def cam2_get_label(request: CompletedRequest, idx: int) -> str:
method cam2_parse_and_draw_classification_results (line 7644) | def cam2_parse_and_draw_classification_results(request: CompletedReque...
method cam2_parse_classification_results (line 7650) | def cam2_parse_classification_results(request: CompletedRequest) -> Li...
method cam2_draw_classification_results (line 7671) | def cam2_draw_classification_results(request: CompletedRequest, result...
method cam2_ai_output_tensor_parse (line 7720) | def cam2_ai_output_tensor_parse(metadata: dict):
method cam2_ai_output_tensor_draw (line 7744) | def cam2_ai_output_tensor_draw(request: CompletedRequest, boxes, score...
method cam2_picamera2_pre_callback (line 7763) | def cam2_picamera2_pre_callback(request: CompletedRequest):
method cam2_set_drawer (line 7770) | def cam2_set_drawer():
method cam2_parse_detections (line 7778) | def cam2_parse_detections(metadata: dict):
method cam2_get_labels (line 7822) | def cam2_get_labels():
method cam2_draw_detections (line 7832) | def cam2_draw_detections(request, stream="main"):
method cam2_create_and_draw_masks (line 7890) | def cam2_create_and_draw_masks(request: CompletedRequest):
method cam2_create_masks (line 7900) | def cam2_create_masks(request: CompletedRequest) -> Dict[int, np.ndarr...
method cam2_compose_overlay (line 7924) | def cam2_compose_overlay(masks):
method cam2_draw_masks (line 7935) | def cam2_draw_masks(request: CompletedRequest, overlay: np.ndarray):
FILE: raspiCamSrv/config.py
function main (line 42) | def main():
function doSyncTransform (line 85) | def doSyncTransform(hflip: bool, vflip: bool, tgt: list) -> bool:
function doSyncAspectRatio (line 122) | def doSyncAspectRatio(ref: tuple, tgt: list) -> bool:
function syncAspectRatio (line 190) | def syncAspectRatio():
function findTuningFile (line 262) | def findTuningFile(tuning_file: str, dir=None) -> str:
function isTuningFile (line 299) | def isTuningFile(file: str, folder: str) -> bool:
function getTuningFiles (line 313) | def getTuningFiles(folder, defFile) -> list:
function tuningCfg (line 341) | def tuningCfg():
function customTuning (line 424) | def customTuning():
function defaultTuning (line 545) | def defaultTuning():
function deleteTuningFile (line 634) | def deleteTuningFile():
function downloadTuningFile (line 732) | def downloadTuningFile():
function uploadTuningFile (line 786) | def uploadTuningFile():
function liveViewCfg (line 864) | def liveViewCfg():
function addLiveViewControls (line 1050) | def addLiveViewControls():
function remLiveViewControls (line 1109) | def remLiveViewControls():
function photoCfg (line 1186) | def photoCfg():
function addPhotoControls (line 1352) | def addPhotoControls():
function remPhotoControls (line 1410) | def remPhotoControls():
function rawCfg (line 1484) | def rawCfg():
function addRawControls (line 1581) | def addRawControls():
function remRawControls (line 1639) | def remRawControls():
function videoCfg (line 1713) | def videoCfg():
function addVideoControls (line 1872) | def addVideoControls():
function remVideoControls (line 1930) | def remVideoControls():
function getAiModelFiles (line 2004) | def getAiModelFiles():
function setAiModelFile (line 2102) | def setAiModelFile():
function enableAi (line 2199) | def enableAi():
function ai_settings (line 2283) | def ai_settings():
FILE: raspiCamSrv/console.py
function console (line 20) | def console():
function execute (line 34) | def execute(row:None, col=None):
function execCommandline (line 80) | def execCommandline():
function do_action (line 123) | def do_action(row:None, col=None):
FILE: raspiCamSrv/db.py
function get_db (line 10) | def get_db():
function close_db (line 20) | def close_db(e=None):
function init_db (line 27) | def init_db():
function init_db_command (line 35) | def init_db_command():
function init_app (line 41) | def init_app(app):
FILE: raspiCamSrv/dbx.py
function get_dbx (line 9) | def get_dbx() -> sqlite3.Connection:
FILE: raspiCamSrv/gpioDevices.py
class StepperMotor (line 19) | class StepperMotor():
method __init__ (line 27) | def __init__(self, \
method in1 (line 148) | def in1(self) -> int:
method in1 (line 152) | def in1(self, value: int):
method in2 (line 156) | def in2(self) -> int:
method in2 (line 160) | def in2(self, value: int):
method in3 (line 164) | def in3(self) -> int:
method in3 (line 168) | def in3(self, value: int):
method in4 (line 172) | def in4(self) -> int:
method in4 (line 176) | def in4(self, value: int):
method mode (line 180) | def mode(self) -> int:
method mode (line 184) | def mode(self, value: int):
method speed (line 195) | def speed(self) -> float:
method speed (line 199) | def speed(self, value: float):
method stride_angle (line 213) | def stride_angle(self) -> float:
method gear_reduction (line 217) | def gear_reduction(self) -> float:
method current_angle (line 221) | def current_angle(self) -> float:
method current_angle (line 225) | def current_angle(self, value: float):
method value (line 229) | def value(self) -> float:
method value (line 233) | def value(self, value: float):
method swing_from (line 237) | def swing_from(self) -> float:
method swing_from (line 241) | def swing_from(self, value: float):
method swing_to (line 245) | def swing_to(self) -> float:
method swing_to (line 249) | def swing_to(self, value: float):
method swing_step (line 253) | def swing_step(self) -> float:
method swing_step (line 257) | def swing_step(self, value: float):
method swing_direction (line 261) | def swing_direction(self) -> float:
method swing_direction (line 265) | def swing_direction(self, value: float):
method _motor_step (line 268) | def _motor_step(self, direction:int):
method _step (line 293) | def _step(self, direction:int):
method step (line 313) | def step(self, steps:int):
method step_forward (line 327) | def step_forward(self, steps:int):
method step_backward (line 336) | def step_backward(self, steps:int):
method rotate (line 345) | def rotate(self, angle:float):
method rotate_right (line 364) | def rotate_right(self, angle:float):
method rotate_left (line 372) | def rotate_left(self, angle:float):
method rotate_to (line 380) | def rotate_to(self, target:float):
method swing (line 388) | def swing(self):
method wipe (line 406) | def wipe(self, angle_from:float=-45, angle_to:float=45, speed:float=1....
method _do_wipe (line 419) | def _do_wipe(self, angle_from, angle_to, speed, count):
method stop (line 453) | def stop(self):
method close (line 463) | def close(self):
class ServoPWM (line 471) | class ServoPWM():
method __init__ (line 485) | def __init__(self,
method is_pin_ok (line 542) | def is_pin_ok(self, pin:int) -> bool:
method current_angle (line 565) | def current_angle(self) -> float:
method current_angle (line 569) | def current_angle(self, value: float):
method value (line 603) | def value(self) -> float:
method value (line 607) | def value(self, value: float):
method _angle_to_duty_cycle (line 610) | def _angle_to_duty_cycle(self, angle:float) -> float:
method _duty_cycle_to_angle (line 623) | def _duty_cycle_to_angle(self, duty_cycle:float) -> float:
method min (line 640) | def min(self):
method max (line 645) | def max(self):
method mid (line 650) | def mid(self):
method rotate_to (line 655) | def rotate_to(self, angle:float):
method rotate_by (line 663) | def rotate_by(self, angle:float):
method rotate_left (line 671) | def rotate_left(self, angle:float):
method rotate_right (line 679) | def rotate_right(self, angle:float):
method stop (line 687) | def stop(self):
method close (line 693) | def close(self):
FILE: raspiCamSrv/home.py
function index (line 35) | def index():
function gen (line 66) | def gen(camera):
function gen2 (line 77) | def gen2(camera):
function live_view_feed (line 90) | def live_view_feed():
function video_feed (line 102) | def video_feed():
function video_feed2 (line 114) | def video_feed2():
function displayImage (line 128) | def displayImage(photo: str):
function focus_control (line 139) | def focus_control():
function trigger_autofocus (line 223) | def trigger_autofocus():
function set_zoom (line 263) | def set_zoom():
function zoom_in (line 308) | def zoom_in():
function checkScalerCrop (line 366) | def checkScalerCrop(crop: tuple, range: tuple) -> tuple:
function zoom_out (line 400) | def zoom_out():
function zoom_full (line 454) | def zoom_full():
function pan_up (line 499) | def pan_up():
function pan_left (line 538) | def pan_left():
function pan_center (line 583) | def pan_center():
function pan_right (line 631) | def pan_right():
function pan_down (line 670) | def pan_down():
function zoom_default (line 709) | def zoom_default():
function zoom_draw (line 740) | def zoom_draw():
function ae_control (line 755) | def ae_control():
function exposure_control (line 820) | def exposure_control():
function image_control (line 888) | def image_control():
function meta_clear (line 957) | def meta_clear():
function meta_prev (line 977) | def meta_prev():
function meta_next (line 998) | def meta_next():
function photoBuffer_add (line 1019) | def photoBuffer_add():
function photoBuffer_remove (line 1039) | def photoBuffer_remove():
function photoBuffer_prev (line 1058) | def photoBuffer_prev():
function photoBuffer_next (line 1078) | def photoBuffer_next():
function show_photo (line 1098) | def show_photo():
function hide_photo (line 1114) | def hide_photo():
function clear_buffer (line 1130) | def clear_buffer():
function take_photo (line 1146) | def take_photo():
function take_raw_photo (line 1183) | def take_raw_photo():
function record_video (line 1218) | def record_video():
function stop_recording (line 1264) | def stop_recording():
function generateHistogram (line 1285) | def generateHistogram(sc: ServerConfig):
function show_histogram (line 1326) | def show_histogram():
function show_metadata (line 1346) | def show_metadata():
function media_viewer (line 1361) | def media_viewer():
function live_direct_control (line 1376) | def live_direct_control():
function dc_set_Sharpness (line 1389) | def dc_set_Sharpness():
function dc_set_Contrast (line 1411) | def dc_set_Contrast():
function dc_set_Saturation (line 1433) | def dc_set_Saturation():
function dc_set_Brightness (line 1455) | def dc_set_Brightness():
function dc_set_exposureTimeSec (line 1477) | def dc_set_exposureTimeSec():
function dc_set_exposureValue (line 1500) | def dc_set_exposureValue():
function dc_set_AnalogueGain (line 1522) | def dc_set_AnalogueGain():
function dc_set_ColourGainRed (line 1544) | def dc_set_ColourGainRed():
function dc_set_ColourGainBlue (line 1566) | def dc_set_ColourGainBlue():
function dc_set_FocalDistance (line 1588) | def dc_set_FocalDistance():
function dc_set_ZoomFactor (line 1608) | def dc_set_ZoomFactor():
function live_do_action (line 1673) | def live_do_action(row:None, col=None):
function live_execute (line 1704) | def live_execute(row:None, col=None):
FILE: raspiCamSrv/images.py
function getFileList (line 19) | def getFileList() -> list:
function main (line 90) | def main():
function control (line 121) | def control():
function today (line 152) | def today():
function all (line 178) | def all():
function select_all (line 203) | def select_all():
function deselect_all (line 220) | def deselect_all():
function select (line 237) | def select():
function delete_selected (line 258) | def delete_selected():
function deleteFile (line 309) | def deleteFile(fp: str, cntOK, cntErr):
function download_selected (line 323) | def download_selected():
function media_viewer (line 415) | def media_viewer():
FILE: raspiCamSrv/info.py
function main (line 17) | def main():
FILE: raspiCamSrv/motionAlgoIB.py
class MotionDetectAlgoIB (line 22) | class MotionDetectAlgoIB():
method __init__ (line 25) | def __init__(self) -> None:
method frame1 (line 57) | def frame1(self):
method frame1 (line 61) | def frame1(self, value):
method frame2 (line 65) | def frame2(self):
method frame2 (line 69) | def frame2(self, value):
method frame2o (line 73) | def frame2o(self):
method frame2o (line 77) | def frame2o(self, value):
method frame1g (line 81) | def frame1g(self):
method frame1g (line 85) | def frame1g(self, value):
method frame2g (line 89) | def frame2g(self):
method frame2g (line 93) | def frame2g(self, value):
method detections (line 97) | def detections(self):
method detections (line 101) | def detections(self, value):
method test (line 105) | def test(self) -> bool:
method test (line 109) | def test(self, value:bool):
method rois (line 113) | def rois(self):
method rois (line 117) | def rois(self, value):
method ronis (line 121) | def ronis(self):
method ronis (line 125) | def ronis(self, value):
method currentRoI (line 129) | def currentRoI(self):
method currentRoI (line 133) | def currentRoI(self, value):
method currentRoiIdx (line 137) | def currentRoiIdx(self):
method currentRoiIdx (line 141) | def currentRoiIdx(self, value):
method testFrame1 (line 145) | def testFrame1(self):
method testFrame1 (line 149) | def testFrame1(self, value):
method testFrame2 (line 153) | def testFrame2(self):
method testFrame2 (line 157) | def testFrame2(self, value):
method testFrame3 (line 161) | def testFrame3(self):
method testFrame3 (line 165) | def testFrame3(self, value):
method testFrame4 (line 169) | def testFrame4(self):
method testFrame4 (line 173) | def testFrame4(self, value):
method tc (line 177) | def tc(self):
method tc (line 181) | def tc(self, value):
method recordFilename (line 185) | def recordFilename(self):
method recordFilename (line 189) | def recordFilename(self, value):
method recordIdx (line 193) | def recordIdx(self):
method recordIdx (line 197) | def recordIdx(self, value):
method frameSize (line 201) | def frameSize(self):
method frameSize (line 205) | def frameSize(self, value):
method framerate (line 209) | def framerate(self):
method framerate (line 213) | def framerate(self, value):
method recordingStart (line 217) | def recordingStart(self):
method recordingStart (line 221) | def recordingStart(self, value):
method recordingActive (line 225) | def recordingActive(self):
method recordingActive (line 229) | def recordingActive(self, value):
method video (line 233) | def video(self):
method video (line 237) | def video(self, value):
method videoWithRoi (line 241) | def videoWithRoi(self):
method videoWithRoi (line 245) | def videoWithRoi(self, value):
method startRecordMotion (line 248) | def startRecordMotion(self, fnRaw, includeRoI: bool = False) -> str:
method stopRecordMotion (line 279) | def stopRecordMotion(self):
method recordMotion (line 289) | def recordMotion(self):
method _frameToStream (line 334) | def _frameToStream(self, frame):
method _draw_bboxes (line 343) | def _draw_bboxes(self):
method _get_contour_detections (line 357) | def _get_contour_detections(self, mask, thresh=400):
method _non_max_suppression (line 380) | def _non_max_suppression(self, boxes, scores, threshold=1e-1):
method _remove_contained_bboxes (line 414) | def _remove_contained_bboxes(self, boxes):
class MotionDetectFrameDiff (line 437) | class MotionDetectFrameDiff(MotionDetectAlgoIB):
method __init__ (line 440) | def __init__(self) -> None:
method bbox_threshold (line 456) | def bbox_threshold(self):
method bbox_threshold (line 460) | def bbox_threshold(self, value):
method nms_threshold (line 464) | def nms_threshold(self):
method nms_threshold (line 468) | def nms_threshold(self, value):
method detectMotion (line 471) | def detectMotion(self, frame2, frame1, camInfo: str, rois: list, ronis...
method _get_detections (line 569) | def _get_detections(self, frame1, frame2, bbox_thresh=400, nms_thresh=...
method _get_mask (line 608) | def _get_mask(self, frame1, frame2, kernel=np.array((9,9), dtype=np.ui...
class MotionDetectOpticalFlow (line 645) | class MotionDetectOpticalFlow(MotionDetectAlgoIB):
method __init__ (line 648) | def __init__(self) -> None:
method detectMotion (line 664) | def detectMotion(self, frame2, frame1, camInfo: str, rois: list, ronis...
method _get_detections (line 769) | def _get_detections(self, frame1, frame2, motion_thresh=1, bbox_thresh...
method _compute_flow (line 824) | def _compute_flow(self, frame1, frame2):
method _get_flow_viz (line 846) | def _get_flow_viz(self, flow):
method _get_motion_mask (line 859) | def _get_motion_mask(self, flow_mag, motion_thresh=1, kernel=np.ones((...
method _get_contour_detections_2 (line 876) | def _get_contour_detections_2(self, mask, ang, angle_thresh=2, thresh=...
class MotionDetectBgSubtract (line 908) | class MotionDetectBgSubtract(MotionDetectAlgoIB):
method __init__ (line 911) | def __init__(self) -> None:
method backSubModel (line 940) | def backSubModel(self):
method backSubModel (line 944) | def backSubModel(self, value):
method detectMotion (line 977) | def detectMotion(self, frame2, frame1, camInfo: str, rois: list, ronis...
method _get_detections (line 1075) | def _get_detections(self, backSub, frame, bbox_thresh=100, nms_thresh=...
method _get_motion_mask (line 1131) | def _get_motion_mask(self, fg_mask, min_thresh=0, kernel=np.array((9,9...
FILE: raspiCamSrv/motionDetector.py
class MotionEvent (line 18) | class MotionEvent(object):
method __init__ (line 22) | def __init__(self):
method wait (line 26) | def wait(self):
method set (line 41) | def set(self):
method clear (line 66) | def clear(self):
class MotionDetector (line 73) | class MotionDetector():
method __new__ (line 107) | def __new__(cls):
method setAlgorithm (line 131) | def setAlgorithm(cls) -> bool:
method get_testFrame1 (line 160) | def get_testFrame1(self):
method get_testFrame2 (line 168) | def get_testFrame2(self):
method get_testFrame3 (line 176) | def get_testFrame3(self):
method get_testFrame4 (line 184) | def get_testFrame4(self):
method prepareRoIs (line 193) | def prepareRoIs(cls):
method _motionDetected (line 297) | def _motionDetected(cls, fCur, fPrv) -> tuple:
method _motionAlgo_MeanSquare (line 317) | def _motionAlgo_MeanSquare(fCur, fPrv, camInfo: str, rois: list, ronis...
method _doAction (line 367) | def _doAction(cls, trigger: str):
method savePhotoWithRois (line 546) | def savePhotoWithRois(frame, fp, rois: list, ronis: list, roiDetected:...
method _initNotificationMessage (line 585) | def _initNotificationMessage(logTS, trigger) -> EmailMessage:
method _attachToNotification (line 605) | def _attachToNotification(msg, fn):
method _sendNotificationThread (line 623) | def _sendNotificationThread(cls):
method _sendNotification (line 653) | def _sendNotification(cls):
method _cleanupEvent (line 666) | def _cleanupEvent(cls):
method _stopAction (line 685) | def _stopAction(cls, force = False):
method _isActive (line 756) | def _isActive() -> bool:
method _motionThread (line 785) | def _motionThread(cls):
method startMotionDetection (line 873) | def startMotionDetection(cls):
method stopMotionDetection (line 925) | def stopMotionDetection(cls):
FILE: raspiCamSrv/photoseries.py
function main (line 29) | def main():
function new_series (line 47) | def new_series():
function select_series (line 124) | def select_series():
function start_series (line 149) | def start_series():
function pause_series (line 238) | def pause_series():
function finish_series (line 271) | def finish_series():
function continue_series (line 306) | def continue_series():
function remove_series (line 393) | def remove_series():
function download_series (line 416) | def download_series():
function series_properties (line 460) | def series_properties():
function attach_camera_cfg (line 552) | def attach_camera_cfg():
function activate_camera_cfg (line 580) | def activate_camera_cfg():
function show_preview (line 613) | def show_preview():
function hide_preview (line 631) | def hide_preview():
function calcSunControlledSeries (line 647) | def calcSunControlledSeries(sr: Series, sun: Sun):
function calcSunAzimuthSeries (line 717) | def calcSunAzimuthSeries(sr: Series, sun: Sun):
function tlseries_properties (line 762) | def tlseries_properties():
function calcExpSeries (line 1005) | def calcExpSeries(start, stop, int):
function expseries_properties (line 1030) | def expseries_properties():
function calcFocusSeries (line 1112) | def calcFocusSeries(start, stop, intv):
function focusstack_properties (line 1130) | def focusstack_properties():
function media_viewer (line 1201) | def media_viewer():
FILE: raspiCamSrv/photoseriesCfg.py
class Series (line 18) | class Series():
method __init__ (line 22) | def __init__(self):
method name (line 92) | def name(self) -> str:
method name (line 96) | def name(self, value: str):
method status (line 100) | def status(self) -> str:
method status (line 104) | def status(self, value: str):
method nextActions (line 108) | def nextActions(self) -> list:
method nextStatus (line 126) | def nextStatus(self, action: str) -> str:
method path (line 147) | def path(self) -> str:
method path (line 151) | def path(self, value: str):
method histogramPath (line 155) | def histogramPath(self) -> str:
method start (line 159) | def start(self) -> datetime:
method start (line 163) | def start(self, value: datetime):
method startIso (line 171) | def startIso(self) -> str:
method started (line 175) | def started(self) -> datetime:
method started (line 179) | def started(self, value: datetime):
method startedIso (line 187) | def startedIso(self) -> str:
method end (line 194) | def end(self) -> datetime:
method end (line 198) | def end(self, value: datetime):
method endIso (line 206) | def endIso(self) -> str:
method ended (line 210) | def ended(self) -> datetime:
method ended (line 214) | def ended(self, value: datetime):
method endedIso (line 222) | def endedIso(self) -> str:
method downloaded (line 229) | def downloaded(self) -> datetime:
method downloaded (line 233) | def downloaded(self, value: datetime):
method downloadedIso (line 241) | def downloadedIso(self) -> str:
method interval (line 248) | def interval(self) -> float:
method interval (line 252) | def interval(self, value: float):
method onDialMarks (line 256) | def onDialMarks(self) -> bool:
method onDialMarks (line 260) | def onDialMarks(self, value: bool):
method nrShots (line 264) | def nrShots(self) -> int:
method nrShots (line 268) | def nrShots(self, value: int):
method curShots (line 272) | def curShots(self) -> int:
method curShots (line 276) | def curShots(self, value: int):
method type (line 280) | def type(self) -> str:
method type (line 284) | def type(self, value: str):
method continueOnServerStart (line 288) | def continueOnServerStart(self) -> bool:
method continueOnServerStart (line 292) | def continueOnServerStart(self, value: bool):
method showPreview (line 296) | def showPreview(self) -> bool:
method showPreview (line 300) | def showPreview(self, value: bool):
method logFileName (line 304) | def logFileName(self) -> str:
method logFileRelPath (line 308) | def logFileRelPath(self) -> str:
method logFile (line 312) | def logFile(self) -> str:
method logFile (line 316) | def logFile(self, value: str):
method cfgFileName (line 320) | def cfgFileName(self) -> str:
method cfgFileRelPath (line 324) | def cfgFileRelPath(self) -> str:
method cfgFile (line 328) | def cfgFile(self) -> str:
method cfgFile (line 332) | def cfgFile(self, value: str):
method camFileName (line 336) | def camFileName(self) -> str:
method camFileRelPath (line 340) | def camFileRelPath(self) -> str:
method camFile (line 344) | def camFile(self) -> str:
method camFile (line 348) | def camFile(self, value: str):
method isExposureSeries (line 352) | def isExposureSeries(self) -> bool:
method isExposureSeries (line 356) | def isExposureSeries(self, value: bool):
method isExpExpTimeFix (line 360) | def isExpExpTimeFix(self) -> bool:
method isExpExpTimeFix (line 364) | def isExpExpTimeFix(self, value: bool):
method isExpGainFix (line 368) | def isExpGainFix(self) -> bool:
method isExpGainFix (line 372) | def isExpGainFix(self, value: bool):
method expTimeStart (line 376) | def expTimeStart(self) -> int:
method expTimeStart (line 380) | def expTimeStart(self, value: int):
method expTimeStop (line 384) | def expTimeStop(self) -> int:
method expTimeStop (line 388) | def expTimeStop(self, value: int):
method expTimeStep (line 392) | def expTimeStep(self) -> int:
method expTimeStep (line 396) | def expTimeStep(self, value: int):
method expGainStart (line 410) | def expGainStart(self) -> float:
method expGainStart (line 414) | def expGainStart(self, value: float):
method expGainStop (line 418) | def expGainStop(self) -> float:
method expGainStop (line 422) | def expGainStop(self, value: float):
method expGainStep (line 426) | def expGainStep(self) -> int:
method expGainStep (line 430) | def expGainStep(self, value: int):
method isFocusStackingSeries (line 444) | def isFocusStackingSeries(self) -> bool:
method isFocusStackingSeries (line 448) | def isFocusStackingSeries(self, value: bool):
method focalDistStart (line 452) | def focalDistStart(self) -> float:
method focalDistStart (line 456) | def focalDistStart(self, value: float):
method focalDistStop (line 460) | def focalDistStop(self) -> float:
method focalDistStop (line 464) | def focalDistStop(self, value: float):
method focalDistStep (line 468) | def focalDistStep(self) -> float:
method focalDistStep (line 472) | def focalDistStep(self, value: float):
method isSunControlledSeries (line 476) | def isSunControlledSeries(self) -> bool:
method isSunControlledSeries (line 480) | def isSunControlledSeries(self, value: bool):
method sunCtrlMode (line 488) | def sunCtrlMode(self) -> int:
method sunCtrlMode (line 492) | def sunCtrlMode(self, value: int):
method sunCtrlPeriods (line 504) | def sunCtrlPeriods(self) -> int:
method sunCtrlPeriods (line 508) | def sunCtrlPeriods(self, value: int):
method sunrise (line 512) | def sunrise(self) -> datetime:
method sunrise (line 516) | def sunrise(self, value: datetime):
method sunriseIso (line 524) | def sunriseIso(self) -> str:
method sunset (line 528) | def sunset(self) -> datetime:
method sunset (line 532) | def sunset(self, value: datetime):
method sunsetIso (line 540) | def sunsetIso(self) -> str:
method sunCtrlStart1Trg (line 544) | def sunCtrlStart1Trg(self) -> int:
method sunCtrlStart1Trg (line 548) | def sunCtrlStart1Trg(self, value: int):
method sunCtrlStart1Shft (line 552) | def sunCtrlStart1Shft(self) -> int:
method sunCtrlStart1Shft (line 556) | def sunCtrlStart1Shft(self, value: int):
method sunCtrlStart1 (line 560) | def sunCtrlStart1(self) -> datetime:
method sunCtrlStart1 (line 564) | def sunCtrlStart1(self, value: datetime):
method sunCtrlStart1Iso (line 572) | def sunCtrlStart1Iso(self) -> str:
method sunCtrlEnd1Trg (line 576) | def sunCtrlEnd1Trg(self) -> int:
method sunCtrlEnd1Trg (line 580) | def sunCtrlEnd1Trg(self, value: int):
method sunCtrlEnd1Shft (line 584) | def sunCtrlEnd1Shft(self) -> int:
method sunCtrlEnd1Shft (line 588) | def sunCtrlEnd1Shft(self, value: int):
method sunCtrlEnd1 (line 592) | def sunCtrlEnd1(self) -> datetime:
method sunCtrlEnd1 (line 596) | def sunCtrlEnd1(self, value: datetime):
method sunCtrlEnd1Iso (line 604) | def sunCtrlEnd1Iso(self) -> str:
method sunCtrlStart2Trg (line 608) | def sunCtrlStart2Trg(self) -> int:
method sunCtrlStart2Trg (line 612) | def sunCtrlStart2Trg(self, value: int):
method sunCtrlStart2Shft (line 616) | def sunCtrlStart2Shft(self) -> int:
method sunCtrlStart2Shft (line 620) | def sunCtrlStart2Shft(self, value: int):
method sunCtrlStart2 (line 624) | def sunCtrlStart2(self) -> datetime:
method sunCtrlStart2 (line 628) | def sunCtrlStart2(self, value: datetime):
method sunCtrlStart2Iso (line 636) | def sunCtrlStart2Iso(self) -> str:
method sunCtrlEnd2Trg (line 640) | def sunCtrlEnd2Trg(self) -> int:
method sunCtrlEnd2Trg (line 644) | def sunCtrlEnd2Trg(self, value: int):
method sunCtrlEnd2Shft (line 648) | def sunCtrlEnd2Shft(self) -> int:
method sunCtrlEnd2Shft (line 652) | def sunCtrlEnd2Shft(self, value: int):
method sunCtrlEnd2 (line 656) | def sunCtrlEnd2(self) -> datetime:
method sunCtrlEnd2 (line 660) | def sunCtrlEnd2(self, value: datetime):
method sunCtrlEnd2Iso (line 668) | def sunCtrlEnd2Iso(self) -> str:
method cameraConfig (line 672) | def cameraConfig(self) -> CameraConfig:
method cameraConfig (line 676) | def cameraConfig(self, value: CameraConfig):
method cameraControls (line 680) | def cameraControls(self) -> CameraControls:
method cameraControls (line 684) | def cameraControls(self, value: CameraControls):
method sunAzimuthTime (line 688) | def sunAzimuthTime(self) -> datetime:
method sunAzimuthTime (line 692) | def sunAzimuthTime(self, value: datetime):
method sunAzimuthTimeIso (line 700) | def sunAzimuthTimeIso(self) -> str:
method sunAzimuth (line 707) | def sunAzimuth(self) -> float:
method sunAzimuth (line 711) | def sunAzimuth(self, value: float):
method sunElevation (line 715) | def sunElevation(self) -> float:
method sunElevation (line 719) | def sunElevation(self, value: float):
method sunAzimuth1 (line 723) | def sunAzimuth1(self) -> float:
method sunAzimuth1 (line 727) | def sunAzimuth1(self, value: float):
method sunAzimuth2 (line 731) | def sunAzimuth2(self) -> float:
method sunAzimuth2 (line 735) | def sunAzimuth2(self, value: float):
method sunAzimuth3 (line 739) | def sunAzimuth3(self) -> float:
method sunAzimuth3 (line 743) | def sunAzimuth3(self, value: float):
method sunAzimuth4 (line 747) | def sunAzimuth4(self) -> float:
method sunAzimuth4 (line 751) | def sunAzimuth4(self, value: float):
method sunAzimuth1Time (line 755) | def sunAzimuth1Time(self) -> datetime:
method sunAzimuth1Time (line 759) | def sunAzimuth1Time(self, value: datetime):
method sunAzimuth1TimeIso (line 767) | def sunAzimuth1TimeIso(self) -> str:
method sunAzimuth2Time (line 774) | def sunAzimuth2Time(self) -> datetime:
method sunAzimuth2Time (line 778) | def sunAzimuth2Time(self, value: datetime):
method sunAzimuth2TimeIso (line 786) | def sunAzimuth2TimeIso(self) -> str:
method sunAzimuth3Time (line 793) | def sunAzimuth3Time(self) -> datetime:
method sunAzimuth3Time (line 797) | def sunAzimuth3Time(self, value: datetime):
method sunAzimuth3TimeIso (line 805) | def sunAzimuth3TimeIso(self) -> str:
method sunAzimuth4Time (line 812) | def sunAzimuth4Time(self) -> datetime:
method sunAzimuth4Time (line 816) | def sunAzimuth4Time(self, value: datetime):
method sunAzimuth4TimeIso (line 824) | def sunAzimuth4TimeIso(self) -> str:
method sunAzimuths (line 831) | def sunAzimuths(self) -> list:
method sunAzimuthTimes (line 844) | def sunAzimuthTimes(self) -> list:
method metaData (line 857) | def metaData(self) -> dict:
method metaData (line 861) | def metaData(self, value: dict):
method error (line 865) | def error(self) -> str:
method error (line 869) | def error(self, value: str):
method error2 (line 876) | def error2(self) -> str:
method error2 (line 880) | def error2(self, value: str):
method errorSource (line 884) | def errorSource(self) -> str:
method errorSource (line 888) | def errorSource(self, value: str):
method resetSunCtrlData (line 891) | def resetSunCtrlData(self):
method resetSunSunriseData (line 921) | def resetSunSunriseData(self):
method resetSunAzimuthata (line 939) | def resetSunAzimuthata(self):
method nextPhoto (line 953) | def nextPhoto(self) -> tuple[int, str, dict]:
method nextTimeOnlyAsStr (line 993) | def nextTimeOnlyAsStr(self) -> str:
method nextTimeIso (line 999) | def nextTimeIso(self) -> str:
method calcSunCtrlData (line 1005) | def calcSunCtrlData(self, dat: str):
method nextTimeSunCtrl (line 1078) | def nextTimeSunCtrl(self) -> datetime:
method nextDialMark (line 1193) | def nextDialMark(self, t:datetime) -> datetime:
method nextTime (line 1235) | def nextTime(self, lastTime=None, test=False) -> datetime:
method getPreviewList (line 1284) | def getPreviewList(self):
method _readLog (line 1305) | def _readLog(self, file: str) -> dict:
method _getParamsFromLog (line 1315) | def _getParamsFromLog(self, log: dict, name: str) -> dict:
method getPreviewListHistDetail (line 1344) | def getPreviewListHistDetail(self):
method logCamCfgCtrlClose (line 1385) | def logCamCfgCtrlClose(self):
method logCamCfgCtrl (line 1392) | def logCamCfgCtrl(self, name: str, cfg: dict, ctrl: dict):
method logPhoto (line 1416) | def logPhoto(self, name: str, ptime: datetime, metadata: dict, seriesM...
method persist (line 1502) | def persist(self):
method toJson (line 1515) | def toJson(self):
method checkPhotos (line 1520) | def checkPhotos(cls, path: str, name: str):
method initFromDict (line 1548) | def initFromDict(cls, dict:dict):
class PhotoSeriesCfg (line 1589) | class PhotoSeriesCfg():
method __new__ (line 1591) | def __new__(cls):
method rootPath (line 1600) | def rootPath(self) -> str:
method rootPath (line 1604) | def rootPath(self, value: str):
method tlSeries (line 1608) | def tlSeries(self) -> list:
method tlSeries (line 1612) | def tlSeries(self, value: list):
method seriesNames (line 1616) | def seriesNames(self) -> list:
method curSeries (line 1623) | def curSeries(self) -> Series:
method curSeries (line 1627) | def curSeries(self, value: Series):
method hasCurSeries (line 1631) | def hasCurSeries(self) -> bool:
method appendSeries (line 1634) | def appendSeries(self, s:Series):
method nameExists (line 1637) | def nameExists(self, name: str) -> bool:
method _initSeriesFromCfg (line 1645) | def _initSeriesFromCfg(self, spath: str, name: str) -> Series:
method initFromTlFolder (line 1666) | def initFromTlFolder(self):
method removeCurrentSeries (line 1692) | def removeCurrentSeries(self):
FILE: raspiCamSrv/schema.sql
type user (line 6) | CREATE TABLE IF NOT EXISTS user (
type config (line 14) | CREATE TABLE IF NOT EXISTS config (
type events (line 20) | CREATE TABLE IF NOT EXISTS events (
type eventactions (line 32) | CREATE TABLE IF NOT EXISTS eventactions (
type events_date_idx (line 45) | CREATE INDEX IF NOT EXISTS events_date_idx ON events(
type eventactions_type_idx (line 50) | CREATE INDEX IF NOT EXISTS eventactions_type_idx ON eventactions(
FILE: raspiCamSrv/settings.py
function main (line 38) | def main():
function serverconfig (line 59) | def serverconfig():
function reloadCameraSystem (line 200) | def reloadCameraSystem():
function reloadCameras (line 227) | def reloadCameras():
function resetServer (line 286) | def resetServer():
function configBackup (line 411) | def configBackup():
function copyDir (line 499) | def copyDir(src: str, dst: str):
function restoreDir (line 526) | def restoreDir(src: str, dst: str):
function getBackupsList (line 542) | def getBackupsList() -> list:
function configRestore (line 563) | def configRestore():
function configRemove (line 647) | def configRemove():
function serverRestart (line 691) | def serverRestart():
function remove_users (line 746) | def remove_users():
function register_user (line 814) | def register_user():
function store_config (line 839) | def store_config():
function load_config (line 873) | def load_config():
function getLoadConfigOnStart (line 975) | def getLoadConfigOnStart(cfgPath: str) -> bool:
function setLoadConfigOnStart (line 986) | def setLoadConfigOnStart(cfgPath: str, value: bool):
function loadConfigOnStart (line 1000) | def loadConfigOnStart():
function api_config (line 1027) | def api_config():
function generate_token (line 1089) | def generate_token():
function vbutton_dimensions (line 1114) | def vbutton_dimensions():
function vbutton_settings (line 1174) | def vbutton_settings():
function abutton_dimensions (line 1219) | def abutton_dimensions():
function abutton_settings (line 1278) | def abutton_settings():
function lbutton_dimensions (line 1323) | def lbutton_dimensions():
function lbutton_settings (line 1382) | def lbutton_settings():
function new_device (line 1435) | def new_device():
function select_device (line 1494) | def select_device():
function checkDeviceDeletion (line 1530) | def checkDeviceDeletion(deviceId: str, tc:TriggerConfig) -> str:
function delete_device (line 1563) | def delete_device():
function parseTuple (line 1615) | def parseTuple(stuple: str) -> tuple[str, tuple]:
function castType (line 1638) | def castType(val:str, tpl:object) ->tuple[str, object]:
function parseColorTuple (line 1693) | def parseColorTuple(stuple: str) -> tuple:
function device_properties (line 1721) | def device_properties():
function storeResult (line 1817) | def storeResult(result:dict, test:str, testResult:str) -> dict:
function test_device (line 1841) | def test_device():
function calibrate_device (line 1956) | def calibrate_device():
function calibrate_fbwd (line 2007) | def calibrate_fbwd():
function calibrate_bwd (line 2080) | def calibrate_bwd():
function docalibrate (line 2153) | def docalibrate():
function calibrate_fwd (line 2256) | def calibrate_fwd():
function calibrate_ffwd (line 2329) | def calibrate_ffwd():
function versionCheckEnabled (line 2402) | def versionCheckEnabled():
function serverUpdate (line 2432) | def serverUpdate():
function updateIgnoreLatest (line 2479) | def updateIgnoreLatest():
function versionCheckIntervalHours (line 2506) | def versionCheckIntervalHours():
function versionCheckNow (line 2534) | def versionCheckNow():
FILE: raspiCamSrv/stereoCam.py
class StereoEvent (line 15) | class StereoEvent(object):
method __init__ (line 19) | def __init__(self):
method wait (line 23) | def wait(self):
method set (line 38) | def set(self):
method clear (line 63) | def clear(self):
class StereoCam (line 70) | class StereoCam():
method __new__ (line 77) | def __new__(cls):
method get_stereoFrame (line 107) | def get_stereoFrame(self):
method _frameToStream (line 115) | def _frameToStream(self, frame):
method _stereoBM (line 125) | def _stereoBM(self, stc:StereoConfig, left, right):
method _stereoSGBM (line 147) | def _stereoSGBM(self, stc: StereoConfig, left, right):
method _3DVideo (line 178) | def _3DVideo(self, stc: StereoConfig, left, right):
method _processStereoImage (line 209) | def _processStereoImage(self, left, right):
method _stereoThread (line 270) | def _stereoThread(self):
method startStereoCam (line 316) | def startStereoCam(self):
method stopStereoCam (line 356) | def stopStereoCam(self):
method _takeCalibPhotoThread (line 386) | def _takeCalibPhotoThread(self):
method takeCalibrationPhotos (line 527) | def takeCalibrationPhotos(self, camL: str, camR: str):
method stoptakeCalibrationPhotos (line 555) | def stoptakeCalibrationPhotos(self):
method calibrateCameras (line 583) | def calibrateCameras(self, camL: str, camR: str):
method startRecordStereo (line 738) | def startRecordStereo(self, fnRaw) -> str:
method stopRecordStereo (line 783) | def stopRecordStereo(self):
method _recordStereo (line 796) | def _recordStereo(self):
FILE: raspiCamSrv/sun.py
class Sun (line 23) | class Sun():
method __init__ (line 24) | def __init__(self, latitude: float, longitude: float, elevation: float...
method _ts2human (line 39) | def _ts2human(self, ts: float, debugtz: tzinfo) -> str:
method _j2ts (line 43) | def _j2ts(self, j: float) -> float:
method _ts2j (line 47) | def _ts2j(self, ts: float) -> float:
method _j2human (line 51) | def _j2human(self, j: float, debugtz: tzinfo) -> str:
method _deg2human (line 56) | def _deg2human(self, deg: float) -> str:
method _calc (line 64) | def _calc(
method sunTimezone (line 145) | def sunTimezone(self) -> str:
method sunrise_sunset (line 153) | def sunrise_sunset(self, time: datetime) -> tuple[datetime, datetime]:
method _day_of_year (line 174) | def _day_of_year(self, dt: datetime) -> int:
method _equation_of_time (line 178) | def _equation_of_time(self, N: int) -> float:
method _declination (line 187) | def _declination(self, N: int) -> float:
method solar_position (line 191) | def solar_position(
method _get_az (line 275) | def _get_az(self, base: datetime, minutes_from_midnight: float) -> float:
method _az_diff (line 280) | def _az_diff(self, base: datetime, minutes: float, target_azimuth: flo...
method _bisect (line 290) | def _bisect(self, base: datetime, t_lo: float, t_hi: float, target_azi...
method find_times_for_azimuth (line 307) | def find_times_for_azimuth(
FILE: raspiCamSrv/trigger.py
function trigger (line 25) | def trigger():
function trg_gen (line 49) | def trg_gen(camera):
function trg_live_view_feed (line 61) | def trg_live_view_feed():
function trgcontrol (line 72) | def trgcontrol():
function motion (line 146) | def motion():
function test_motion_detection (line 214) | def test_motion_detection():
function stop_test_motion_detection (line 264) | def stop_test_motion_detection():
function test_frame1_feed (line 285) | def test_frame1_feed():
function gen_testFrame1 (line 292) | def gen_testFrame1(motionDetector):
function test_frame2_feed (line 304) | def test_frame2_feed():
function gen_testFrame2 (line 311) | def gen_testFrame2(motionDetector):
function test_frame3_feed (line 323) | def test_frame3_feed():
function gen_testFrame3 (line 330) | def gen_testFrame3(motionDetector):
function test_frame4_feed (line 342) | def test_frame4_feed():
function gen_testFrame4 (line 349) | def gen_testFrame4(motionDetector):
function action (line 361) | def action():
function notify (line 398) | def notify():
function start_triggered_capture (line 492) | def start_triggered_capture():
function stop_triggered_capture (line 540) | def stop_triggered_capture():
function prev_month (line 565) | def prev_month():
function prev_day (line 581) | def prev_day():
function set_date (line 597) | def set_date():
function next_day (line 614) | def next_day():
function next_month (line 630) | def next_month():
function prev_hor (line 646) | def prev_hor():
function prev_quarter (line 661) | def prev_quarter():
function set_time (line 676) | def set_time():
function next_quarter (line 692) | def next_quarter():
function next_hour (line 707) | def next_hour():
function events_now (line 722) | def events_now():
function event_include_video (line 737) | def event_include_video():
function event_include_photo (line 757) | def event_include_photo():
function do_refresh (line 777) | def do_refresh():
function prev_cal_month (line 793) | def prev_cal_month():
function set_cal_month (line 806) | def set_cal_month():
function next_cal_month (line 822) | def next_cal_month():
function calendar_now (line 837) | def calendar_now():
function do_refresh_calendar (line 852) | def do_refresh_calendar():
function calendar_goto (line 868) | def calendar_goto():
function do_cleanup (line 889) | def do_cleanup():
function do_download_log (line 914) | def do_download_log():
function new_trigger (line 939) | def new_trigger():
function countEvent (line 1044) | def countEvent(source:str, device:str, event:str, tc:TriggerConfig) -> int:
function checkTrigger (line 1064) | def checkTrigger(tc:TriggerConfig) -> bool:
function trigger_activation (line 1082) | def trigger_activation():
function parseTuple (line 1117) | def parseTuple(stuple: str) -> tuple[str, tuple]:
function castType (line 1140) | def castType(val:str, tpl:object) ->tuple[str, object]:
function new_action (line 1262) | def new_action():
function checkActionUsage (line 1382) | def checkActionUsage(actionId:str, actionUsage: list, sc:ServerConfig) -...
function action_activation (line 1402) | def action_activation():
function trigger_action (line 1462) | def trigger_action():
function media_viewer (line 1519) | def media_viewer():
FILE: raspiCamSrv/triggerHandler.py
class TriggerHandler (line 22) | class TriggerHandler():
method __new__ (line 38) | def __new__(cls):
method _isActive (line 46) | def _isActive() -> bool:
method _findDeviceInRegistry (line 78) | def _findDeviceInRegistry(cls, source: str, deviceId: str, sc:ServerCo...
method _bouncing (line 191) | def _bouncing(cls, trg:Trigger, sc:ServerConfig) -> bool:
method _doGpioAction (line 235) | def _doGpioAction(cls, action:Action, trigger:Trigger=None, eventId:UU...
method _videoTimer (line 383) | def _videoTimer(cls, action:Action, isEvent:bool, sc:ServerConfig, tc:...
method _doRecordVideo (line 414) | def _doRecordVideo(cls, action:Action, isEvent:bool, sc:ServerConfig, ...
method _doStartVideo (line 443) | def _doStartVideo(cls, action:Action, isEvent:bool, sc:ServerConfig, t...
method _doStopVideo (line 530) | def _doStopVideo(cls, action:Action, isEvent:bool, sc:ServerConfig, tc...
method _doTakePhoto (line 583) | def _doTakePhoto(cls, action:Action, isEvent:bool, sc:ServerConfig, tc...
method _doCameraAction (line 679) | def _doCameraAction(cls, action:Action, trigger:Trigger=None, eventId:...
method _initNotificationMessage (line 784) | def _initNotificationMessage(cls, eventId:UUID) -> EmailMessage:
method _attachMedia (line 896) | def _attachMedia(cls, mail:EmailMessage, eventId:UUID) -> bool:
method _doSMTPaAction (line 940) | def _doSMTPaAction(cls, action:Action, trigger:Trigger=None, eventId:U...
method doAction (line 1020) | def doAction(cls, actionId: str) ->str:
method _getEventContext (line 1068) | def _getEventContext(cls, eventId:UUID) -> dict:
method _getActionContext (line 1085) | def _getActionContext(cls, eventId:UUID, actionId:str) -> dict:
method _finalizeEvent (line 1107) | def _finalizeEvent(cls, eventId:UUID):
method _waitForCompletion (line 1127) | def _waitForCompletion(cls, eventId:UUID):
method _logEvent (line 1167) | def _logEvent(cls, db:Connection, logType:str, tc:TriggerConfig, event...
method _actionDispatcher (line 1318) | def _actionDispatcher(cls, gpioDevice, trigger:Trigger):
method _registerGpioTrigger (line 1442) | def _registerGpioTrigger(cls, sc:ServerConfig, tc:TriggerConfig, trg:T...
method _registerCameraTrigger (line 1498) | def _registerCameraTrigger(cls, sc:ServerConfig, tc:TriggerConfig, trg...
method _registerMotionDetectorTrigger (line 1534) | def _registerMotionDetectorTrigger(cls, sc:ServerConfig, tc:TriggerCon...
method _registerTriggers (line 1572) | def _registerTriggers(cls):
method _unregisterGpioTrigger (line 1596) | def _unregisterGpioTrigger(cls, sc:ServerConfig, tc:TriggerConfig, trg...
method _unregisterCameraTrigger (line 1628) | def _unregisterCameraTrigger(cls, sc:ServerConfig, tc:TriggerConfig, t...
method _unregisterMotionDetectorTrigger (line 1659) | def _unregisterMotionDetectorTrigger(cls, sc:ServerConfig, tc:TriggerC...
method _unregisterTriggers (line 1690) | def _unregisterTriggers(cls):
method _closeGpioDevices (line 1713) | def _closeGpioDevices(cls):
method _triggerThread (line 1745) | def _triggerThread(cls):
method start (line 1779) | def start(cls) -> bool:
method stop (line 1804) | def stop(cls) -> bool:
FILE: raspiCamSrv/webcam.py
function webcam (line 39) | def webcam():
function active_camera_photo_cfg (line 82) | def active_camera_photo_cfg():
function second_camera_photo_cfg (line 110) | def second_camera_photo_cfg():
function store_streaming_config (line 138) | def store_streaming_config():
function sync_settings (line 183) | def sync_settings():
function switch_cameras (line 231) | def switch_cameras():
function change_active_camera (line 331) | def change_active_camera():
function change_second_camera (line 413) | def change_second_camera():
function photo_feed (line 478) | def photo_feed():
function photo_feed_hr (line 486) | def photo_feed_hr():
function photo_feed2 (line 494) | def photo_feed2():
function photo_feed2_hr (line 502) | def photo_feed2_hr():
function cam_take_photo (line 510) | def cam_take_photo():
function cam_take_raw_photo (line 557) | def cam_take_raw_photo():
function cam_record_video (line 603) | def cam_record_video():
function cam_stop_recording (line 659) | def cam_stop_recording():
function take_photo2 (line 693) | def take_photo2():
function cam_take_raw_photo2 (line 732) | def cam_take_raw_photo2():
function cam_record_video2 (line 774) | def cam_record_video2():
function cam_stop_recording2 (line 823) | def cam_stop_recording2():
function take_photo_both (line 856) | def take_photo_both():
function cam_take_raw_photo_both (line 904) | def cam_take_raw_photo_both():
function cam_record_video_both (line 963) | def cam_record_video_both():
function cam_stop_recording_both (line 1031) | def cam_stop_recording_both():
function start_stereo_cam (line 1079) | def start_stereo_cam():
function stop_stereo_cam (line 1117) | def stop_stereo_cam():
function stereo_cam_feed (line 1151) | def stereo_cam_feed():
function gen_stereoCamFrame (line 1161) | def gen_stereoCamFrame(stereoCam):
function stereo_feed (line 1174) | def stereo_feed():
function stereo_display (line 1192) | def stereo_display():
function stereo_config (line 1227) | def stereo_config():
function first_calib_photo (line 1391) | def first_calib_photo():
function prev_calib_photo (line 1407) | def prev_calib_photo():
function next_calib_photo (line 1423) | def next_calib_photo():
function last_calib_photo (line 1442) | def last_calib_photo():
function doRemoveCalibPhoto (line 1455) | def doRemoveCalibPhoto(sc: ServerConfig, ster: StereoConfig, idx: int) -...
function getStereoCameras (line 1500) | def getStereoCameras():
function remove_calib_photo (line 1515) | def remove_calib_photo():
function display_corners (line 1535) | def display_corners():
function calib_settings (line 1552) | def calib_settings():
function reset_calib_photos (line 1655) | def reset_calib_photos():
function start_take_calib_photos (line 1683) | def start_take_calib_photos():
function stop_take_calib_photos (line 1720) | def stop_take_calib_photos():
function doResetCalibration (line 1743) | def doResetCalibration(camL: str, camR: str, keepPhotos: bool = False):
function doCleanup (line 1779) | def doCleanup(sc: ServerConfig, ster: StereoConfig):
function doInitCalibration (line 1831) | def doInitCalibration(camL: str, camR: str):
function calibrate_cameras (line 1888) | def calibrate_cameras():
function start_record_stereo (line 1924) | def start_record_stereo():
function stop_record_stereo (line 1963) | def stop_record_stereo():
Condensed preview — 143 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,028K chars).
[
{
"path": ".dockerignore",
"chars": 324,
"preview": "**/__pycache__\n**/.env\n**/.git\n**/.venv\n**/.vscode\nconfig\n**/docs\n**/instance\n**/logs\n**/backups\nraspiCamSrv/static/conf"
},
{
"path": ".gitignore",
"chars": 3365,
"preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\ntests/\nuser_code/\nlogs/\noutput/\nbackups\nraspiC"
},
{
"path": ".vscode/launch.json",
"chars": 522,
"preview": "{\n // Verwendet IntelliSense zum Ermitteln möglicher Attribute.\n // Zeigen Sie auf vorhandene Attribute, um die zu"
},
{
"path": "Dockerfile",
"chars": 1336,
"preview": "# syntax=docker/dockerfile:1\nFROM dtcooper/raspberrypi-os:bookworm\n\nLABEL maintainer=\"signag\"\n\nRUN apt update && apt -y "
},
{
"path": "LICENSE",
"chars": 1063,
"preview": "MIT License\n\nCopyright (c) 2023 signag\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "README.md",
"chars": 1834,
"preview": "# raspiCamSrv V4.10.0\n\n**raspiCamSrv** is a Web server for Raspberry Pi systems providing an App for control and streami"
},
{
"path": "config/raspiCamSrv.service",
"chars": 457,
"preview": "[Unit]\nDescription=raspiCamSrv\nAfter=network.target\n\n[Service]\nExecStart=/home/<user>/prg/raspi-cam-srv/.venv/bin/python"
},
{
"path": "config/raspiCamSrv_gunicorn.service",
"chars": 534,
"preview": "[Unit]\nDescription=raspiCamSrv\nAfter=network.target\n\n[Service]\nExecStart=/home/<user>/prg/raspi-cam-srv/.venv/bin/gunico"
},
{
"path": "docker-compose.yml",
"chars": 627,
"preview": "name: raspi-cam-srv\nservices:\n raspi-cam-srv:\n container_name: raspi-cam-srv\n build: .\n image: signag/raspi-ca"
},
{
"path": "docs/API.md",
"chars": 1705,
"preview": "# raspiCamSrv API\n\n[](./UserGuide.md)\n\nThe **raspiCamSrv** API allows access to several RaspberryPi c"
},
{
"path": "docs/AiCameraSupport.md",
"chars": 54312,
"preview": "# raspiCamSrv AI Camera Support\n\n[](./UserGuide.md)\n\nThe [Raspberry Pi AI Camera](https://www.raspber"
},
{
"path": "docs/Authentication.md",
"chars": 2560,
"preview": "# raspiCamSrv Authorization\n\n[](./UserGuide.md)\n\nAccess to the raspiCamSrv server requires login with"
},
{
"path": "docs/Background Processes.md",
"chars": 2794,
"preview": "# raspiCamSrv Tasks and Background Processes\n\n[](./UserGuide.md)\n\nThe figure below gives an overview "
},
{
"path": "docs/Cam.md",
"chars": 1472,
"preview": "# Cam - Camera Usage\n\n[](./UserGuide.md)\n\n\n\nThis menu gives access to the"
},
{
"path": "docs/CamCalibration.md",
"chars": 3967,
"preview": "# Camera Calibration\n\n[](./Cam.md)\n\nThis dialog allows calibration of the [stereo camera system](./Ca"
},
{
"path": "docs/CamMulticam.md",
"chars": 7103,
"preview": "# Multi-Camera Control\n\n[](./Cam.md)\n\n**NOTE**: This dialog is only available for systems with two or"
},
{
"path": "docs/CamStereo.md",
"chars": 3983,
"preview": "# Stereo-Cam\n\n[](./Cam.md)\n\nThis dialog features [stereo camera](#stereo-camera) capabilities and can"
},
{
"path": "docs/CamWebcam.md",
"chars": 2713,
"preview": "# Web Cam Access\n\n[](./Cam.md)\n\n**raspiCamSrv** enables webcam functionalities with Raspberry Pi came"
},
{
"path": "docs/CameraControls.md",
"chars": 3392,
"preview": "# raspiCamSrv Camera Controls\n\n[](./LiveScreen.md)\n\n**NOTE**: The subsequent description is essential"
},
{
"path": "docs/CameraControls_AutoExposure.md",
"chars": 210,
"preview": "# Camera Controls / Auto-Exposure\n\n[](./CameraControls.md)\n\n\n\nT"
},
{
"path": "docs/CameraControls_Ctrl.md",
"chars": 566,
"preview": "# Camera Controls / Ctrl\n\n[](./CameraControls.md)\n\n\n\nThis tab shows functi"
},
{
"path": "docs/CameraControls_Exposure.md",
"chars": 163,
"preview": "# Camera Controls / Exposure\n\n[](./CameraControls.md)\n\n\n\nThis tab includ"
},
{
"path": "docs/CameraControls_Image.md",
"chars": 158,
"preview": "# Camera Controls / Image\n\n[](./CameraControls.md)\n\n\n\nThis tab includes parame"
},
{
"path": "docs/CameraControls_UsbCams.md",
"chars": 1608,
"preview": "# Camera Controls for USB Cameras\n\n[](./CameraControls.md)\n\n\n**raspiCamSrv** supports a limited set o"
},
{
"path": "docs/Configuration.md",
"chars": 8059,
"preview": "# raspiCamSrv Camera Configuration\n\nRelated Topics:\n\n- [AI Camera Configuration](./Configuration_AI.md)\n- [Camera Tuning"
},
{
"path": "docs/Configuration_AI.md",
"chars": 4478,
"preview": "# raspiCamSrv Camera AI Configuration\n\n[](./Configuration.md)\n\n**NOTE**: This dialog is only availabl"
},
{
"path": "docs/Console.md",
"chars": 459,
"preview": "# Console\n\n[](./UserGuide.md)\n\nThe Console group of dialogs provides functions for user interactions "
},
{
"path": "docs/ConsoleActionButtons.md",
"chars": 969,
"preview": "# Console - Action Buttons\n\n[](./Console.md)\n\nThis page shows buttons which have been configured in t"
},
{
"path": "docs/ConsoleVButtons.md",
"chars": 1901,
"preview": "# Console - Versatile Buttons\n\n[](./Console.md)\n\nThis page shows buttons which have been configured i"
},
{
"path": "docs/FocusHandling.md",
"chars": 3403,
"preview": "# raspiCamSrv Focus Handling\n\n[](./CameraControls.md)\n\nFocus handling is not supported by camera vers"
},
{
"path": "docs/Information.md",
"chars": 762,
"preview": "# raspiCamSrv Information\n\n[](./UserGuide.md)\n\n\n\nThis menu gives acces"
},
{
"path": "docs/Information_Cam.md",
"chars": 19946,
"preview": "# raspiCamSrv Info/Camera Information\n\n[](./Information.md)\n\nThis screen shows information on the ins"
},
{
"path": "docs/Information_CamPrp.md",
"chars": 302,
"preview": "# raspiCamSrv Info/Camera Properties\n\n[](./Information.md)\n\nThis screen shows properties of the activ"
},
{
"path": "docs/Information_Sensor.md",
"chars": 551,
"preview": "# raspiCamSrv Info/Sensor Mode\n\n[](./Information.md)\n\n\nThe camera system advertises the supported Sen"
},
{
"path": "docs/Information_Sys.md",
"chars": 5594,
"preview": "# raspiCamSrv Info/System Information\n\n[](./Information.md)\n\nThis screen shows information on the Ras"
},
{
"path": "docs/LiveDirectControl.md",
"chars": 1971,
"preview": "# raspiCamSrv Live Direct Control\n\n[](./LiveScreen.md)\n\nThis screen is opened by clicking on the [Liv"
},
{
"path": "docs/LiveScreen.md",
"chars": 2965,
"preview": "# raspiCamSrv Live Screen\n\n[](./UserGuide.md)\n\nThe **Live** screen is the central part of the applica"
},
{
"path": "docs/PhotoSeries.md",
"chars": 12500,
"preview": "# raspiCamSrv Photo Series\n\n[](./UserGuide.md)\n\n\nThe *Photo Series* screen allows the management of d"
},
{
"path": "docs/PhotoSeriesExp.md",
"chars": 3200,
"preview": "# Photo Series of type \"Exposure Series\"\n\n[](./PhotoSeries.md)\n\n\nExposure series iterate through a sp"
},
{
"path": "docs/PhotoSeriesFocus.md",
"chars": 1709,
"preview": "# Photo Series of Type \"Focus Stack\"\n\n[](./PhotoSeries.md)\n\n\nA Focus Stack series iterates the Lens P"
},
{
"path": "docs/PhotoSeriesTimelapse.md",
"chars": 5490,
"preview": "# Photo Series of Type \"Timelapse\"\n\n[](./PhotoSeries.md)\n\nThis screen allows special configurations f"
},
{
"path": "docs/PhotoViewer.md",
"chars": 2562,
"preview": "# raspiCamSrv Photo Viewer\n\n[](./UserGuide.md)\n\nAll photos, raw photos or videos taken wit **raspiCam"
},
{
"path": "docs/Phototaking.md",
"chars": 4889,
"preview": "# raspiCamSrv Photo Taking and Video Recording\n\n[](./LiveScreen.md)\n\nThe *Live* tab of **raspiCamSrv*"
},
{
"path": "docs/ReleaseNotes.md",
"chars": 69046,
"preview": "# Release Notes\n\n[](./index.md)\n\n## V4.10.0\n\n### New Features\n\n- [Photo Series of Type \"Timelapse\"](."
},
{
"path": "docs/ScalerCrop.md",
"chars": 4508,
"preview": "# Image Cropping and Sensor Modes\n\n[](./ZoomPan.md)\n\n\n## Pixel Array Size and Sensor Modes\n\nRaspberry"
},
{
"path": "docs/Settings.md",
"chars": 11466,
"preview": "# raspiCamSrv Settings\n\n[](./UserGuide.md)\n\nThe Parameters section of the Settings screen is used for"
},
{
"path": "docs/SettingsAButtons.md",
"chars": 491,
"preview": "# Settings - Action Buttons\n\n[](./Settings.md)\n\nOn this screen, you can 'design' the [Console Action "
},
{
"path": "docs/SettingsAPI.md",
"chars": 3568,
"preview": "# Settings API\n\n[](./Settings.md)\n\nIn this section of the Settings screen, parameters for protection "
},
{
"path": "docs/SettingsConfiguration.md",
"chars": 9308,
"preview": "# Settings / Server Configuration\n\n[](./Settings.md)\n\n\nThe *Settings* screen includes a *Configuratio"
},
{
"path": "docs/SettingsConfiguration_NoCam.md",
"chars": 986,
"preview": "# Settings / Server Configuration (No Camera)\n\nThis is a variant of the [Settings / Server Configuration](./SettingsConf"
},
{
"path": "docs/SettingsDevices.md",
"chars": 13301,
"preview": "# Settings - Devices\n\n[](./Settings.md)\n\nOn this Settings screen you can configure devices connected "
},
{
"path": "docs/SettingsLButtons.md",
"chars": 513,
"preview": "# Settings - Live Buttons\n\n[](./Settings.md)\n\nOn this screen, you can 'design' the [Live Ctrl Buttons"
},
{
"path": "docs/SettingsUpdate.md",
"chars": 2697,
"preview": "# Settings - Update\n\n[](./Settings.md)\n\nThis dialog can be used to update raspiCamSrv to the latest v"
},
{
"path": "docs/SettingsUsers.md",
"chars": 629,
"preview": "# Settings Users\n\n[](./Settings.md)\n\n\nFor management of users, the *Settings* screen has an additiona"
},
{
"path": "docs/SettingsVButtons.md",
"chars": 3197,
"preview": "# Settings - Versatile Buttons\n\n[](./Settings.md)\n\nThis Settings screen allows configuration of funct"
},
{
"path": "docs/Settings_NoCam.md",
"chars": 2555,
"preview": "# raspiCamSrv Settings (No Camera)\n\n[](./UserGuide_NoCam.md)\n\nThis is a variant of the general [Setti"
},
{
"path": "docs/SetupDocker.md",
"chars": 8076,
"preview": "# Running **raspiCamSrv** as Docker Container\n\n[](./getting_started_overview.md)\n\nA container image i"
},
{
"path": "docs/Trigger.md",
"chars": 6158,
"preview": "# Introduction to Event Handling and Triggered Capture of Videos and Photos\n\n[](./TriggerOverview.md)"
},
{
"path": "docs/TriggerActions.md",
"chars": 6648,
"preview": "# Actions\n\n[](./TriggerOverview.md)\n\nThis screen is used to specify actions which can be started by *"
},
{
"path": "docs/TriggerActive.md",
"chars": 2934,
"preview": "# Triggered Capture of Videos and Photos\n\n[](./TriggerOverview.md)\n\n# Active Motion Capturing\n\nThe *S"
},
{
"path": "docs/TriggerCalendar.md",
"chars": 1321,
"preview": "# Trigger / Event Calendar\n\n[](./TriggerOverview.md)\n\nThe calendar gives an overview on the number of"
},
{
"path": "docs/TriggerCameraActions.md",
"chars": 1417,
"preview": "# Camera Actions\n\n[](./TriggerOverview.md)\n\n\n\n\nThis section allows"
},
{
"path": "docs/TriggerControl.md",
"chars": 4178,
"preview": "# Trigger / Control\n\n[](./TriggerOverview.md)\n\nWith this screen, you control scheduling of event hand"
},
{
"path": "docs/TriggerEventViewer.md",
"chars": 2705,
"preview": "# Trigger / Events\n\n[](./TriggerOverview.md)\n\nEvent Details are shown in the Event Viewer for a speci"
},
{
"path": "docs/TriggerMotion.md",
"chars": 11298,
"preview": "# Trigger / Motion Detection Configuration\n\n[](./TriggerOverview.md)\n\n](./TriggerOverview.md)\n\nOn this tab, you specify the details required for"
},
{
"path": "docs/TriggerOverview.md",
"chars": 877,
"preview": "# Trigger - Triggers and Actions\n\n[](./UserGuide.md)\n\n\n\n**raspiCamSrv"
},
{
"path": "docs/TriggerTriggerActions.md",
"chars": 569,
"preview": "# Trigger-Actions\n\n[](./TriggerOverview.md)\n\nOn this page, you specify which actions are invoked in c"
},
{
"path": "docs/TriggerTriggers.md",
"chars": 4646,
"preview": "# Triggers\n\n[](./TriggerOverview.md)\n\nThis page is used for spacification of triggers. \nTriggers "
},
{
"path": "docs/Troubelshooting.md",
"chars": 8947,
"preview": "# raspiCamSrv Troubleshooting\n\n## Errors during Installation\n\nThis section deals with errors which may occur while runni"
},
{
"path": "docs/Tuning.md",
"chars": 5875,
"preview": "# raspiCamSrv Camera Tuning\n\n[](./UserGuide.md)\n\nThe algorithms of Raspberry Pi cameras are affected "
},
{
"path": "docs/UserGuide.md",
"chars": 12952,
"preview": "# RaspiCamSrv User Guide\n\n[](./index.md)\n\nThe variant of the user interface, described on this page, "
},
{
"path": "docs/UserGuide_NoCam.md",
"chars": 3646,
"preview": "# RaspiCamSrv User Guide (No Camera)\n\n[](./index.md)\n\nThis is a special variant of the general **rasp"
},
{
"path": "docs/Z_Legacy_Information.md",
"chars": 23926,
"preview": "# raspiCamSrv Information on Camera System\n\n[](./UserGuide.md)\n\nThis screen contains several tabs wit"
},
{
"path": "docs/ZoomPan.md",
"chars": 4311,
"preview": "# raspiCamSrv Zoom & Pan\n\n[](./CameraControls.md)\n\n\n\nThis tab allows zoomi"
},
{
"path": "docs/api/postman/raspiCamSrv.postman_collection.json",
"chars": 22072,
"preview": "{\n\t\"info\": {\n\t\t\"_postman_id\": \"5f679e3f-97eb-491c-8265-7ebfe598603c\",\n\t\t\"name\": \"raspiCamSrv\",\n\t\t\"description\": \"API for"
},
{
"path": "docs/bp_Hotspot_Bookworm.md",
"chars": 3123,
"preview": "# Hotspot Configuration for 'Bookworm' OS\n\n[](./bp_PiZero_Standalone.md)\n\nThis section describes how "
},
{
"path": "docs/bp_Hotspot_Bullseye.md",
"chars": 3518,
"preview": "# Hotspot Configuration for 'Bullseye' OS\n\n[](./bp_PiZero_Standalone.md)\n\nThis section describes how "
},
{
"path": "docs/bp_Hotspot_Trixie.md",
"chars": 3061,
"preview": "# Hotspot Configuration for *Trixie* OS\n\n[](./bp_PiZero_Standalone.md)\n\nThis section describes how to"
},
{
"path": "docs/bp_PiZero_Standalone.md",
"chars": 3927,
"preview": "# Setup of Raspberry Pi Zero as Standalone System\n\n[](./getting_started_overview.md)\n\nThis section de"
},
{
"path": "docs/features.md",
"chars": 16021,
"preview": "\n# Features V4.10.x\n\n[](./index.md)\n\nFor more details, see the [User Guide](./UserGuide.md). \n\n](./index.md)\n\n1. [Check requirements](requirements.md)\n2. [Setu"
},
{
"path": "docs/gpioDevices/ServoPWM.md",
"chars": 5149,
"preview": "# ServoPWM\n\n## Overview\n\n```\nclass ServoPWM(*args, **kwargs)\n```\n\nimplements control of servo motors with hardware PWM.\n"
},
{
"path": "docs/gpioDevices/StepperMotor.md",
"chars": 6581,
"preview": "# StepperMotor\n\n## Overview\n\n```\nclass StepperMotor(*args, **kwargs)\n```\n\nextends ```gpiozero.OutputDevice``` and repres"
},
{
"path": "docs/index.md",
"chars": 1324,
"preview": "**raspiCamSrv** is a Web server for Raspberry Pi systems providing an App for control and streaming of CSI and USB camer"
},
{
"path": "docs/installation.md",
"chars": 19386,
"preview": "# RaspiCamSrv Installation\n\n[](./getting_started_overview.md)\n\n## Installation Steps\n\nThe following d"
},
{
"path": "docs/installation_man.md",
"chars": 10396,
"preview": "# Manual raspiCamSrv Installation\n\n[](./getting_started_overview.md)\n\n\nThe following procedure descri"
},
{
"path": "docs/picamera2_manual.md",
"chars": 168,
"preview": "[The Picamera2 Library](https://pip-assets.raspberrypi.com/categories/652-raspberry-pi-camera-module-2/documents/RP-0081"
},
{
"path": "docs/requirements.md",
"chars": 2414,
"preview": "# Requirements\n\n[](./getting_started_overview.md)\n\n- A **Raspberry Pi** ([Zero W](https://www.raspber"
},
{
"path": "docs/service_configuration.md",
"chars": 7549,
"preview": "# Service Configuration\n\n[](./getting_started_overview.md)\n\n**NOTE**: This installation step is inclu"
},
{
"path": "docs/system_setup.md",
"chars": 1269,
"preview": "# System Setup for raspiCamSrv\n\n[](./getting_started_overview.md)\n\nFollow the instructions of the [Ra"
},
{
"path": "docs/tutorials/AWB_with_neural_networks.md",
"chars": 3265,
"preview": "# Tutorial: Automatic White Balance with Neural Networks\n\n[](./Tutorials_Overview.md)\n\nThis tutori"
},
{
"path": "docs/tutorials/Tutorials_Overview.md",
"chars": 144,
"preview": "# RaspiCamSrv Tutorials\n\n[](../index.md)\n\n- [Automatic White Balance with Neural Networks](./AWB_w"
},
{
"path": "docs/updating_raspiCamSrv.md",
"chars": 2812,
"preview": "# Updating raspiCamSrv\n\n[](./index.md)\n\nBefore updating, make sure that\n\n- [video recording](./Photot"
},
{
"path": "mkdocs.yml",
"chars": 4865,
"preview": "site_name: raspiCamSrv V4.10.x Documentation\nplugins:\n - search\n - mike\ntheme:\n name: material\n favicon: img/fav"
},
{
"path": "raspiCamSrv/__init__.py",
"chars": 10336,
"preview": "import os\nfrom pathlib import Path\nfrom flask import Flask\nimport logging\nfrom flask.logging import default_handler\nfrom"
},
{
"path": "raspiCamSrv/api.py",
"chars": 27783,
"preview": "from flask import Blueprint, request, jsonify\nfrom werkzeug.security import check_password_hash\nfrom werkzeug.exceptions"
},
{
"path": "raspiCamSrv/auth.py",
"chars": 9780,
"preview": "import functools\nfrom raspiCamSrv.version import version\n\nfrom flask import (\n Blueprint,\n flash,\n g,\n redir"
},
{
"path": "raspiCamSrv/auth_su.py",
"chars": 1169,
"preview": "import functools\n\nfrom flask import (\n g,\n redirect,\n url_for,\n)\nfrom werkzeug.security import check_password_h"
},
{
"path": "raspiCamSrv/camCfg.py",
"chars": 276119,
"preview": "import subprocess\r\nimport importlib\r\nfrom subprocess import CalledProcessError\r\nimport json\r\nimport logging\r\nimport os\r\n"
},
{
"path": "raspiCamSrv/camera_pi.py",
"chars": 346673,
"preview": "import io\r\nimport time\r\nimport datetime\r\nimport threading\r\nfrom _thread import get_ident, allocate_lock\r\nfrom raspiCamSr"
},
{
"path": "raspiCamSrv/config.py",
"chars": 85443,
"preview": "from flask import (\n Blueprint,\n Response,\n flash,\n g,\n redirect,\n render_template,\n request,\n u"
},
{
"path": "raspiCamSrv/console.py",
"chars": 5009,
"preview": "from flask import Blueprint, Response, flash, g, redirect, render_template, request, url_for\nfrom werkzeug.exceptions im"
},
{
"path": "raspiCamSrv/db.py",
"chars": 873,
"preview": "import sqlite3\n\nimport click\nfrom flask import current_app, g\nfrom raspiCamSrv.camCfg import CameraCfg\nimport logging\n\nl"
},
{
"path": "raspiCamSrv/dbx.py",
"chars": 433,
"preview": "import sqlite3\n\nimport raspiCamSrv.camCfg as camCfg\nimport logging\n\nlogger = logging.getLogger(__name__)\n\n\ndef get_dbx()"
},
{
"path": "raspiCamSrv/gpioDeviceTypes.py",
"chars": 26752,
"preview": "gpioDeviceTypes = [\n {\n \"type\": \"Button\",\n \"usage\": \"Input\",\n \"docUrl\": \"https://gpiozero.readth"
},
{
"path": "raspiCamSrv/gpioDevices.py",
"chars": 29031,
"preview": "from gpiozero import OutputDevice, PWMOutputDevice\nimport threading\nfrom _thread import allocate_lock\nimport time\nfrom d"
},
{
"path": "raspiCamSrv/home.py",
"chars": 61163,
"preview": "from flask import (\n current_app,\n Blueprint,\n Response,\n flash,\n g,\n redirect,\n render_template,\n "
},
{
"path": "raspiCamSrv/images.py",
"chars": 14755,
"preview": "from flask import Blueprint, Response, flash, g, redirect, render_template, request, url_for\nfrom flask import send_file"
},
{
"path": "raspiCamSrv/info.py",
"chars": 1446,
"preview": "from flask import Blueprint, Response, flash, g, redirect, render_template, request, url_for\nfrom werkzeug.exceptions im"
},
{
"path": "raspiCamSrv/motionAlgoIB.py",
"chars": 46053,
"preview": "##############################################################################################\n# Motion detection Algori"
},
{
"path": "raspiCamSrv/motionDetector.py",
"chars": 42189,
"preview": "from raspiCamSrv.camera_pi import Camera\nfrom raspiCamSrv.camCfg import CameraCfg\nimport numpy as np\nfrom _thread import"
},
{
"path": "raspiCamSrv/photoseries.py",
"chars": 51453,
"preview": "from flask import Blueprint, Response, flash, g, redirect, render_template, request, url_for\nfrom flask import send_file"
},
{
"path": "raspiCamSrv/photoseriesCfg.py",
"chars": 57101,
"preview": "from datetime import datetime\nfrom datetime import timedelta\nfrom raspiCamSrv.camCfg import CameraCfg, CameraConfig, Cam"
},
{
"path": "raspiCamSrv/schema.sql",
"chars": 1228,
"preview": "DROP TABLE IF EXISTS user;\nDROP TABLE IF EXISTS config;\nDROP TABLE IF EXISTS events;\nDROP TABLE IF EXISTS eventactions;\n"
},
{
"path": "raspiCamSrv/settings.py",
"chars": 100773,
"preview": "from flask import Blueprint, Response, flash, g, render_template, request, current_app\nfrom werkzeug.exceptions import a"
},
{
"path": "raspiCamSrv/static/w3.css",
"chars": 31204,
"preview": "/* W3.CSS 5.02 March 31 2025 by Jan Egil and Borge Refsnes */\nhtml {\n box-sizing: border-box\n}\n\n*,\n*:before,\n*:after"
},
{
"path": "raspiCamSrv/stereoCam.py",
"chars": 38430,
"preview": "from raspiCamSrv.camera_pi import Camera\nfrom raspiCamSrv.camCfg import CameraCfg\nfrom raspiCamSrv.camCfg import StereoC"
},
{
"path": "raspiCamSrv/sun.py",
"chars": 16671,
"preview": "\"\"\" Module for calculation of sun path properties\n\n - Sunrise / Sunset times\n (Based on code from https://en.wik"
},
{
"path": "raspiCamSrv/templates/auth/login.html",
"chars": 529,
"preview": "{% extends 'base.html' %}\n\n{% block header %}\n{% block title %}Log In{% endblock %}\n{% endblock %}\n\n{% block content %}\n"
},
{
"path": "raspiCamSrv/templates/auth/password.html",
"chars": 872,
"preview": "{% extends 'base.html' %}\n\n{% block header %}\n{% block title %}Change Password{% endblock %}\n{% endblock %}\n\n{% block co"
},
{
"path": "raspiCamSrv/templates/auth/register.html",
"chars": 575,
"preview": "{% extends 'base.html' %}\n\n{% block header %}\n{% block title %}Register{% endblock %}\n{% endblock %}\n\n{% block content %"
},
{
"path": "raspiCamSrv/templates/base.html",
"chars": 15990,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <meta charset=\"UTF-8\">\n <title>{% block title %}{% endblock %} - raspiCamSrv</ti"
},
{
"path": "raspiCamSrv/templates/config/main.html",
"chars": 126357,
"preview": "{% extends 'base.html' %}\n\n{% block header %}\n {% block title %}Camera Configurations{% endblock %}\n <style>\n "
},
{
"path": "raspiCamSrv/templates/console/console.html",
"chars": 14825,
"preview": "{% extends 'base.html' %}\n\n{% block header %}\n{% block title %}Console{% endblock %}\n{% endblock %}\n\n{% block content %}"
},
{
"path": "raspiCamSrv/templates/home/index.html",
"chars": 160268,
"preview": "<!--\nRaspiCamSrv's Live page \n-->\n{% extends 'base.html' %}\n\n{% block header %}\n {% block title %}Live{% endblock "
},
{
"path": "raspiCamSrv/templates/home/liveDirectPanel.html",
"chars": 24052,
"preview": "<!--\nRaspiCamSrv's Live page \n-->\n{% extends 'base.html' %}\n\n{% block header %}\n {% block title %}Live - Direct Co"
},
{
"path": "raspiCamSrv/templates/images/main.html",
"chars": 10227,
"preview": "{% extends 'base.html' %}\n\n{% block header %}\n {% block title %}Photos{% endblock %}\n <style>\n /* Custom st"
},
{
"path": "raspiCamSrv/templates/info/info.html",
"chars": 21100,
"preview": "{% extends 'base.html' %}\n\n{% block header %}\n {% block title %}Information{% endblock %}\n{% endblock %}\n\n{% block co"
},
{
"path": "raspiCamSrv/templates/media_viewer.html",
"chars": 1005,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\">\n <title>{{ filename }}</title>\n <meta name=\"v"
},
{
"path": "raspiCamSrv/templates/photoseries/main.html",
"chars": 96478,
"preview": "{% extends 'base.html' %}\n\n{% block header %}\n {% block title %}Photo Series{% endblock %}\n{% endblock %}\n\n{% block c"
},
{
"path": "raspiCamSrv/templates/settings/main.html",
"chars": 117948,
"preview": "{% extends 'base.html' %}\n\n{% block header %}\n {% block title %}Server Settings{% endblock %}\n{% endblock %}\n\n{% bloc"
},
{
"path": "raspiCamSrv/templates/trigger/trigger.html",
"chars": 153791,
"preview": "{% extends 'base.html' %}\n\n{% block header %}\n{% block title %}Trigger{% endblock %}\n <style>\n /* Custom style"
},
{
"path": "raspiCamSrv/templates/webcam/webcam.html",
"chars": 75760,
"preview": "{% extends 'base.html' %}\n\n{% block header %}\n{% block title %}Camera Access{% endblock %}\n{% endblock %}\n\n{% block cont"
},
{
"path": "raspiCamSrv/trigger.py",
"chars": 56186,
"preview": "from flask import Blueprint, Response, flash, g, redirect, render_template, request, url_for\nfrom flask import send_file"
},
{
"path": "raspiCamSrv/triggerHandler.py",
"chars": 82956,
"preview": "from gpiozero import Button, LineSensor, MotionSensor, LightSensor, DistanceSensor, RotaryEncoder, DigitalInputDevice\nfr"
},
{
"path": "raspiCamSrv/version.py",
"chars": 17,
"preview": "version=\"V4.10.0\""
},
{
"path": "raspiCamSrv/versionDoc.py",
"chars": 17,
"preview": "docversion=\"4.10\""
},
{
"path": "raspiCamSrv/webcam.py",
"chars": 73201,
"preview": "from flask import (\n Blueprint,\n Response,\n flash,\n g,\n redirect,\n render_template,\n request,\n u"
},
{
"path": "requirements.txt",
"chars": 119,
"preview": "RPi.GPIO\ngpiozero\nFlask>=3,<4\nnumpy\nmatplotlib<3.8\nflask-jwt-extended\npsutil\nrequests\nmunkres\ngunicorn\nrpi_hardware_pwm"
},
{
"path": "scripts/install_raspiCamSrv.sh",
"chars": 30573,
"preview": "#!/bin/bash\nset -e\n\n############################################\n# raspiCamSrv Installer + systemd setup\n###############"
},
{
"path": "scripts/uninstall_raspiCamSrv.sh",
"chars": 5307,
"preview": "#!/bin/bash\nset -e\n\n############################################\n# raspiCamSrv Uninstaller\n#############################"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the signag/raspi-cam-srv GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 143 files (2.8 MB), approximately 727.3k tokens, and a symbol index with 1970 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.