{"id":26492727,"url":"https://github.com/timothydodd/hubitat-to-mqtt","last_synced_at":"2026-05-20T19:05:31.659Z","repository":{"id":282777984,"uuid":"949624578","full_name":"timothydodd/hubitat-to-mqtt","owner":"timothydodd","description":"A bridge between Hubitat Elevation home automation hub and MQTT","archived":false,"fork":false,"pushed_at":"2025-03-16T21:29:19.000Z","size":25,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-16T22:25:31.200Z","etag":null,"topics":["hubitat","mqtt"],"latest_commit_sha":null,"homepage":"https://robododd.com","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/timothydodd.png","metadata":{"files":{"readme":"README.MD","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-03-16T21:17:46.000Z","updated_at":"2025-03-16T21:29:22.000Z","dependencies_parsed_at":"2025-03-16T22:25:36.177Z","dependency_job_id":"2eb3a2a7-f22f-4a97-b718-20426abe8221","html_url":"https://github.com/timothydodd/hubitat-to-mqtt","commit_stats":null,"previous_names":["timothydodd/hubitat-to-mqtt"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timothydodd%2Fhubitat-to-mqtt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timothydodd%2Fhubitat-to-mqtt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timothydodd%2Fhubitat-to-mqtt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timothydodd%2Fhubitat-to-mqtt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timothydodd","download_url":"https://codeload.github.com/timothydodd/hubitat-to-mqtt/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244584810,"owners_count":20476615,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["hubitat","mqtt"],"created_at":"2025-03-20T09:26:53.213Z","updated_at":"2026-05-20T19:05:31.649Z","avatar_url":"https://github.com/timothydodd.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Hubitat to MQTT Bridge\n\nThis project creates a robust, production-ready bridge between Hubitat Elevation home automation hub and MQTT, enabling integration with other smart home platforms and custom applications that support MQTT.\n\n## Features\n\n- **Bi-directional Communication**: Send device states from Hubitat to MQTT and control devices via MQTT topics\n- **Real-time Updates**: Receive instant device state changes via webhooks with race condition protection\n- **Enhanced Reliability**: Hybrid approach with webhooks, periodic synchronization, and comprehensive error handling\n- **Flexible Topic Structure**: Clear, hierarchical MQTT topics for easy integration\n- **Smart Refresh Strategy**: Configurable rules for when to fetch complete device data\n- **Device Control**: Control Hubitat devices by publishing to MQTT topics\n- **Dual Addressing**: Access devices by name or ID for maximum flexibility\n- **MQTT Authentication**: Support for both secured and unsecured MQTT brokers\n- **Thread-Safe Operations**: Concurrent webhook processing with proper synchronization\n- **Automatic Reconnection**: Intelligent MQTT reconnection with exponential backoff\n- **Comprehensive Logging**: Detailed logging for troubleshooting and monitoring\n- **Configuration Validation**: Startup validation prevents runtime configuration errors\n- **Topic Cleanup**: Automatic cleanup of stale MQTT topics during synchronization\n\n## Architecture\n\nThe application consists of several key components working together:\n\n1. **WebAPI with Webhook Controller**: Receives real-time device events from Hubitat\n2. **Background Worker Service**: Performs periodic synchronization to ensure data consistency\n3. **Sync Coordinator**: Prevents race conditions between webhook updates and full sync operations\n4. **Device Cache**: Thread-safe, high-performance caching of device data\n5. **MQTT Services**: Robust publishing with retry logic and connection management\n6. **Command Handler**: Processes MQTT commands to control Hubitat devices\n\n## Setup \u0026 Configuration\n\n### Prerequisites\n\n- .NET 9.0 SDK or newer\n- Hubitat Elevation hub with Maker API app installed\n- MQTT broker (like Mosquitto, HiveMQ, or Eclipse MQTT)\n\n### Installation\n\n1. Clone the repository:\n   ```bash\n   git clone https://github.com/yourusername/hubitat-mqtt.git\n   cd hubitat-mqtt\n   ```\n\n2. Update the `appsettings.json` with your configuration:\n   ```json\n   {\n     \"Hubitat\": {\n       \"BaseUrl\": \"http://your-hubitat-ip\",\n       \"AccessToken\": \"your-maker-api-token\",\n       \"DeviceId\": \"your-maker-api-app-id\",\n       \"FullRefreshEvents\": \"mode,hsm,alarm,presence,away,home\",\n       \"FullRefreshDeviceTypes\": \"thermostat,lock,security,doorControl,valve,waterSensor\"\n     },\n     \"MQTT\": {\n       \"Server\": \"your-mqtt-broker-address\",\n       \"Port\": 1883,\n       \"Username\": \"\",  // Optional - leave empty for no authentication\n       \"Password\": \"\",  // Optional - leave empty for no authentication\n       \"BaseTopic\": \"hubitat\",\n       \"MaxRetryAttempts\": 3,        // Retry attempts for failed MQTT publishes\n       \"RetryDelayMs\": 1000,         // Delay between retry attempts\n       \"SyncTimeoutMs\": 10000        // Timeout for MQTT topic sync operations\n     },\n     \"SyncPollIntervalHours\": 4,     // Set to 0 to disable polling after initial sync\n     \"ClearTopicOnSync\": true        // Clean up stale MQTT topics during sync\n   }\n   ```\n\n3. Build and run the application:\n   ```bash\n   dotnet build\n   dotnet run --project src/HubitatMqtt/HubitatMqtt.csproj\n   ```\n\n### Docker Deployment\n\nBuild and run using Docker:\n```bash\ndocker build -t hubitat-mqtt -f src/HubitatMqtt/Dockerfile src/\ndocker run -d --name hubitat-mqtt -p 8080:8080 -v /path/to/appsettings.json:/app/appsettings.json hubitat-mqtt\n```\n\n### Hubitat Configuration\n\n1. Install the Maker API app on your Hubitat hub\n2. Select the devices you want to expose to the API\n3. Note your Access Token and App ID\n4. Configure a webhook in the Maker API to point to your server:\n   - URL: `http://your-server-ip:8080/api/hook/device/event`\n   - Method: POST\n\n## MQTT Topic Structure\n\nThe bridge publishes device states to MQTT topics using the following structure:\n\n- **Full Device Data (by ID)**: `hubitat/device/{device_id}`\n- **Device Attributes (by ID)**: `hubitat/device/{device_id}/{attribute_name}`\n- **Event Data**: `hubitat/device/{id}/events` (fallback for unknown devices)\n\n### Command Topics\n\nTo control devices, publish to the command topics:\n\n- **Command by device ID**: `hubitat/device/{device_id}/command/{command_name}`\n\nThe payload of the message should be the command parameter value. For commands without parameters, the payload can be empty.\n\n**Example commands:**\n- Publish `\"on\"` to `hubitat/device/123/command/switch` to turn on device ID 123\n- Publish `\"70\"` to `hubitat/device/456/command/setTemperature` to set temperature to 70°\n\n**Example attribute topics:**\n- `hubitat/device/123/switch` → `\"on\"`\n- `hubitat/device/456/temperature` → `\"72\"`\n- `hubitat/device/789/battery` → `\"85\"`\n\n## Smart Refresh Strategy\n\nThe application uses an intelligent approach to balance performance and reliability:\n\n1. **Configurable Event Types**: Events like mode changes, security alerts, or presence changes trigger full device refresh\n2. **Configurable Device Types**: Complex devices like thermostats, locks, or security systems always use full device data\n3. **Periodic Synchronization**: Scheduled full synchronization ensures data consistency\n4. **Race Condition Prevention**: Sync coordinator prevents conflicts between webhook updates and full sync\n\n## Enhanced Logging\n\nThe application provides comprehensive logging for monitoring and troubleshooting:\n\n### AlwaysRefreshDevice Logging\nFor devices configured in `FullRefreshDeviceTypes`, detailed change logging is available:\n\n```\n[INFO] AlwaysRefreshDevice Update - Device: 123 (Front Door Lock) Type: lock | Trigger: lock=locked\n[INFO] AlwaysRefreshDevice Change - 123 (Front Door Lock) | lock: 'unlocked' → 'locked'\n[INFO] AlwaysRefreshDevice Change - 123 (Front Door Lock) | battery: '85' → '84'\n[INFO] AlwaysRefreshDevice Summary - 123 (Front Door Lock) | 2 attributes changed: lock, battery\n```\n\n### Error Handling and Recovery\n- **Hubitat API Errors**: Automatic fallback to event-only updates\n- **MQTT Connection Issues**: Automatic reconnection with exponential backoff\n- **Publish Failures**: Retry logic with configurable attempts and delays\n- **Configuration Errors**: Comprehensive validation at startup\n\n## Performance Optimizations\n\n- **Thread-Safe Device Cache**: High-performance concurrent device data storage\n- **Webhook-First Approach**: Primary updates come from webhooks for efficiency\n- **Selective Refresh**: Only fetches full device data when necessary\n- **Connection Pooling**: Efficient HTTP client management for Hubitat API calls\n- **Async Operations**: Non-blocking operations throughout the application\n- **Memory Efficient**: Proper resource disposal and memory management\n\n## Health Monitoring\n\nThe application exposes a health check endpoint at `/health` for monitoring:\n\n```bash\ncurl http://localhost:8080/health\n```\n\n## Project Structure\n\n- **Controllers/WebhookController.cs**: Handles incoming webhook events from Hubitat with sync coordination\n- **Services/Worker.cs**: Background service for periodic device synchronization\n- **Services/HubitatClient.cs**: Robust HTTP client for Hubitat API communication\n- **Services/DeviceCache.cs**: Thread-safe device data caching\n- **Services/MqttPublishService.cs**: MQTT publishing with retry logic and error handling\n- **Services/SyncCoordinator.cs**: Prevents race conditions between webhook and sync operations\n- **Services/MqttCommandHandler.cs**: Processes MQTT commands to control devices\n- **Common/MqttBuilder.cs**: MQTT client factory with advanced reconnection logic\n- **Program.cs**: Application startup, DI configuration, and validation\n\n## Configuration Reference\n\n### Required Settings\n- `Hubitat:BaseUrl` - URL of your Hubitat hub\n- `Hubitat:AccessToken` - Maker API access token\n- `Hubitat:DeviceId` - Maker API app ID\n- `MQTT:Server` - MQTT broker hostname/IP\n- `MQTT:Port` - MQTT broker port\n\n### Optional Settings\n- `Hubitat:FullRefreshEvents` - Comma-separated list of events that trigger full refresh\n- `Hubitat:FullRefreshDeviceTypes` - Comma-separated list of device types that always get full refresh\n- `MQTT:Username/Password` - MQTT authentication credentials\n- `MQTT:BaseTopic` - Base topic prefix (default: \"hubitat\")\n- `MQTT:MaxRetryAttempts` - Retry attempts for failed publishes (default: 3)\n- `MQTT:RetryDelayMs` - Delay between retries in milliseconds (default: 1000)\n- `MQTT:SyncTimeoutMs` - Timeout for sync operations (default: 10000)\n- `SyncPollIntervalHours` - Hours between full syncs (default: 4, 0 to disable)\n- `ClearTopicOnSync` - Clean up stale topics during sync (default: true)\n\n## Troubleshooting\n\n### Common Issues\n\n**Configuration Validation Errors**: Check logs during startup for specific validation failures\n\n**MQTT Connection Issues**: \n- Verify broker accessibility and credentials\n- Check logs for reconnection attempts and exponential backoff behavior\n\n**Webhook Timeout Warnings**:\n- `Timeout acquiring webhook lock` indicates full sync was in progress\n- This is normal behavior that prevents race conditions\n\n**Device Sync Issues**:\n- Check Hubitat API accessibility and token validity\n- Review logs for specific API error messages\n\n### Log Analysis\n- Use log prefixes like `AlwaysRefreshDevice` to filter specific device updates\n- Monitor health check endpoint for overall system status\n- Watch for `HubitatApiException` and `MqttPublishException` for service-specific issues\n\n### Performance Tuning\n- Adjust `SyncPollIntervalHours` based on your needs\n- Configure `MaxRetryAttempts` and `RetryDelayMs` for your network conditions\n- Monitor device cache performance in logs\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request. When contributing:\n\n1. Follow the existing code style and patterns\n2. Add appropriate logging for new features\n3. Include error handling and validation\n4. Update documentation as needed\n\n## License\n\nThis project is licensed under the MIT License - see the LICENSE file for details.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimothydodd%2Fhubitat-to-mqtt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimothydodd%2Fhubitat-to-mqtt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimothydodd%2Fhubitat-to-mqtt/lists"}