Spencer Grimes 66c9790d2b Bump to v1.1.0, enable network and docker detectors
- Version bump reflecting new features (sounds, tap reaction, docker detector)
- Rename title to Kao
- Enable network and docker detectors by default

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 20:57:18 -06:00
2026-02-03 17:42:34 -06:00

Kao

A minimalist system status monitor that uses ASCII emotes to display server health on an old phone.

Status: Optimal

Why?

Turn an old phone (with its OLED screen) into a glanceable ambient display for your home server. Instead of graphs and numbers, see a happy face ( ^_^) when things are good, and a worried face ( o_o) when they're not.

TODO

  • Figure out way to update installation in /opt/kao when git updates. Maybe run a git pull on service startup?
  • Think about ways of implementing noises.

Features

  • OLED-optimized — Pure black background, saves battery
  • Glanceable — Know your server's status from across the room
  • Extensible — Add custom detectors for any metric
  • Personality — Rotating expressions, celebration animations, sleep mode
  • Home Assistant ready — Webhook endpoints for automation

Quick Start

# Clone and setup
git clone https://github.com/yourusername/kao.git
cd kao
python -m venv venv
source venv/bin/activate  # Windows: .\venv\Scripts\activate
pip install -r requirements.txt

# Run everything
python kao.py

Open http://localhost:5100 on your phone (use Fully Kiosk Browser for best results).

Status Faces

State Emote Meaning
Optimal ( ^_^) All systems healthy
Warning ( o_o) Something needs attention
Critical ( x_x) Immediate action required
Notify ( 'o') Transient notification
Sleeping ( -_-)zzZ Sleep mode active
Disconnected ( ?.?) Can't reach server

Built-in Detectors

Detector Monitors
disk_space Disk usage on all drives
cpu CPU utilization
memory RAM usage
service Whether processes are running
network Host reachability (ping)

Configuration

Edit config.json to enable/disable detectors and set thresholds:

{
	"aggregator_url": "http://localhost:5100",
	"detectors": [
		{
			"name": "disk_space",
			"enabled": true,
			"script": "detectors/disk_space.py",
			"env": {
				"CHECK_INTERVAL": "300",
				"THRESHOLD_WARNING": "85",
				"THRESHOLD_CRITICAL": "95"
			}
		}
	]
}

Custom Detectors

Create your own detector by POSTing events to the aggregator:

curl -X POST http://localhost:5100/event \
  -H "Content-Type: application/json" \
  -d '{"id": "my_check", "priority": 2, "message": "Something is wrong", "ttl": 120}'
  • id — Unique identifier for this event
  • priority — 1 (critical), 2 (warning), 3 (notify), 4 (optimal)
  • message — What to display
  • ttl — Auto-expire after N seconds (for heartbeat pattern)

Clear an event:

curl -X POST http://localhost:5100/clear \
  -d '{"id": "my_check"}'

Home Assistant Integration

Add webhook commands to your Home Assistant config:

rest_command:
  sentry_sleep:
    url: "http://YOUR_SERVER:5100/sleep"
    method: POST
  sentry_wake:
    url: "http://YOUR_SERVER:5100/wake"
    method: POST

Trigger from automations:

automation:
  - alias: "Sentry Sleep at Bedtime"
    trigger:
      platform: time
      at: "23:00:00"
    action:
      service: rest_command.sentry_sleep

  - alias: "Sentry Wake in Morning"
    trigger:
      platform: time
      at: "07:00:00"
    action:
      service: rest_command.sentry_wake

API Reference

Endpoint Method Description
/ GET Web UI
/status GET Current state as JSON
/events GET List all active events
/event POST Register an event
/clear POST Clear an event by ID
/sleep POST Enter sleep mode
/wake POST Exit sleep mode

Personality

The emote has personality! In optimal state it:

  • Rotates through happy faces every 5 minutes
  • Occasionally winks ( -_^) or blinks ( ᵕ.ᵕ)
  • Celebrates \(^o^)/ when recovering from warnings
  • Each face has its own animation (floating, bouncing, swaying)

License

MIT

Description
No description provided
Readme 333 KiB
Languages
Python 73.6%
HTML 19.4%
Shell 7%