Skip to main content

Optimise photos for the SwitchBot 13.3" AI Art Frame (E Ink Spectra 6).

Project description

switchbot-e6-optimizer

CI

Make photos look better on the SwitchBot 13.3" AI Art Frame and other E Ink Spectra 6 ("E6") panels.

E6 panels show only six muted inks and render dark, flat, and low-contrast to mimic paper. Uploaded straight from your phone, most photos come out dull and muddy. This tool applies the continuous-tone preparation the panel needs - boosted saturation and contrast, opened shadows, a warm nudge, and sharpening - then leaves the dithering to the SwitchBot app.

Do not pre-dither for the SwitchBot app. The app does its own colour mapping and dithering on upload. If you dither first you get double-dithering: visible noise, muddy colour.

Why the panel needs this

Adjustment Compensates for
Saturation (biggest lever) Muted six-ink gamut
Contrast Compressed (~26:1) dynamic range
Brightness + shadow lift Panel renders dark and crushes shadows
Warmth Paper-grey white, weak blues
Sharpen Detail lost to dithering and sub-native resolution
No dithering The app dithers; doing it twice = mud

Requirements

  • Python 3.14+
  • uv (manages the environment, tests, and linting)

Install

git clone https://github.com/hamzic/switchbot-e6-optimizer
cd switchbot-e6-optimizer
uv sync            # create the venv and install everything

Run it with uv run:

uv run switchbot-e6 photo.jpg

Or install the CLI as a standalone tool:

uv tool install .
switchbot-e6 photo.jpg

To uninstall the tool later:

uv tool uninstall switchbot-e6-optimizer

Usage

# one photo, default "medium" intensity -> photo_e6.png next to it
switchbot-e6 photo.jpg

# a whole folder into ./out, portrait mount
switchbot-e6 ~/Pictures/art --orientation portrait --out ./out

# punchier preset for flat, boldly-coloured art
switchbot-e6 poster.png --intensity high

# ride the high preset but pin saturation to exactly +80%
switchbot-e6 poster.png --intensity high --saturation 80

# crop + resize only, no tonal edits (A/B against the app's own processing)
switchbot-e6 photo.jpg --raw

Inputs can be files or whole folders. Running with no arguments prints the full help. You can also run it as a module: python -m switchbot_e6_optimizer.

Supported formats

Direction Formats
Input JPEG, PNG, WebP, BMP, TIFF, iPhone HEIC/HEIF
Output PNG (default) or JPEG (--format jpg)

When a folder is expanded, files already ending in the output suffix (*_e6) are skipped with a notice so re-runs don't double-process previous output; pass such a file explicitly to force it.

The exported file looks a little too vivid and too bright on your monitor; that is correct for E6. After exporting, upload the *_e6 file to the SwitchBot app as-is and fine-tune with the app's own saturation/contrast sliders once you see it on the panel.

Intensity presets

Each preset sets every knob at once. medium is the default. Any single tuning flag overrides just that value on top of the chosen preset.

Preset Saturation Contrast Brightness Shadow lift Warmth Sharpen
none / --raw - - - - - -
low +40% +18% +5% 10 3 60
medium +60% +25% +8% 18 5 80
high +100% +30% +12% 26 8 100

none (or --raw) does crop + resize only, with no tonal changes.

Options

Option Default Description
-o, --output DIR (or --out) next to source Output directory, created if missing
--suffix S _e6 Output filename suffix
--format {png,jpg} png Output format
--quality N 100 JPEG quality (1-100), used with --format jpg
--orientation {landscape,portrait} landscape Panel mount
--intensity {none,low,medium,high} medium Overall strength preset
--raw off Alias for --intensity none
--saturation--sharpen from preset Override an individual knob (values must be ≥ 0)
--no-crop off Letterbox instead of crop-to-fill 4:3
--size WxH 1600x1200 Override panel size

The panel is 1600×1200 (4:3). By default the tool crops-to-fill (centred) so it fills the frame; use --no-crop to contain the whole image with borders instead (white with --raw, tinted slightly warm once a tonal preset is applied).

Development

Everything runs through uv:

uv sync                 # install deps + dev tools (pytest, ruff)
uv run pytest           # run the test suite
uv run ruff check .     # lint (PEP 8 + import sort + pyupgrade + bugbear)
uv run ruff format .    # format
uv build                # build sdist + wheel into dist/

Project structure

switchbot-e6-optimizer/
├── .github/
│   ├── dependabot.yml                  # weekly action-SHA + uv dep updates
│   ├── ruleset-main-protection.json    # branch protection, applied via API
│   └── workflows/
│       ├── ci.yml                      # lint + tests on Linux/macOS/Windows
│       └── release.yml                 # gated build/publish (OIDC)
├── src/switchbot_e6_optimizer/
│   ├── __init__.py                     # version + public re-exports
│   ├── __main__.py                     # python -m switchbot_e6_optimizer
│   ├── optimizer.py                    # the pipeline + CLI
│   └── py.typed
├── tests/
│   └── test_optimizer.py
├── AGENTS.md                           # guidance for AI coding agents
├── CHANGELOG.md
├── LICENSE
├── README.md
├── pyproject.toml
└── uv.lock

Trademarks

"SwitchBot" and "E Ink" / "Spectra" are trademarks of their respective owners. This is an independent, unofficial tool - not affiliated with, endorsed by, or sponsored by SwitchBot or E Ink.

License

MIT - free to use, modify, and distribute; just keep the license notice so use traces back to this project.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

switchbot_e6_optimizer-1.0.0.tar.gz (11.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

switchbot_e6_optimizer-1.0.0-py3-none-any.whl (14.2 kB view details)

Uploaded Python 3

File details

Details for the file switchbot_e6_optimizer-1.0.0.tar.gz.

File metadata

  • Download URL: switchbot_e6_optimizer-1.0.0.tar.gz
  • Upload date:
  • Size: 11.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for switchbot_e6_optimizer-1.0.0.tar.gz
Algorithm Hash digest
SHA256 a8b66e3517a4c9f481825e029c5776e37396886c601136665acd9c6993d1f284
MD5 7772fe551d993a9595bb8055cc6b81ff
BLAKE2b-256 c36d9f91f27dac4cc4055c3ded7cf6b45de72dbeab660a585e871e6183ee920b

See more details on using hashes here.

File details

Details for the file switchbot_e6_optimizer-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: switchbot_e6_optimizer-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 14.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for switchbot_e6_optimizer-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 22ad60e073c18ae5a5f30e176cc14a3eba882364ffeae32c931f4744892864e0
MD5 bb598bafaf803475879179705e9cf168
BLAKE2b-256 608720dc2685ebb0b9e0059caa8b906181eb07e539295ce05685a29bcfe30180

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page