- /notify now accepts optional: emote, color, animation, sound - Backend passes custom properties to status response - Frontend handles custom sounds (chime, alert, success, etc.) - Added new sound effects: chime, alert, success - Updated documentation with full notify options - Added HA automation examples for doorbell and timer Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
214 lines
6.2 KiB
Markdown
214 lines
6.2 KiB
Markdown
# Kao
|
|
|
|
A minimalist system status monitor that uses ASCII emotes to display server health on an old phone.
|
|
|
|
-brightgreen>)
|
|
|
|
## 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.
|
|
|
|
## 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
|
|
- **Sound effects** — Optional audio cues for state changes (tap to enable)
|
|
- **Home Assistant ready** — Webhook endpoints for notifications and automation
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
# 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) |
|
|
| **docker** | Container health and restart loops |
|
|
|
|
## Configuration
|
|
|
|
Edit `config.json` to enable/disable detectors and set thresholds:
|
|
|
|
```json
|
|
{
|
|
"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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
curl -X POST http://localhost:5100/clear \
|
|
-d '{"id": "my_check"}'
|
|
```
|
|
|
|
## Home Assistant Integration
|
|
|
|
Add REST commands to your `configuration.yaml`:
|
|
|
|
```yaml
|
|
rest_command:
|
|
kao_notify:
|
|
url: "http://YOUR_SERVER:5100/notify"
|
|
method: POST
|
|
content_type: "application/json"
|
|
payload: >
|
|
{
|
|
"message": "{{ message | default('') }}",
|
|
"duration": {{ duration | default(5) }},
|
|
"emote": "{{ emote | default('') }}",
|
|
"color": "{{ color | default('') }}",
|
|
"animation": "{{ animation | default('') }}",
|
|
"sound": "{{ sound | default('') }}"
|
|
}
|
|
|
|
kao_sleep:
|
|
url: "http://YOUR_SERVER:5100/sleep"
|
|
method: POST
|
|
|
|
kao_wake:
|
|
url: "http://YOUR_SERVER:5100/wake"
|
|
method: POST
|
|
```
|
|
|
|
Use in automations:
|
|
|
|
```yaml
|
|
automation:
|
|
- alias: "Doorbell Notification"
|
|
trigger:
|
|
platform: state
|
|
entity_id: binary_sensor.doorbell
|
|
to: "on"
|
|
action:
|
|
service: rest_command.kao_notify
|
|
data:
|
|
message: "Someone at the door"
|
|
duration: 10
|
|
emote: "( °o°)"
|
|
color: "#FF9900"
|
|
sound: "chime"
|
|
|
|
- alias: "Timer Complete"
|
|
trigger:
|
|
platform: event
|
|
event_type: timer.finished
|
|
action:
|
|
service: rest_command.kao_notify
|
|
data:
|
|
message: "Timer done!"
|
|
emote: "\\(^o^)/"
|
|
animation: "celebrating"
|
|
sound: "success"
|
|
|
|
- alias: "Kao Sleep at Bedtime"
|
|
trigger:
|
|
platform: time
|
|
at: "23:00:00"
|
|
action:
|
|
service: rest_command.kao_sleep
|
|
|
|
- alias: "Kao Wake in Morning"
|
|
trigger:
|
|
platform: time
|
|
at: "07:00:00"
|
|
action:
|
|
service: rest_command.kao_wake
|
|
```
|
|
|
|
**Notify options:**
|
|
- `emote`: Any ASCII emote (e.g., `( °o°)`, `\\(^o^)/`)
|
|
- `color`: Hex color (e.g., `#FF9900`)
|
|
- `animation`: `breathing`, `shaking`, `popping`, `celebrating`, `floating`, `bouncing`, `swaying`
|
|
- `sound`: `chime`, `alert`, `warning`, `critical`, `success`, `notify`, `none`
|
|
|
|
## 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 |
|
|
| `/notify` | POST | Simple notification `{"message": "", "duration": 5}` |
|
|
| `/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 `( ᵕ.ᵕ)` for a second or two
|
|
- Celebrates `\(^o^)/` when recovering from warnings
|
|
- Each face has its own animation (floating, bouncing, swaying)
|
|
- Reacts when tapped `( °o°)` and shows version info
|
|
|
|
**Sound effects** (tap screen to enable, or use `?sound=on`):
|
|
- Warning: soft double-beep
|
|
- Critical: urgent descending tone
|
|
- Notify: gentle ping
|
|
- Recovery: happy ascending chirp
|
|
|
|
## License
|
|
|
|
MIT
|