Metadata-Version: 2.4
Name: umeko-py-thermal
Version: 0.1.0
Summary: Python SDK for Umeko ESP32 thermal imaging camera
Project-URL: Homepage, https://github.com/umeko/umeko-py-thermal
Project-URL: Issues, https://github.com/umeko/umeko-py-thermal/issues
Author: Umeko
License: MIT
Keywords: esp32,heimann,infrared,mlx90640,serial,thermal
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Image Recognition
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Requires-Dist: numpy>=1.20
Requires-Dist: pillow>=9.0
Requires-Dist: pyserial>=3.5
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == 'dev'
Description-Content-Type: text/markdown

# umeko-py-thermal

[![PyPI](https://img.shields.io/pypi/v/umeko-py-thermal.svg)](https://pypi.org/project/umeko-py-thermal/)
[![Python](https://img.shields.io/pypi/pyversions/umeko-py-thermal.svg)](https://pypi.org/project/umeko-py-thermal/)

**English** | [中文](README.zh.md)

Python SDK for Umeko ESP32-based thermal imaging cameras.  
Read temperature matrices in real-time over serial port — no GUI boilerplate required.

Supported sensors (auto-detected):

| Sensor | Resolution | Data format |
|--------|-----------|-------------|
| Heimann | 32×32 | `uint16` raw → `°C` |
| Melexis MLX90640 | 32×24 | `float` °C |
| Melexis MLX90641 | 16×12 | `float` °C |

## Install

```bash
pip install umeko-py-thermal
```

Requires **Python ≥ 3.8**, `pyserial`, `numpy`, and `Pillow`.

## Quick start

```python
from umeko_thermal import ThermalCamera

# Auto-detect serial port
cam = ThermalCamera(auto_detect=True)
cam.connect()

# Stream 100 frames
for frame in cam.stream(max_frames=100):
    print(f"max={frame.max():.1f}°C  min={frame.min():.1f}°C")

cam.disconnect()
```

Or use the context manager:

```python
from umeko_thermal import ThermalCamera

with ThermalCamera(port="COM3") as cam:
    for frame in cam.stream(max_frames=200):
        mat = frame.to_numpy()   # shape: (height, width)
        img = frame.to_image(scale=10, colormap="stream")
        img.save("thermal.png")
```

## Live preview window

```python
with ThermalCamera(port="COM3") as cam:
    cam.show(scale=15, colormap="inferno")
```

Opens a small blocking window that renders the live stream.  
Everything runs on the main thread — no background workers. Closing the window stops the stream, drains the serial buffer, and returns control to your script.

## Device filesystem

The camera can store `.bin` snapshots on its internal flash:

```python
files = cam.list_files()          # [FileInfo(name="IMG_001.bin", size=2048, type="32x32")]
frame = cam.read_file("IMG_001.bin")
frame.to_image().save("snapshot.png")

cam.delete_file("IMG_001.bin")
cam.clear_all_files()
```

## API at a glance

| Method | Description |
|--------|-------------|
| `cam.connect()` | Open serial port |
| `cam.disconnect()` | Close serial port |
| `cam.stream(...)` | Generator yielding `ThermalFrame` |
| `cam.show(...)` | Blocking live preview window |
| `cam.list_files()` | List stored `.bin` snapshots |
| `cam.read_file(name)` | Read a stored snapshot |
| `cam.delete_file(name)` | Delete a snapshot |
| `cam.clear_all_files()` | Wipe all snapshots |
| `cam.list_calibrations()` | Read temperature calibration table |
| `cam.reboot_to_bootloader()` | Enter bootloader |
| `cam.reverse_screen_color()` | Flip device screen colors |

### `ThermalFrame`

| Property / Method | Returns |
|-------------------|---------|
| `frame.data` | `list[list[float]]` temperature matrix (°C) |
| `frame.width`, `frame.height` | Resolution |
| `frame.max()` | Highest temperature |
| `frame.min()` | Lowest temperature |
| `frame.mean()` | Average temperature |
| `frame.get(x, y)` | Temperature at pixel *(x, y)* |
| `frame.to_numpy()` | `np.ndarray` shape *(height, width)* |
| `frame.to_image(scale=10, colormap="stream")` | `PIL.Image.Image` (RGB) |

## Documentation

See [`docs/SDK.md`](docs/SDK.md) for the full design spec and protocol details.

## License

MIT
