Metadata-Version: 2.4
Name: kaithem
Version: 0.97.0
Summary: Home/Commercial SCADA-like automation system
Author: Daniel Dunn
License-Expression: GPL-3.0-or-later
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Requires-Dist: scullery==0.4.0
Requires-Dist: iot-devices==0.33.0
Requires-Dist: icemedia==0.2.3
Requires-Dist: nvrchannel==0.20.0
Requires-Dist: numpy==2.5.2
Requires-Dist: extism==1.1.1
Requires-Dist: extism-sys==1.12.0
Requires-Dist: mako==1.4.1
Requires-Dist: jinja2==3.1.6
Requires-Dist: pam==0.2.0
Requires-Dist: msgpack==1.2.2
Requires-Dist: pyyaml==6.0.3
Requires-Dist: types-pyyaml==6.0.12.20260815
Requires-Dist: nmcli==1.8.0
Requires-Dist: apprise==1.13.1
Requires-Dist: ffmpeg-python==0.2.0
Requires-Dist: yappi==1.7.6
Requires-Dist: zeroconf==0.151.3
Requires-Dist: colorzero==2.0
Requires-Dist: tinytag==2.3.1
Requires-Dist: jsonschema==4.26.0
Requires-Dist: pint==0.25.3
Requires-Dist: pyflakes==3.4.0
Requires-Dist: python-mpv-jsonipc==1.4.0
Requires-Dist: textdistance==4.6.3
Requires-Dist: toml==0.10.2
Requires-Dist: vignette==6.0.0
Requires-Dist: simpleeval==1.0.7
Requires-Dist: websockets==17.1
Requires-Dist: zeep==4.3.3
Requires-Dist: passlib==1.7.4
Requires-Dist: pillow==12.3.0
Requires-Dist: markupsafe==3.0.3
Requires-Dist: python-dateutil==2.9.0.post0
Requires-Dist: recurrent==0.4.1
Requires-Dist: pygments==2.21.0
Requires-Dist: pytz==2026.3.post1
Requires-Dist: ntplib==0.4.0
Requires-Dist: holidays==0.103
Requires-Dist: pyserial==3.5
Requires-Dist: pygrep==0.3.2
Requires-Dist: paho-mqtt==2.1.0
Requires-Dist: setproctitle==1.3.7
Requires-Dist: psutil==7.2.2
Requires-Dist: jack-client==0.5.5
Requires-Dist: sf2utils==1.0.0
Requires-Dist: scipy==1.18.1
Requires-Dist: attrs==26.1.0
Requires-Dist: pydantic==2.13.5
Requires-Dist: types-jsonschema==4.26.0.20260518
Requires-Dist: stamina==26.1.0
Requires-Dist: stream-zip==0.0.84
Requires-Dist: pycrdt==0.14.4
Requires-Dist: argon2-cffi==25.1.0
Requires-Dist: msgpack-types==0.8.0
Requires-Dist: niquests==3.21.1
Requires-Dist: quart>=0.20.0
Requires-Dist: hypercorn==0.18.0
Requires-Dist: structlog==26.1.0
Requires-Dist: rich==15.0.0
Requires-Dist: starlette==1.6.0
Requires-Dist: ephem==4.2.1
Requires-Dist: sherpa-onnx==1.13.0
Requires-Dist: sherpa-onnx-core==1.13.0
Requires-Dist: soundfile==0.14.0
Requires-Dist: textual-image==0.13.2
Requires-Dist: urllib3-future==2.24.906
Requires-Dist: scipy-stubs==1.18.1.0
Requires-Dist: aenum==3.1.17
Requires-Dist: aioesphomeapi==42.7.0
Requires-Dist: aiofiles==25.1.0
Requires-Dist: aiohappyeyeballs==2.7.1
Requires-Dist: aiohttp==3.14.3
Requires-Dist: aiorun==2025.1.1
Requires-Dist: aiosignal==1.4.0
Requires-Dist: aiostream==0.7.1
Requires-Dist: annotated-types==0.8.0
Requires-Dist: anyio==4.15.0
Requires-Dist: argon2-cffi-bindings==26.1.0
Requires-Dist: async-interrupt==1.2.2
Requires-Dist: bleak==3.0.2
Requires-Dist: blinker==1.9.0
Requires-Dist: certifi==2026.7.22
Requires-Dist: cffi==2.1.1
Requires-Dist: chacha20poly1305-reuseable==0.13.2
Requires-Dist: charset-normalizer==3.5.1
Requires-Dist: click==8.5.0
Requires-Dist: coloredlogs==15.0.1
Requires-Dist: cryptography==50.0.1
Requires-Dist: dacite==1.9.2
Requires-Dist: dbus-fast==5.0.22 ; sys_platform == 'linux'
Requires-Dist: flask==3.1.3
Requires-Dist: flexcache==0.3
Requires-Dist: flexparser==0.4
Requires-Dist: frozenlist==1.8.0
Requires-Dist: future==1.0.0
Requires-Dist: gpiozero==2.0.1.post3
Requires-Dist: gpsdclient==1.3.2
Requires-Dist: h11==0.16.0
Requires-Dist: h2==4.4.1
Requires-Dist: home-assistant-chip-clusters==2025.7.0
Requires-Dist: hpack==4.2.0
Requires-Dist: humanfriendly==10.0
Requires-Dist: hyperframe==6.1.0
Requires-Dist: idna==3.19
Requires-Dist: ifaddr==0.2.0
Requires-Dist: isodate==0.7.2
Requires-Dist: itsdangerous==2.2.0
Requires-Dist: jh2==5.0.14
Requires-Dist: jsonschema-specifications==2025.9.1
Requires-Dist: linkify-it-py==2.2.0
Requires-Dist: lxml==6.1.3
Requires-Dist: markdown==3.10.3
Requires-Dist: markdown-it-py==4.2.0
Requires-Dist: mdit-py-plugins==0.6.1
Requires-Dist: mdurl==0.1.2
Requires-Dist: multidict==6.7.1
Requires-Dist: noiseprotocol==0.3.1
Requires-Dist: numpy-typing-compat==20260602.2.5
Requires-Dist: oauthlib==3.3.1
Requires-Dist: opencv-python==5.0.0.93
Requires-Dist: optype==0.18.0
Requires-Dist: orjson==3.12.0
Requires-Dist: parsedatetime==2.6
Requires-Dist: platformdirs==4.11.7
Requires-Dist: priority==2.0.0
Requires-Dist: propcache==0.5.2
Requires-Dist: protobuf==7.36.1
Requires-Dist: pycparser==3.0 ; implementation_name != 'PyPy'
Requires-Dist: pycryptodome==3.23.0
Requires-Dist: pydantic-core==2.46.5
Requires-Dist: pyobjc-core==12.2.2 ; sys_platform == 'darwin'
Requires-Dist: pyobjc-framework-cocoa==12.2.2 ; sys_platform == 'darwin'
Requires-Dist: pyobjc-framework-corebluetooth==12.2.2 ; sys_platform == 'darwin'
Requires-Dist: pyobjc-framework-libdispatch==12.2.2 ; sys_platform == 'darwin'
Requires-Dist: pyreadline3==3.5.6 ; sys_platform == 'win32'
Requires-Dist: python-magic==0.4.27
Requires-Dist: python-matter-server==8.1.2
Requires-Dist: python-pam==2.0.2
Requires-Dist: qh3==2.0.3 ; (platform_machine == 'AMD64' and platform_python_implementation == 'CPython' and sys_platform == 'darwin') or (platform_machine == 'ARM64' and platform_python_implementation == 'CPython' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'darwin') or (platform_machine == 'arm64' and platform_python_implementation == 'CPython' and sys_platform == 'darwin') or (platform_machine == 'armv7l' and platform_python_implementation == 'CPython' and sys_platform == 'darwin') or (platform_machine == 'i686' and platform_python_implementation == 'CPython' and sys_platform == 'darwin') or (platform_machine == 'ppc64' and platform_python_implementation == 'CPython' and sys_platform == 'darwin') or (platform_machine == 'ppc64le' and platform_python_implementation == 'CPython' and sys_platform == 'darwin') or (platform_machine == 'riscv64' and platform_python_implementation == 'CPython' and sys_platform == 'darwin') or (platform_machine == 'riscv64gc' and platform_python_implementation == 'CPython' and sys_platform == 'darwin') or (platform_machine == 's390x' and platform_python_implementation == 'CPython' and sys_platform == 'darwin') or (platform_machine == 'x86' and platform_python_implementation == 'CPython' and sys_platform == 'darwin') or (platform_machine == 'x86_64' and platform_python_implementation == 'CPython' and sys_platform == 'darwin') or (platform_machine == 'AMD64' and platform_python_implementation == 'CPython' and sys_platform == 'linux') or (platform_machine == 'ARM64' and platform_python_implementation == 'CPython' and sys_platform == 'linux') or (platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'linux') or (platform_machine == 'arm64' and platform_python_implementation == 'CPython' and sys_platform == 'linux') or (platform_machine == 'armv7l' and platform_python_implementation == 'CPython' and sys_platform == 'linux') or (platform_machine == 'i686' and platform_python_implementation == 'CPython' and sys_platform == 'linux') or (platform_machine == 'ppc64' and platform_python_implementation == 'CPython' and sys_platform == 'linux') or (platform_machine == 'ppc64le' and platform_python_implementation == 'CPython' and sys_platform == 'linux') or (platform_machine == 'riscv64' and platform_python_implementation == 'CPython' and sys_platform == 'linux') or (platform_machine == 'riscv64gc' and platform_python_implementation == 'CPython' and sys_platform == 'linux') or (platform_machine == 's390x' and platform_python_implementation == 'CPython' and sys_platform == 'linux') or (platform_machine == 'x86' and platform_python_implementation == 'CPython' and sys_platform == 'linux') or (platform_machine == 'x86_64' and platform_python_implementation == 'CPython' and sys_platform == 'linux') or (platform_machine == 'AMD64' and platform_python_implementation == 'CPython' and sys_platform == 'win32') or (platform_machine == 'ARM64' and platform_python_implementation == 'CPython' and sys_platform == 'win32') or (platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'win32') or (platform_machine == 'arm64' and platform_python_implementation == 'CPython' and sys_platform == 'win32') or (platform_machine == 'armv7l' and platform_python_implementation == 'CPython' and sys_platform == 'win32') or (platform_machine == 'i686' and platform_python_implementation == 'CPython' and sys_platform == 'win32') or (platform_machine == 'ppc64' and platform_python_implementation == 'CPython' and sys_platform == 'win32') or (platform_machine == 'ppc64le' and platform_python_implementation == 'CPython' and sys_platform == 'win32') or (platform_machine == 'riscv64' and platform_python_implementation == 'CPython' and sys_platform == 'win32') or (platform_machine == 'riscv64gc' and platform_python_implementation == 'CPython' and sys_platform == 'win32') or (platform_machine == 's390x' and platform_python_implementation == 'CPython' and sys_platform == 'win32') or (platform_machine == 'x86' and platform_python_implementation == 'CPython' and sys_platform == 'win32') or (platform_machine == 'x86_64' and platform_python_implementation == 'CPython' and sys_platform == 'win32')
Requires-Dist: quart==0.22.0 ; python_full_version < '3.13'
Requires-Dist: quart==0.23.1 ; python_full_version >= '3.13'
Requires-Dist: referencing==0.37.0
Requires-Dist: requests==2.34.2
Requires-Dist: requests-file==3.0.1
Requires-Dist: requests-oauthlib==2.0.0
Requires-Dist: requests-toolbelt==1.0.0
Requires-Dist: rpds-py==2026.6.3
Requires-Dist: setuptools==84.0.0
Requires-Dist: six==1.17.0
Requires-Dist: tenacity==9.1.4
Requires-Dist: textual==8.2.8
Requires-Dist: typing-extensions==4.16.0
Requires-Dist: typing-inspection==0.4.4
Requires-Dist: tzdata==2026.3 ; sys_platform == 'win32'
Requires-Dist: tzlocal==5.4.4
Requires-Dist: urllib3==2.7.0
Requires-Dist: wassima==2.1.4 ; sys_platform != 'emscripten'
Requires-Dist: werkzeug==3.1.8
Requires-Dist: winrt-runtime==3.2.1 ; sys_platform == 'win32'
Requires-Dist: winrt-windows-devices-bluetooth==3.2.1 ; sys_platform == 'win32'
Requires-Dist: winrt-windows-devices-bluetooth-advertisement==3.2.1 ; sys_platform == 'win32'
Requires-Dist: winrt-windows-devices-bluetooth-genericattributeprofile==3.2.1 ; sys_platform == 'win32'
Requires-Dist: winrt-windows-devices-enumeration==3.2.1 ; sys_platform == 'win32'
Requires-Dist: winrt-windows-devices-radios==3.2.1 ; sys_platform == 'win32'
Requires-Dist: winrt-windows-foundation==3.2.1 ; sys_platform == 'win32'
Requires-Dist: winrt-windows-foundation-collections==3.2.1 ; sys_platform == 'win32'
Requires-Dist: winrt-windows-storage-streams==3.2.1 ; sys_platform == 'win32'
Requires-Dist: wsproto==1.3.2
Requires-Dist: yarl==1.24.5
Requires-Dist: yeelight==0.7.16
Requires-Python: >=3.12, <4.0
Description-Content-Type: text/markdown

# Kaithem Automation

![AI generated banner of a tavern](kaithem/data/static/img/16x9/kaithem-tavern.avif)

![Linux](badges/linux.png)
![Python](badges/python.png)
![Ten Year Project](badges/ten-years.png)
![Offline First](badges/offline-first.png)
![GPLv3 Badge](badges/gpl-v3.png)
![Single Board Computer badge](badges/sbc.png)
![Pytest](badges/pytest.png)
![Ruff](badges/ruff.png)
![Ruff](badges/uv.png)


> Amidst the mists and fiercest frosts,\
> with stoutest wrists and loudest boasts,\
> He thrusts his fists against the posts,\
> And still insists he sees the ghosts.

Kaithem is Linux home/commercial automation server written in pure Python(3.10 and up). Resource usage is low enough to run well on the Raspberry Pi from an SD card

You automate things by directly writing python and HTML via a web IDE, or by using the built-in Chandler module, which is a full web-based lighting aud audio control board with a visual programming language.

## Screenshots 🏕️

![Cues List](screenshots/cues-list.avif)
![Preset Selector](screenshots/preset-selection.avif)
![Audio Mixer](screenshots/audio-mixer-mobile.avif)
![Logic Editor](screenshots/cue-logic-mobile.avif)
![Device Page](screenshots/device-page.avif)


See the barrel.css [demo](https://eternityforest.github.io/barrel.css/) for more themes

## Try it out in a Docker sandbox

With Docker's sandboxing, you won't be able to access any hardware,
but you can check out the UI, and if you want to set it up for real,
see the kaithem-scripts repo and the docker instructions.

You might see some warnings on the command line about the hardware it can't access, but it should eventually load.

--set-admin-password is NOT meant for normal use, and will always set the password to test-admin-password, it only exists for demos.

```bash
mkdir -p kaithem-test && docker run --rm -v ./kaithem-test:/app-home/ -p 8002:8002 -u "$(id -u):$(id -g)" -e USER=$(id -un) -e LOGNAME=$(id -un)  cooperskeep/kaithem:0.97.0 --set-admin-password test-admin-password
```

## Installation 🌲


>The careful text-books measure\
>  (Let all who build beware!)\
> The load, the shock, the pressure\
>  Material can bear.


Assuming you're on Debian or similar and have uv installed,
you can run it directly from UV tool.


See [Install dependencies](./kaithem/data/debian_setup_dependencies.sh) and [Runtime dependencies](./kaithem/data/debian_runtime_dependencies.sh)

```bash

# See links for the list of apt packages you'll need
sudo apt install ......

uv tool install --force kaithem

# Start it
kaithem

```


### System Configuration 🛠️

> So, when the buckled girder\
>  Lets down the grinding span,\
> The blame of loss, or murder,\
>  Is laid upon the man.\
>    Not on the Stuff — the Man!

Coming soon: Everything is in the process of being moved to docker.
Old scripts are broken on new Debian/Raspios, breaking changes are taking
an unsustainable amount of time and this project does not
have the resources for an interim solution.

## Dev Install 🖐️

Info for devs here on the wiki (https://github.com/EternityForest/KaithemAutomation/wiki/Development)

### Build dependencies
Dashbeard(https://github.com/EternityForest/Dashbeard) must be cloned into the same folder you cloned this repo into.

### Setup

First get all system dependencies as per the main install section.

```bash
uv sync

# Need to set up Rust if you don't already have everything
# All Rust code currently compiles to .wasm
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add wasm32-unknown-unknown

# Need install deps to build the frontend with npm
npm install

make build
```

### Docker Building

Clone this repo and dashbeard, do

```bash
cd docker
docker compose build
```

This will buid three images, a builder that creates the kaithem Wheel,
the runtime app image that would be used for production, and
a dev image that can be used to debug.

The dev image contains /workspaces/KaithemAutomation as the default working directory, so you can

```bash
KAITHEM_UID=$UID KAITHEM_GROUP=$GID KAITHEM_USER=$USR docker compose run kaithem-d
ev testing_server.py
```

Recent Changes 🕗
============
![AI generated banner of a water snake](kaithem/data/static/img/16x9/lightning-water-snake.avif)

> Good men, the last wave by, crying how bright\
> Their frail deeds might have danced in a green bay,\
> Rage, rage against the dying of the light.

(See [Full Changelog](kaithem/src/docs/changes.md))
