This 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.
- Bi-directional Communication: Send device states from Hubitat to MQTT and control devices via MQTT topics
- Real-time Updates: Receive instant device state changes via webhooks with race condition protection
- Enhanced Reliability: Hybrid approach with webhooks, periodic synchronization, and comprehensive error handling
- Flexible Topic Structure: Clear, hierarchical MQTT topics for easy integration
- Smart Refresh Strategy: Configurable rules for when to fetch complete device data
- Device Control: Control Hubitat devices by publishing to MQTT topics
- Dual Addressing: Access devices by name or ID for maximum flexibility
- MQTT Authentication: Support for both secured and unsecured MQTT brokers
- Thread-Safe Operations: Concurrent webhook processing with proper synchronization
- Automatic Reconnection: Intelligent MQTT reconnection with exponential backoff
- Comprehensive Logging: Detailed logging for troubleshooting and monitoring
- Configuration Validation: Startup validation prevents runtime configuration errors
- Topic Cleanup: Automatic cleanup of stale MQTT topics during synchronization
The application consists of several key components working together:
- WebAPI with Webhook Controller: Receives real-time device events from Hubitat
- Background Worker Service: Performs periodic synchronization to ensure data consistency
- Sync Coordinator: Prevents race conditions between webhook updates and full sync operations
- Device Cache: Thread-safe, high-performance caching of device data
- MQTT Services: Robust publishing with retry logic and connection management
- Command Handler: Processes MQTT commands to control Hubitat devices
- .NET 9.0 SDK or newer
- Hubitat Elevation hub with Maker API app installed
- MQTT broker (like Mosquitto, HiveMQ, or Eclipse MQTT)
-
Clone the repository:
git clone https://github.com/yourusername/hubitat-mqtt.git cd hubitat-mqtt
-
Update the
appsettings.json
with your configuration:{ "Hubitat": { "BaseUrl": "http://your-hubitat-ip", "AccessToken": "your-maker-api-token", "DeviceId": "your-maker-api-app-id", "FullRefreshEvents": "mode,hsm,alarm,presence,away,home", "FullRefreshDeviceTypes": "thermostat,lock,security,doorControl,valve,waterSensor" }, "MQTT": { "Server": "your-mqtt-broker-address", "Port": 1883, "Username": "", // Optional - leave empty for no authentication "Password": "", // Optional - leave empty for no authentication "BaseTopic": "hubitat", "MaxRetryAttempts": 3, // Retry attempts for failed MQTT publishes "RetryDelayMs": 1000, // Delay between retry attempts "SyncTimeoutMs": 10000 // Timeout for MQTT topic sync operations }, "SyncPollIntervalHours": 4, // Set to 0 to disable polling after initial sync "ClearTopicOnSync": true // Clean up stale MQTT topics during sync }
-
Build and run the application:
dotnet build dotnet run --project src/HubitatMqtt/HubitatMqtt.csproj
Build and run using Docker:
docker build -t hubitat-mqtt -f src/HubitatMqtt/Dockerfile src/
docker run -d --name hubitat-mqtt -p 8080:8080 -v /path/to/appsettings.json:/app/appsettings.json hubitat-mqtt
- Install the Maker API app on your Hubitat hub
- Select the devices you want to expose to the API
- Note your Access Token and App ID
- Configure a webhook in the Maker API to point to your server:
- URL:
http://your-server-ip:8080/api/hook/device/event
- Method: POST
- URL:
The bridge publishes device states to MQTT topics using the following structure:
- Full Device Data (by ID):
hubitat/device/{device_id}
- Device Attributes (by ID):
hubitat/device/{device_id}/{attribute_name}
- Event Data:
hubitat/device/{id}/events
(fallback for unknown devices)
To control devices, publish to the command topics:
- Command by device ID:
hubitat/device/{device_id}/command/{command_name}
The payload of the message should be the command parameter value. For commands without parameters, the payload can be empty.
Example commands:
- Publish
"on"
tohubitat/device/123/command/switch
to turn on device ID 123 - Publish
"70"
tohubitat/device/456/command/setTemperature
to set temperature to 70°
Example attribute topics:
hubitat/device/123/switch
→"on"
hubitat/device/456/temperature
→"72"
hubitat/device/789/battery
→"85"
The application uses an intelligent approach to balance performance and reliability:
- Configurable Event Types: Events like mode changes, security alerts, or presence changes trigger full device refresh
- Configurable Device Types: Complex devices like thermostats, locks, or security systems always use full device data
- Periodic Synchronization: Scheduled full synchronization ensures data consistency
- Race Condition Prevention: Sync coordinator prevents conflicts between webhook updates and full sync
The application provides comprehensive logging for monitoring and troubleshooting:
For devices configured in FullRefreshDeviceTypes
, detailed change logging is available:
[INFO] AlwaysRefreshDevice Update - Device: 123 (Front Door Lock) Type: lock | Trigger: lock=locked
[INFO] AlwaysRefreshDevice Change - 123 (Front Door Lock) | lock: 'unlocked' → 'locked'
[INFO] AlwaysRefreshDevice Change - 123 (Front Door Lock) | battery: '85' → '84'
[INFO] AlwaysRefreshDevice Summary - 123 (Front Door Lock) | 2 attributes changed: lock, battery
- Hubitat API Errors: Automatic fallback to event-only updates
- MQTT Connection Issues: Automatic reconnection with exponential backoff
- Publish Failures: Retry logic with configurable attempts and delays
- Configuration Errors: Comprehensive validation at startup
- Thread-Safe Device Cache: High-performance concurrent device data storage
- Webhook-First Approach: Primary updates come from webhooks for efficiency
- Selective Refresh: Only fetches full device data when necessary
- Connection Pooling: Efficient HTTP client management for Hubitat API calls
- Async Operations: Non-blocking operations throughout the application
- Memory Efficient: Proper resource disposal and memory management
The application exposes a health check endpoint at /health
for monitoring:
curl http://localhost:8080/health
- Controllers/WebhookController.cs: Handles incoming webhook events from Hubitat with sync coordination
- Services/Worker.cs: Background service for periodic device synchronization
- Services/HubitatClient.cs: Robust HTTP client for Hubitat API communication
- Services/DeviceCache.cs: Thread-safe device data caching
- Services/MqttPublishService.cs: MQTT publishing with retry logic and error handling
- Services/SyncCoordinator.cs: Prevents race conditions between webhook and sync operations
- Services/MqttCommandHandler.cs: Processes MQTT commands to control devices
- Common/MqttBuilder.cs: MQTT client factory with advanced reconnection logic
- Program.cs: Application startup, DI configuration, and validation
Hubitat:BaseUrl
- URL of your Hubitat hubHubitat:AccessToken
- Maker API access tokenHubitat:DeviceId
- Maker API app IDMQTT:Server
- MQTT broker hostname/IPMQTT:Port
- MQTT broker port
Hubitat:FullRefreshEvents
- Comma-separated list of events that trigger full refreshHubitat:FullRefreshDeviceTypes
- Comma-separated list of device types that always get full refreshMQTT:Username/Password
- MQTT authentication credentialsMQTT:BaseTopic
- Base topic prefix (default: "hubitat")MQTT:MaxRetryAttempts
- Retry attempts for failed publishes (default: 3)MQTT:RetryDelayMs
- Delay between retries in milliseconds (default: 1000)MQTT:SyncTimeoutMs
- Timeout for sync operations (default: 10000)SyncPollIntervalHours
- Hours between full syncs (default: 4, 0 to disable)ClearTopicOnSync
- Clean up stale topics during sync (default: true)
Configuration Validation Errors: Check logs during startup for specific validation failures
MQTT Connection Issues:
- Verify broker accessibility and credentials
- Check logs for reconnection attempts and exponential backoff behavior
Webhook Timeout Warnings:
Timeout acquiring webhook lock
indicates full sync was in progress- This is normal behavior that prevents race conditions
Device Sync Issues:
- Check Hubitat API accessibility and token validity
- Review logs for specific API error messages
- Use log prefixes like
AlwaysRefreshDevice
to filter specific device updates - Monitor health check endpoint for overall system status
- Watch for
HubitatApiException
andMqttPublishException
for service-specific issues
- Adjust
SyncPollIntervalHours
based on your needs - Configure
MaxRetryAttempts
andRetryDelayMs
for your network conditions - Monitor device cache performance in logs
Contributions are welcome! Please feel free to submit a Pull Request. When contributing:
- Follow the existing code style and patterns
- Add appropriate logging for new features
- Include error handling and validation
- Update documentation as needed
This project is licensed under the MIT License - see the LICENSE file for details.