{"id":46730347,"url":"https://github.com/astrostl/pentameter","last_synced_at":"2026-04-01T23:55:22.555Z","repository":{"id":302018078,"uuid":"1010960183","full_name":"astrostl/pentameter","owner":"astrostl","description":"Prometheus metric exporter for Pentair IntelliCenter (Prometheus with Grafana dashboards included). Vibe coded in Go.","archived":false,"fork":false,"pushed_at":"2026-02-10T05:06:50.000Z","size":1231,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-02-10T10:36:11.651Z","etag":null,"topics":["exporter","go","grafana","home-automation","intellicenter","iot","metrics","monitoring","pentair","pool","prometheus"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/astrostl.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"astrostl","custom":["https://paypal.me/astrostl","https://cash.app/$astrostl","http://venmo.com/astrostl"]}},"created_at":"2025-06-30T05:17:06.000Z","updated_at":"2026-02-10T05:06:46.000Z","dependencies_parsed_at":"2025-07-27T05:12:15.466Z","dependency_job_id":"9caea0cb-b374-4644-be5b-cce7f833a478","html_url":"https://github.com/astrostl/pentameter","commit_stats":null,"previous_names":["astrostl/pentameter"],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/astrostl/pentameter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astrostl%2Fpentameter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astrostl%2Fpentameter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astrostl%2Fpentameter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astrostl%2Fpentameter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/astrostl","download_url":"https://codeload.github.com/astrostl/pentameter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astrostl%2Fpentameter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30299884,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-09T14:33:48.460Z","status":"ssl_error","status_checked_at":"2026-03-09T14:33:48.027Z","response_time":61,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["exporter","go","grafana","home-automation","intellicenter","iot","metrics","monitoring","pentair","pool","prometheus"],"created_at":"2026-03-09T15:04:13.482Z","updated_at":"2026-03-09T15:04:14.342Z","avatar_url":"https://github.com/astrostl.png","language":"Go","funding_links":["https://github.com/sponsors/astrostl","https://paypal.me/astrostl","https://cash.app/$astrostl","http://venmo.com/astrostl"],"categories":[],"sub_categories":[],"readme":"# Pentameter - Pentair IntelliCenter Metrics \u0026 Dashboarding\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/astrostl/pentameter)](https://goreportcard.com/report/github.com/astrostl/pentameter)\n\n\u003e **⚠️ AI-Generated Code Warning**: This project was \"vibe coded\" using generative AI and should be thoroughly reviewed before use. It comes with no warranty or guarantee of functionality, security, or reliability.\n\n![Pentameter Grafana Dashboard](pentameter.png?v=1)\n\nPentameter is a Prometheus exporter for Pentair IntelliCenter pool controllers that connects via WebSocket and exposes pool equipment data as Prometheus metrics with pre-configured Grafana dashboards for visualization.\n\n## Features\n\n### Real-Time Data Collection\n- **Temperature Monitoring**: Pool, spa, and outdoor air sensors\n- **Pump Monitoring**: Variable speed RPM and flow rates\n- **Equipment Status**: Circuit and feature on/off states\n- **Connection Health**: Automatic failure detection and recovery\n- **Auto-Discovery**: Finds IntelliCenter automatically via mDNS (multicast DNS)\n\n### Data Export and Visualization\n- **Prometheus Metrics**: Standard format compatible with any monitoring tool\n- **Pre-configured Dashboards**: Grafana dashboards with automatic provisioning\n- **Kiosk Mode**: Clean displays for dedicated monitoring screens\n- **Historical Trends**: Long-term data visualization and analysis\n\n### Smart Features\n- **Intelligent Filtering**: Focus on meaningful equipment vs virtual controls\n- **User-Controlled Feature Visibility**: Respects IntelliCenter's \"Show as Feature\" settings\n- **Graceful Degradation**: Handle missing sensors without errors\n- **Browser Compatibility**: Standard metrics endpoint works everywhere\n\n### Technical Features\n- WebSocket connection to IntelliCenter controllers\n- Automatic IntelliCenter discovery via mDNS (finds `pentair.local` on network)\n- Listen mode for real-time equipment change monitoring and debugging\n- Robust connection management with exponential backoff retry logic\n- Health checks with automatic reconnection on failures\n- Configurable via command line flags or environment variables\n- Health check endpoint\n\n## Architecture Overview\n\nPentameter connects to IntelliCenter controllers via WebSocket and transforms pool data into standard Prometheus metrics for monitoring and alerting.\n\n### System Components\n\n1. **Go Service** - Core monitoring service\n   - WebSocket client for IntelliCenter communication\n   - Prometheus metrics endpoint (`/metrics`)\n   - Health checks and connection management\n\n2. **IntelliCenter Interface**\n   - WebSocket connection (default port 6680)\n   - JSON message protocol using GetParamList API\n   - Exponential backoff retry with health checks\n   - **Request/response polling** - API does not support push notifications (verified 2025-11-08)\n   - Persistent connection with configurable poll intervals (2s for listen mode, 60s default)\n\n3. **Metrics Export**\n   - HTTP server (default port 8080)\n   - Standard Prometheus format\n   - Compatible with any monitoring tool\n\n4. **Docker Deployment**\n   - Multi-stage builds with scratch base images (~12MB)\n   - Docker Compose orchestration\n   - Prometheus and Grafana included\n\n### Technology Stack\n\n- **Language:** Go with standard library HTTP server\n- **WebSocket:** `github.com/gorilla/websocket`\n- **Metrics:** `github.com/prometheus/client_golang`\n- **Build:** Makefile with Docker integration\n- **Deployment:** Docker Compose with restart policies\n\n## Installation Options\n\nPentameter offers multiple installation methods to suit different deployment preferences:\n\n| Method | Platform | Use Case | Features |\n|--------|----------|-----------|----------|\n| **Homebrew** | macOS | Single exporter, integrate with existing monitoring | Instant install, pre-built binaries |\n| **Docker Compose** | All platforms | Complete monitoring stack | Grafana dashboards, Prometheus included |\n| **Docker** | All platforms | Container deployment | Lightweight, configurable |\n| **Go Install** | All platforms | Go developers, build from source | Latest source, Go toolchain integration |\n| **Source Build** | All platforms | Development, customization | Full control, latest changes |\n\n## Quick Start\n\n### Option 1: Homebrew (macOS) - Instant Installation\n\n**Recommended for macOS users who want just the metrics exporter:**\n\n```bash\n# One-line install (automatically adds tap)\nbrew install astrostl/pentameter/pentameter\n\n# Start the exporter (auto-discovers IntelliCenter)\npentameter\n\n# Or manually specify IP address if needed\nexport PENTAMETER_IC_IP=192.168.1.100\npentameter\n```\n\n**Alternative two-step install:**\n```bash\n# Add the tap (one time setup)\nbrew tap astrostl/pentameter https://github.com/astrostl/pentameter\nbrew install pentameter\n```\n\n✅ **Instant installation** - No build time, no dependencies  \n✅ **Pre-built binaries** - Intel and Apple Silicon supported  \n✅ **Automatic updates** - `brew upgrade pentameter`  \n\nMetrics are available at `http://localhost:8080/metrics`\n\n*For complete monitoring with Grafana dashboards, use the Docker Compose option below.*\n\n### Option 2: Go Install - Build from Source\n\n**Recommended for Go developers who want to build from source:**\n\n```bash\n# Install latest version\ngo install github.com/astrostl/pentameter@latest\n\n# Or install specific version\ngo install github.com/astrostl/pentameter@v0.2.2\n\n# Start the exporter (auto-discovers IntelliCenter)\npentameter\n\n# Or manually specify IP address if needed\nexport PENTAMETER_IC_IP=192.168.1.100\npentameter\n```\n\n✅ **Latest source** - Always up-to-date with repository  \n✅ **Go toolchain integration** - Uses your existing Go installation  \n✅ **All platforms** - Works wherever Go runs  \n\n**Note**: Version information (`pentameter --version`) will show as \"dev\" since go install doesn't include build-time version injection.\n\nMetrics are available at `http://localhost:8080/metrics`\n\n### Option 3: Docker Compose - Complete Monitoring Stack\n\n**Recommended for full monitoring setup with Grafana dashboards:**\n\n```bash\n# Clone the repository (includes all config files)\ngit clone https://github.com/astrostl/pentameter.git\ncd pentameter\n\n# Start the complete monitoring stack (auto-discovers IntelliCenter)\ndocker compose up -d\n\n# Or manually configure IP if auto-discovery doesn't work\ncp .env.example .env\n# Edit .env and set your PENTAMETER_IC_IP\ndocker compose up -d\n```\n\n✅ **Complete monitoring** - Pentameter + Prometheus + Grafana  \n✅ **Pre-configured dashboards** - Ready-to-use Grafana setup  \n✅ **No build time** - Uses published DockerHub images  \n✅ **All platforms** - Works on macOS, Linux, Windows  \n\n**Access Points:**\n- **Grafana Dashboard**: `http://localhost:3000/d/pentameter/`\n- **Metrics**: `http://localhost:8080/metrics`  \n- **Prometheus**: `http://localhost:9090`\n\n## Endpoints\n\n- **Metrics**: `http://HOSTNAME:8080/metrics` - Prometheus metrics\n- **Health**: `http://HOSTNAME:8080/health` - Health check\n- **Prometheus**: `http://HOSTNAME:9090` - Prometheus web interface\n- **Grafana**: `http://HOSTNAME:3000/d/pentameter/` - Grafana dashboards (no login required)\n- **Kiosk Mode**: `http://HOSTNAME:3000/d/pentameter/?kiosk` - Clean dashboard display\n\n## Feature Visibility Control\n\nPentameter respects IntelliCenter's \"Show as Feature\" settings to avoid duplicate controls and maintain clean dashboards.\n\n### How It Works\n\nIntelliCenter allows users to control whether features appear in the interface through a \"Show as Feature\" checkbox in the Feature Circuits configuration. Pentameter automatically detects and respects this setting.\n\n**Common Use Case**: Pool heating equipment often appears as both:\n- **Feature**: User control (e.g., \"Spa Heat\" - enable/disable heating)  \n- **Thermal Equipment**: Actual equipment status (e.g., \"Spa Heater\" - heating/idle/cooling)\n\nThis creates duplication in monitoring dashboards where both the user control and equipment status are shown.\n\n### User Control\n\nUsers can eliminate this duplication through their IntelliCenter interface:\n\n1. **Access IntelliCenter** → Settings → Feature Circuits\n2. **Select the feature** (e.g., \"Spa Heat\")\n3. **Uncheck \"Show as Feature\"** to hide the user control\n4. **Keep thermal equipment monitoring** for actual operational status\n\n### Technical Implementation\n\nPentameter uses IntelliCenter's `SHOMNU` parameter to detect the \"Show as Feature\" setting:\n\n- **Show as Feature: YES** → Feature appears in `feature_status` metrics\n- **Show as Feature: NO** → Feature is automatically hidden from metrics\n\n### Benefits\n\n- **User-Controlled**: No hardcoded logic - users decide what to show\n- **Universal**: Works with any equipment configuration and naming\n- **Clean Dashboards**: Eliminates duplicate controls when desired\n- **Flexible**: Users can show both if they want different information\n\n### Example Scenarios\n\n**Scenario 1: Show Both Controls**\n- `feature_status{name=\"Spa Heat\"}` → User enable/disable control\n- `thermal_status{name=\"Spa Heater\"}` → Equipment operational status\n- **Use Case**: Monitor both user intent and equipment response\n\n**Scenario 2: Show Equipment Only**  \n- User disables \"Show as Feature\" for \"Spa Heat\"\n- Only `thermal_status{name=\"Spa Heater\"}` appears\n- **Use Case**: Focus on equipment operation, control via IntelliCenter\n\nThis approach ensures Pentameter works universally across different pool configurations while giving users full control over their monitoring interface.\n\n## Configuration\n\nAll configuration options can be set via command line flags or environment variables:\n\n| Flag | Environment Variable | Default | Description |\n|------|---------------------|---------|-------------|\n| `--ic-ip` | `PENTAMETER_IC_IP` | (auto-discover) | IntelliCenter IP address (optional, auto-discovers via mDNS if not provided) |\n| `--ic-port` | `PENTAMETER_IC_PORT` | `6680` | IntelliCenter WebSocket port |\n| `--http-port` | `PENTAMETER_HTTP_PORT` | `8080` | HTTP server port for metrics |\n| `--interval` | `PENTAMETER_INTERVAL` | `60` | Polling interval in seconds (minimum 5s) |\n| `--listen` | `PENTAMETER_LISTEN` | `false` | Enable live event monitoring mode |\n| `--discover` | N/A | N/A | Discover IntelliCenter IP address and exit |\n| `--version` | N/A | N/A | Show version information |\n\n### Auto-Discovery\n\nPentameter can automatically discover your IntelliCenter on the local network using mDNS (multicast DNS). The IntelliCenter broadcasts itself as `pentair.local` on the network.\n\n**How it works:**\n- When `--ic-ip` is not provided, pentameter automatically searches for `pentair.local` via mDNS\n- Discovery timeout is 60 seconds with progress indicators every 2 seconds\n- Works on most home networks without additional configuration\n- **Docker support**: Auto-discovery works in Docker using host networking (enabled by default)\n- **Automatic re-discovery**: If the IntelliCenter's IP changes (DHCP renewal, router reboot), pentameter automatically re-discovers it after 3 failed connection attempts\n\n**Test discovery:**\n```bash\n# Test auto-discovery and show IP address\npentameter --discover\n\n# Example output:\n# IntelliCenter discovered at: 192.168.1.100\n```\n\n**Manual IP specification:**\n```bash\n# Bypass auto-discovery and use specific IP\npentameter --ic-ip 192.168.1.100\n\n# Or via environment variable\nexport PENTAMETER_IC_IP=192.168.1.100\npentameter\n```\n\n**Docker auto-discovery:**\n```bash\n# Docker Compose with auto-discovery (default behavior)\ndocker compose up -d\n\n# Docker run with auto-discovery\ndocker run -d --name pentameter --network host astrostl/pentameter:latest\n```\n\n**Troubleshooting:**\n- If auto-discovery fails, pentameter provides clear guidance on using the `--ic-ip` flag\n- Check that your IntelliCenter is on the same network\n- Some networks may block mDNS multicast traffic (port 5353/UDP)\n- Firewalls may need to allow multicast traffic to 224.0.0.251:5353\n- **Docker**: Host networking is required for mDNS (enabled by default in docker-compose.yml)\n- Use `--ic-ip` flag to manually specify IP address if auto-discovery doesn't work\n\n## Listen Mode - Live Equipment Monitoring\n\nListen mode provides real-time event logging for pool equipment changes using a hybrid push + poll architecture. Perfect for debugging, discovering equipment, and monitoring activity.\n\n### Features\n\n- **Hybrid Push + Poll**: Real-time push notifications for instant updates, plus periodic polling (default 60s) to catch equipment that doesn't push (like pump RPM changes)\n- **Source Identification**: Events prefixed with `PUSH:` or `POLL:` to distinguish real-time vs polled updates\n- **Initial State Discovery**: Shows all equipment and current state on startup\n- **Unknown Equipment Detection**: Automatically discovers equipment types not specifically implemented (valves, sensors, remotes, etc.)\n- **Clean Output**: Reports `POLL: [no changes]` when poll cycles find no updates\n\n### Usage\n\n```bash\n# Basic listen mode (60-second poll interval)\npentameter --ic-ip 192.168.1.100 --listen\n\n# Custom polling interval (10 seconds)\npentameter --ic-ip 192.168.1.100 --listen --interval 10\n\n# Via environment variable\nexport PENTAMETER_IC_IP=192.168.1.100\nexport PENTAMETER_LISTEN=true\npentameter\n```\n\n### Example Output\n\n```\n2025/11/28 18:51:15 Fetching initial equipment state...\n2025/11/28 18:51:15 POLL: Pool temperature detected: 22.0°F\n2025/11/28 18:51:15 POLL: Spa temperature detected: 95.0°F\n2025/11/28 18:51:15 POLL: VS detected: 3000 RPM\n2025/11/28 18:51:16 POLL: Pool detected: ON\n2025/11/28 18:51:16 POLL: Spa Heater detected: heating\n2025/11/28 18:51:35 Listening for real-time changes (Ctrl+C to stop)...\n2025/11/28 18:52:04 PUSH: Spa temp=97°F setpoint=98°F htmode=1 status=ON\n2025/11/28 18:53:35 POLL: Spa temperature changed: 95.0°F → 96.0°F\n2025/11/28 18:53:35 POLL: VS changed: 3000 → 2500 RPM\n2025/11/28 18:54:35 POLL: [no changes]\n```\n\n### Use Cases\n\n- **Debugging**: Watch equipment respond to commands in real-time via `PUSH:` events\n- **Discovery**: Find all equipment in your IntelliCenter, including unknown types\n- **Monitoring**: Track circuit activation, temperature changes, and pump speed adjustments\n- **Testing**: Verify equipment changes are being reported correctly\n- **Pump Tracking**: Monitor pump RPM changes (not pushed by IntelliCenter, requires polling)\n\n### Equipment Tracked\n\nListen mode monitors all equipment types:\n- **Water \u0026 Air Temperatures**: Bodies and sensors\n- **Circuits**: Lights, pumps, valves, cleaners\n- **Features**: Spa jets, fountains, automation features\n- **Thermal Equipment**: Heaters and heat pumps with operational states\n- **Pumps**: Variable speed RPM changes (via polling)\n- **Unknown Equipment**: Any equipment type not specifically implemented\n\n## Usage\n\n### Command Line Flags\n```bash\ngo run main.go --ic-ip 192.168.192.168 --ic-port 6680 --http-port 8080 --interval 60\n```\n\n### Environment Variables\n```bash\nexport PENTAMETER_IC_IP=192.168.192.168\nexport PENTAMETER_IC_PORT=6680\nexport PENTAMETER_HTTP_PORT=8080\nexport PENTAMETER_INTERVAL=60\ngo run main.go\n```\n\n### Mixed Configuration\n```bash\n# Use environment for IP, override HTTP port via flag\nexport PENTAMETER_IC_IP=192.168.192.168\ngo run main.go --http-port 9090\n```\n\n## Metrics Reference\n\n### Temperature Metrics\n```prometheus\n# Water temperatures\nwater_temperature_fahrenheit{body=\"POOL\",name=\"Pool\"} 87\nwater_temperature_fahrenheit{body=\"SPA\",name=\"Spa\"} 84\n\n# Air temperature (optional)\nair_temperature_fahrenheit{sensor=\"AIR\",name=\"Air Sensor\"} 73\n```\n\n### Equipment Metrics\n```prometheus\n# Pump speeds and flow\npump_rpm{pump=\"PMP01\",name=\"VS\"} 3000\npump_rpm{pump=\"PMP02\",name=\"pool\"} 2450\n\n# Circuit status (1=on, 0=off)\ncircuit_status{circuit=\"C0001\",name=\"Spa\",type=\"SPA\"} 1\ncircuit_status{circuit=\"C0003\",name=\"Pool Light\",type=\"LIGHT\"} 0\ncircuit_status{circuit=\"FTR01\",name=\"Spa Heat\",type=\"GENERIC\"} 0\n```\n\n### Thermal Equipment Metrics\n\n**thermal_status Values - Pentameter's Interpretation Layer:**\n\n**Derived from IntelliCenter Data:**\n- **0 (off)**: Based on HTSRC=\"00000\" (no heater assigned)\n- **1 (heating)**: Based on HTMODE=1 or HTMODE=4 (active heating demand)\n\n**Pentameter's Logical Inference:**\n- **2 (idle)**: Pentameter's interpretation of HTMODE=0 + HTSRC≠\"00000\" (heater assigned but not demanded)\n- **3 (cooling)**: Pentameter's interpretation of HTMODE=9 (heat pump cooling mode)\n\n**IntelliCenter Raw Data:**\n- **HTMODE**: 0, 1, 4, 9 (heating/cooling demand states)\n- **HTSRC**: \"00000\" or heater ID (assignment status)\n\nThe thermal_status metric translates IntelliCenter's raw operational data into human-friendly states. The \"idle\" and \"cooling\" concepts are pentameter's abstractions - IntelliCenter itself only provides demand and assignment status.\n\n```prometheus\n# Thermal equipment operational status (see interpretation above)\nthermal_status{heater=\"H0002\",name=\"Spa Heater\",subtyp=\"GENERIC\"} 2\n\n# Temperature setpoints (Fahrenheit)\nthermal_low_setpoint_fahrenheit{heater=\"H0002\",name=\"Spa Heater\",subtyp=\"GENERIC\"} 95\nthermal_high_setpoint_fahrenheit{heater=\"H0001\",name=\"Pool Heat Pump\",subtyp=\"ULTRA\"} 88\n```\n\n**Setpoint Display Logic:**\n- **Heatpoint (low setpoint)**: Always shown for any assigned heater\n- **Coolpoint (high setpoint)**: Only shown when \u003c 100°F and equipment is idle or cooling\n- **100°F Threshold**: Filters out impractical cooling setpoints from heating-only equipment\n\n### System Health Metrics\n```prometheus\n# Connection monitoring\nintellicenter_connection_failure 0\nintellicenter_last_refresh_timestamp_seconds 1751302319\n\n# Equipment connection status (1=connected, 0=disconnected)\nthermal_status{heater=\"H0001\",name=\"Pool Heat Pump\",subtyp=\"ULTRA\"} 0\npump_status{pump=\"PMP01\",name=\"VS\",subtyp=\"PUMP\"} 1\n```\n\n**Connection Status Behavior:**\n- **Service Level**: `intellicenter_connection_failure` tracks WebSocket connectivity to IntelliCenter\n- **Equipment Level**: Individual equipment metrics disappear when equipment is offline/disconnected\n- **Graceful Degradation**: Missing equipment doesn't cause service failures\n- **Automatic Recovery**: Equipment metrics reappear when equipment comes back online\n\n### Data Sources\n\n| Metric Type | Source | API Query | Parameter |\n|-------------|--------|-----------|------------|\n| Water Temperature | Pool/Spa bodies | OBJTYP=BODY | TEMP |\n| Air Temperature | Outdoor sensor | Object _A135 | PROBE |\n| Pump RPM | Variable speed pumps | OBJTYP=PUMP | RPM |\n| Circuit Status | Equipment controls | OBJTYP=CIRCUIT | STATUS |\n| Thermal Status | Heating equipment | OBJTYP=HEATER | STATUS + HTMODE |\n| Thermal Setpoints | Pool/Spa bodies | OBJTYP=BODY | LOTMP, HITMP |\n| Connection Health | Internal monitoring | N/A | WebSocket health checks |\n| Equipment Health | Individual equipment | API responses | Missing data = offline |\n| Refresh Timestamp | Internal tracking | N/A | Unix timestamp |\n\n## Connection Reliability\n\n### Service-Level Connection Management\n- **Exponential Backoff**: 1s → 2s → 4s → 8s → 16s → 30s max\n- **Health Checks**: WebSocket ping/pong every 30 seconds\n- **Retry Limits**: Maximum 5 attempts before giving up\n- **Connection Failure Metric**: `intellicenter_connection_failure` (0=connected, 1=failed)\n\n### Equipment-Level Connection Handling\n- **Individual Equipment Status**: Each piece of equipment reports its own connection state\n- **Missing Data Detection**: Equipment metrics disappear when equipment goes offline\n- **No Service Impact**: Individual equipment failures don't affect service or other equipment\n- **Automatic Reappearance**: Equipment metrics return when equipment comes back online\n\n### Graceful Degradation Examples\n- **Pump Offline**: `pump_rpm` metrics disappear, water temperature monitoring continues\n- **Heater Offline**: `thermal_status` metrics disappear, circuit monitoring continues  \n- **Sensor Offline**: `air_temperature` metrics disappear, pool/spa monitoring continues\n- **Service Recovery**: All equipment metrics reappear when service reconnects to IntelliCenter\n\n### Configuration\n```go\nRetryConfig{\n    MaxRetries:      5,\n    BaseDelay:       1 * time.Second,\n    MaxDelay:        30 * time.Second,\n    BackoffFactor:   2.0,\n    HealthCheckRate: 30 * time.Second,\n}\n```\n\n## Smart Circuit Filtering\n\nPentameter filters IntelliCenter's ~35 circuits down to ~9 meaningful equipment items:\n\n**Included (Useful Equipment):**\n- **C-prefixed**: Core equipment (Pool, Spa, Lights, Cleaner)\n- **FTR-prefixed**: Features (Spa Heat, Fountain, Spa Jets)\n\n**Excluded (Virtual Controls):**\n- **AUX circuits**: Unused placeholder circuits\n- **X-prefixed**: Virtual buttons (Pump Speed +/-)\n- **_A-prefixed**: Action commands (All Lights On/Off)\n- **Duplicates**: Multiple entries for same equipment\n\n## Building and Development\n\n### Development Tools\n\nThe project includes comprehensive build automation via Makefile:\n\n```bash\n# Development workflow\nmake dev          # Build + quality checks (recommended for development)\nmake build        # Build binary only\nmake quality      # Run all quality checks\n\n# Release workflow  \nmake release      # Complete release (Docker + Homebrew + GitHub assets)\n\n# Docker development\nmake docker-build # Build with aggressive cache clearing (nuclear rebuild)\nmake compose-up   # Start full monitoring stack\n\n# Homebrew development\nmake build-macos-binaries      # Build macOS binaries (Intel + Apple Silicon)\nmake update-homebrew-formula   # Update Formula/pentameter.rb with checksums\n\n# View all available targets (organized by category)\nmake help\n```\n\n### Repository Structure\n\nThe project uses a consolidated repository structure:\n\n```\npentameter/\n├── Formula/\n│   └── pentameter.rb          # Homebrew formula (consolidated tap)\n├── dist/                      # Generated during release (macOS binaries)\n├── grafana/                   # Dashboard and datasource configs\n├── prometheus.yml             # Prometheus scraping configuration\n├── docker-compose.yml         # Complete monitoring stack\n├── Makefile                   # Build automation (Docker + Homebrew)\n├── main.go                    # Core application\n└── README.md\n```\n\n**Key Features:**\n- **Homebrew tap included** - No separate repository needed\n- **Multi-platform releases** - Docker (all platforms) + Homebrew (macOS)\n- **Automated workflows** - Single `make release` command\n- **Development friendly** - Nuclear rebuild options for reliable Docker development\n\n### Manual Build\n```bash\ngo build -o pentameter main.go\n./pentameter --ic-ip 192.168.192.168\n```\n\n## Docker Usage\n\n### Quick Start with Docker Compose\n```bash\n# Using Makefile (recommended)\nmake compose-up    # Start pentameter, Prometheus, and Grafana\nmake compose-logs  # View logs\nmake compose-down  # Stop all services\n\n# Or manually\ndocker-compose up -d\ndocker-compose logs -f\ndocker-compose down\ndocker-compose restart\n```\n\nThis starts the complete monitoring stack:\n- **Pentameter**: Pool data collection service\n- **Prometheus**: Metrics storage and querying\n- **Grafana**: Pre-configured dashboard at http://HOSTNAME:3000/d/pentameter/\n\n### Configuration via Environment Variables\nThe `docker-compose.yml` uses environment variables that you can override:\n\n```yaml\nenvironment:\n  - PENTAMETER_IC_IP=192.168.192.168\n  - PENTAMETER_IC_PORT=6680\n  - PENTAMETER_HTTP_PORT=8080\n  - PENTAMETER_INTERVAL=60\n```\n\n### Manual Docker Build and Run\n```bash\n# Build the image (required during early development)\ndocker build --no-cache -t pentameter .\n\n# Run the container\ndocker run -d \\\n  --name pentameter \\\n  -p 8080:8080 \\\n  -e PENTAMETER_IC_IP=192.168.192.168 \\\n  pentameter\n```\n\n### Docker Image Details\n- **Base Image**: `scratch` (minimal ~12MB image)\n- **Multi-stage build**: Go compilation in `golang:1.24-alpine`, final binary in scratch\n- **Networking**: Host networking mode for mDNS auto-discovery support\n- **Health Check**: Built-in health check endpoint at `/health`\n- **Restart Policy**: `unless-stopped` for automatic recovery\n\n### Network Configuration\n\nThe `pentameter-app` service uses host networking (`network_mode: \"host\"`) to enable mDNS auto-discovery:\n\n- **Auto-Discovery**: Allows pentameter to find IntelliCenter via `pentair.local` multicast DNS\n- **Why Host Networking**: Docker's default bridge network doesn't forward multicast traffic required for mDNS\n- **Security**: Appropriate for local network monitoring tools that need direct network access\n- **Performance**: Eliminates NAT overhead for WebSocket connections\n\nPrometheus and Grafana remain on the bridge network (`pentameter-net`) and connect to pentameter via localhost.\n\n## Prometheus Integration\n\n### Configuration\n- **Scrape Interval**: 60 seconds (matches polling interval)\n- **Data Retention**: 730 days (2 years) for long-term historical analysis\n- **Network**: Docker bridge communication via pentameter-net\n- **Format**: Standard Prometheus metrics with label-based time series\n\nAdd to your Prometheus `prometheus.yml`:\n\n```yaml\nscrape_configs:\n  - job_name: 'pentameter'\n    static_configs:\n      - targets: ['pentameter-app:8080']\n    scrape_interval: 60s\n```\n\n### Common Queries\n```promql\n# Specific equipment\nwater_temperature_fahrenheit{body=\"POOL\"}\npump_rpm{name=\"VS\"}\ncircuit_status{type=\"LIGHT\"}\n\n# All equipment types\nwater_temperature_fahrenheit\npump_rpm\ncircuit_status\n\n# System health\nintellicenter_connection_failure\nintellicenter_last_refresh_timestamp_seconds\n```\n\n## Grafana Integration\n\n### Dashboard Features\n- **Pre-configured**: Automatically provisioned \"Pool Monitoring\" dashboard\n- **Anonymous Access**: No authentication required for local use\n- **Adaptive Layout**: Handles missing air sensors gracefully\n- **Real-time Updates**: 30-second refresh with 6-hour default range\n\n### Display Options\n- **Standard View**: Full dashboard at `http://HOSTNAME:3000/d/pentameter/`\n- **Kiosk Mode**: Clean display at `http://HOSTNAME:3000/d/pentameter/?kiosk`\n- **Recommended Dashboard**: `http://HOSTNAME:3000/d/pentameter/?kiosk\u0026autofitpanels=true`\n- **Mobile Friendly**: Responsive design for all screen sizes\n\n### Visual Elements\n- Water temperature trends (Pool \u0026 Spa)\n- Air temperature trends (if available)\n- Connection status indicators\n- Human-readable timestamps (\"X minutes ago\" format)\n\n### Manual Dashboard Creation\nCreate custom panels using these queries:\n```promql\nwater_temperature_fahrenheit{body=\"POOL\"}\nwater_temperature_fahrenheit{body=\"SPA\"}\nair_temperature_fahrenheit{sensor=\"AIR\"}\nintellicenter_connection_failure\nintellicenter_last_refresh_timestamp_seconds\n```\n\n## Roadmap\n\n- Refactor monolithic main.go into focused modules\n- Implement structured logging with configurable levels\n- Add comprehensive integration tests\n- Implement automated coverage reporting\n- Alert rule templates and notification integrations\n- Update Makefile release targets to reflect current multi-step workflow\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fastrostl%2Fpentameter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fastrostl%2Fpentameter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fastrostl%2Fpentameter/lists"}