# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

This is a Homebridge plugin that exposes Ecobee thermostat climate status control (Home/Away/Sleep) through HomeKit's security system interface. Users can control their thermostat's climate modes using HomeKit automation.

## Development Commands

```bash
# Build the TypeScript code
npm run build

# Lint the codebase
npm run lint

# Watch mode for development (builds, links, and runs nodemon)
npm run watch
```

## Architecture

### Core Components

1. **Platform (`src/platform.ts`)**: The main `EcobeeAPIPlatform` class that implements Homebridge's `IndependentPlatformPlugin`. Responsible for:
   - Initializing the AuthTokenManager singleton
   - Creating and registering accessories (security system and optional automation switch)
   - Managing cached accessories on Homebridge restart

2. **Accessories**:
   - **AwaySwitchAccessory (`src/awaySwitchAccessory.ts`)**: The main security system accessory that maps HomeKit security states to Ecobee climate modes:
     - STAY_ARM → Home (resume program or indefinite hold)
     - AWAY_ARM → Away (indefinite hold by default)
     - NIGHT_ARM → Sleep (indefinite hold by default)
   - **AutomationSwitchAccessory (`src/automationSwitchAccessory.ts`)**: Optional simple ON/OFF switch for Home/Away control (enabled via `enableAutomationSwitch` config)

3. **Authentication (`src/auth-token-refresh.ts`)**: Singleton `AuthTokenManager` that:
   - Manages Ecobee OAuth2 access tokens and refresh tokens
   - Automatically refreshes tokens before expiration (5 min buffer)
   - Handles rate limiting with exponential backoff
   - Updates the Homebridge config file when refresh tokens change
   - Uses NetworkRetry for resilient token refresh operations

4. **Network Resilience (`src/network-retry.ts`)**: Reusable `NetworkRetry` class that:
   - Implements exponential backoff with jitter
   - Handles transient network errors (DNS failures, timeouts, connection resets)
   - Respects rate limit headers (429 responses)
   - Provides time-window-based retry logic
   - Used by both AuthTokenManager and API calls in accessories

### Key Design Patterns

- **Singleton Pattern**: AuthTokenManager is a singleton configured during platform initialization
- **Mapping Layer**: Security system states are mapped to/from Ecobee climate references in awaySwitchAccessory.ts
- **Hold Type Configuration**: Each climate mode (Home/Away/Sleep) can be configured to use either:
  - Indefinite hold: Maintains temperature until manually changed
  - Resume program: Follows Ecobee's programmed schedule
- **Polling**: Status updates from Ecobee API occur every 60 minutes by default (configurable via `statusPollingMinutes`)

### Ecobee API Integration

- **Token Endpoint**: `https://api.ecobee.com/token` - OAuth2 token operations
- **Thermostat Endpoint**: `https://api.ecobee.com/1/thermostat` - Climate control and status queries
- **API Key**: Hardcoded in AuthTokenManager (public API key for this plugin)
- **Selection Types**:
  - `registered`: All thermostats on the account (default)
  - `thermostats`: Specific thermostats by serial number (when `thermostatSerialNumbers` is configured)

### Configuration Schema

See `src/platform.ts:22-30` for the full config interface. Key options:
- `refreshToken`: Required OAuth2 refresh token (obtained via `ecobee-auth-cli`)
- `thermostatSerialNumbers`: Optional comma-separated list to filter thermostats
- `enableAutomationSwitch`: Adds a simple ON/OFF switch alongside the security system
- `homeIndefiniteHold`, `awayIndefiniteHold`, `sleepIndefiniteHold`: Control hold behavior per state
- `statusPollingMinutes`: Polling interval for status updates (default: 60)

### Authentication CLI

The `ecobee-auth-cli` binary (entry point: `ecobee-auth-cli.js`) runs the authentication flow:
- Generates a PIN code for Ecobee My Apps portal
- Exchanges PIN for initial tokens after user authorizes
- Outputs the refresh token for config file

Implementation in `src/refresh-token.ts` and `src/cli-util.ts`.

### Error Handling

- Network errors are retried with exponential backoff via NetworkRetry
- Rate limiting (429 errors) triggers longer backoff periods with respect for Retry-After headers
- Token expiration is proactively handled with background refresh scheduling
- Failed API calls log errors but don't crash the plugin
- Auth token refresh failures are logged and automatically retried

## Important Notes

- The plugin automatically updates the Homebridge config file when refresh tokens rotate
- Multiple simultaneous token refresh attempts are prevented via a lock mechanism
- Rate limiting is tracked with a `rateLimitedUntil` timestamp to avoid excessive retry attempts
- The default polling interval is 60 minutes to minimize API calls
- All Ecobee API calls use NetworkRetry for resilience against transient network issues
