feat: add Dockerfile, dry-run mode, and documentation
- Add Dockerfile with multi-stage build using UV - Add --dry-run CLI flag to log metrics instead of submitting - Add comprehensive README with usage and metrics documentation - Fix ruff linter warnings - Add uv.lock for reproducible builds
This commit is contained in:
199
README.md
199
README.md
@@ -0,0 +1,199 @@
|
||||
# Datacat
|
||||
|
||||
Collect metrics from Whisker Litter Robot devices and submit to Datadog.
|
||||
|
||||
Datacat connects to the Whisker API (used by Litter-Robot and Feeder-Robot devices) and periodically collects metrics, submitting them to Datadog for monitoring and alerting.
|
||||
|
||||
## Supported Devices
|
||||
|
||||
- **Litter-Robot 3** - Original connected litter box
|
||||
- **Litter-Robot 4** - Newer model with additional sensors
|
||||
- **Feeder-Robot** - Automatic pet feeder
|
||||
|
||||
## Features
|
||||
|
||||
- Collects metrics from all connected robots every 2 minutes (configurable)
|
||||
- Submits metrics to Datadog via DogStatsD
|
||||
- Emits Datadog events for state changes (drawer full, offline, errors)
|
||||
- Supports pet profile metrics (weight, health status)
|
||||
- Dry-run mode for testing without submitting metrics
|
||||
- Configuration via environment variables or YAML file
|
||||
|
||||
## Installation
|
||||
|
||||
### Using UV (recommended)
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone https://github.com/yourusername/datacat.git
|
||||
cd datacat
|
||||
|
||||
# Install with UV
|
||||
uv sync
|
||||
|
||||
# Run
|
||||
uv run python -m datacat
|
||||
```
|
||||
|
||||
### Using pip
|
||||
|
||||
```bash
|
||||
pip install .
|
||||
datacat
|
||||
```
|
||||
|
||||
### Using Docker
|
||||
|
||||
```bash
|
||||
# Build the image
|
||||
docker build -t datacat .
|
||||
|
||||
# Run with environment variables
|
||||
docker run -d \
|
||||
-e WHISKER_USERNAME=your-email@example.com \
|
||||
-e WHISKER_PASSWORD=your-password \
|
||||
-e DATADOG_API_KEY=your-api-key \
|
||||
datacat
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Datacat can be configured via environment variables, a YAML config file, or both. Environment variables take precedence over config file values.
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description | Required |
|
||||
|----------|-------------|----------|
|
||||
| `WHISKER_USERNAME` | Whisker account email | Yes |
|
||||
| `WHISKER_PASSWORD` | Whisker account password | Yes |
|
||||
| `DATADOG_API_KEY` | Datadog API key | Yes |
|
||||
| `DATADOG_APP_KEY` | Datadog application key | No |
|
||||
| `DATADOG_SITE` | Datadog site (default: `datadoghq.com`) | No |
|
||||
| `DATACAT_POLL_INTERVAL` | Polling interval in seconds (default: `120`) | No |
|
||||
| `DATACAT_INCLUDE_PETS` | Include pet metrics (default: `true`) | No |
|
||||
| `DATACAT_EMIT_EVENTS` | Emit Datadog events (default: `true`) | No |
|
||||
| `DATACAT_METRIC_PREFIX` | Metric prefix (default: `litterrobot`) | No |
|
||||
| `DATACAT_CONFIG_FILE` | Path to YAML config file | No |
|
||||
|
||||
### Config File (YAML)
|
||||
|
||||
```yaml
|
||||
whisker:
|
||||
username: "your-email@example.com"
|
||||
password: "your-password"
|
||||
|
||||
datadog:
|
||||
api_key: "your-datadog-api-key"
|
||||
app_key: "your-datadog-app-key" # optional
|
||||
site: "datadoghq.com"
|
||||
metric_prefix: "litterrobot"
|
||||
|
||||
collector:
|
||||
poll_interval_seconds: 120
|
||||
include_pets: true
|
||||
emit_events: true
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Run continuously (default)
|
||||
datacat
|
||||
|
||||
# Run with config file
|
||||
datacat -c config.yaml
|
||||
|
||||
# Run once and exit
|
||||
datacat --once
|
||||
|
||||
# Dry run (log metrics instead of submitting)
|
||||
datacat --dry-run
|
||||
|
||||
# Verbose logging
|
||||
datacat -v
|
||||
```
|
||||
|
||||
## Metrics
|
||||
|
||||
### Litter Robot Metrics (LR3 & LR4)
|
||||
|
||||
| Metric | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| `litterrobot.online` | Gauge | 1 if online, 0 if offline |
|
||||
| `litterrobot.waste_drawer_level` | Gauge | Drawer fullness (0-100%) |
|
||||
| `litterrobot.cycle_count` | Gauge | Cycles since last reset |
|
||||
| `litterrobot.cycle_capacity` | Gauge | Max cycles before full |
|
||||
| `litterrobot.waste_drawer_full` | Gauge | 1 if drawer is full |
|
||||
| `litterrobot.is_sleeping` | Gauge | 1 if in sleep mode |
|
||||
| `litterrobot.wait_time_minutes` | Gauge | Clean cycle delay |
|
||||
| `litterrobot.night_light_enabled` | Gauge | Night light status |
|
||||
| `litterrobot.panel_lock_enabled` | Gauge | Panel lock status |
|
||||
| `litterrobot.power_status` | Gauge | 2=AC, 1=DC, 0=NC |
|
||||
|
||||
### Litter Robot 4 Additional Metrics
|
||||
|
||||
| Metric | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| `litterrobot.litter_level` | Gauge | Litter level (0-100%) |
|
||||
| `litterrobot.pet_weight` | Gauge | Last recorded weight (lbs) |
|
||||
| `litterrobot.scoops_saved` | Gauge | Environmental counter |
|
||||
| `litterrobot.wifi_rssi` | Gauge | WiFi signal strength |
|
||||
| `litterrobot.night_light_brightness` | Gauge | Brightness level |
|
||||
| `litterrobot.hopper_enabled` | Gauge | Hopper status |
|
||||
|
||||
### Feeder Robot Metrics
|
||||
|
||||
| Metric | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| `feederrobot.food_level` | Gauge | Food level (0-100%) |
|
||||
| `feederrobot.gravity_mode_enabled` | Gauge | Gravity mode status |
|
||||
| `feederrobot.meal_insert_size` | Gauge | Meal insert size (cups) |
|
||||
|
||||
### Pet Metrics
|
||||
|
||||
| Metric | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| `litterrobot.pet.weight` | Gauge | Pet weight (lbs) |
|
||||
| `litterrobot.pet.is_healthy` | Gauge | Health status |
|
||||
| `litterrobot.pet.is_active` | Gauge | Active status |
|
||||
| `litterrobot.pet.age` | Gauge | Pet age |
|
||||
|
||||
### Tags
|
||||
|
||||
All metrics include the following tags:
|
||||
|
||||
- `robot_id` - Unique robot identifier
|
||||
- `robot_serial` - Robot serial number
|
||||
- `robot_name` - User-defined robot name
|
||||
- `robot_model` - Robot model (Litter-Robot 3, Litter-Robot 4, Feeder-Robot)
|
||||
- `status` - Current robot status (for litter robots)
|
||||
|
||||
## Events
|
||||
|
||||
Datacat emits Datadog events for important state changes:
|
||||
|
||||
- **Robot goes offline/online** - Warning/Success event
|
||||
- **Waste drawer full** - Warning event
|
||||
- **Robot errors** (sensor faults, pinch detect, etc.) - Error event
|
||||
- **Food level low** (Feeder Robot, <20%) - Warning event
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
# Install with dev dependencies
|
||||
uv sync
|
||||
|
||||
# Run linter
|
||||
uv run ruff check src/
|
||||
|
||||
# Run formatter
|
||||
uv run ruff format src/
|
||||
```
|
||||
|
||||
## Disclaimer
|
||||
|
||||
This project uses the unofficial [pylitterbot](https://github.com/natekspencer/pylitterbot) library to communicate with the Whisker API. The API is reverse-engineered and may break at any time. Use at your own risk.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
Reference in New Issue
Block a user