Automated temperature control for your Airbnb rental based on booking check-ins and check-outs. Integrates with Airbnb iCal feeds and Envi smart thermostats to optimize energy usage.
This application automatically adjusts your Envi thermostat(s) based on your Airbnb booking calendar with time-based execution:
- 8:00 AM (Check-in mode): If exactly 1 check-in event today → Set temperature to 63°F (comfortable for arriving guests)
- 11:00 AM (Check-out mode): If exactly 1 check-out event today → Set temperature to 41°F (energy saving mode)
The system implements strict rules to ensure reliable operation:
- ✅ Single check-in (8am run) → Set to 63°F
- ✅ Single check-out (11am run) → Set to 41°F
- ❌ Back-to-back (check-out + check-in same day) → No action
- ❌ Multiple events of same type → No action
- ❌ No events → No action
- ❌ Wrong event type for execution time → No action
AirbnbClimateControl/
├── AirbnbClimateControl/ # Main application
│ ├── Models/ # Data models
│ │ ├── BookingEvent.cs # Booking event representation
│ │ ├── TemperatureCommand.cs # Temperature command model
│ │ ├── EnviDevice.cs # Envi device model
│ │ └── EnviAccountConfig.cs # Envi configuration model
│ ├── Services/ # Business logic services
│ │ ├── ICalendarService.cs # Calendar service interface
│ │ ├── AirbnbCalendarService.cs # Airbnb iCal parser
│ │ ├── IThermostatService.cs # Thermostat service interface
│ │ ├── EnviThermostatService.cs # Envi API integration
│ │ └── BookingAnalyzer.cs # Temperature decision logic
│ ├── Program.cs # Entry point with CLI parsing
│ └── appsettings.json # Configuration (template)
├── AirbnbClimateControl.Tests/ # Test suite
│ ├── Services/ # Unit tests
│ ├── Integration/ # Integration tests
│ └── TestData/ # Test calendar files
└── README.md
✨ Fully Automated: Set-and-forget temperature management
🌡️ Smart Logic: Only acts on clear check-in/check-out scenarios
🔌 Multi-Device: Control multiple Envi thermostats simultaneously
📊 Comprehensive Logging: Detailed logs for monitoring and debugging
🧪 Well Tested: 21 unit tests + 4 integration tests
🔒 Secure: Credentials managed via configuration files (not in source)
- Log into your Airbnb host account
- Go to Calendar → Availability Settings → Calendar sync
- Copy your iCal export URL
- Update
appsettings.json:
{
"Airbnb": {
"CalendarUrl": "https://www.airbnb.com/calendar/ical/YOUR_LISTING_ID.ics?s=YOUR_SECRET_TOKEN"
}
}Update the Envi section in appsettings.json:
{
"Envi": {
"Username": "your_envi_username",
"Password": "your_envi_password",
"ApiUrl": "https://app-apis.enviliving.com/apis/v1",
"DeviceIds": [14883, 14884] // Your Envi device IDs
}
}To find your Device IDs:
- Run the integration test
GetAllDevicesAsync_WithRealCredentials_ReturnsDeviceList - Or use the Envi mobile app to identify your device IDs
# Restore dependencies
dotnet restore
# Build the solution
dotnet build
# Run check-in mode (8am execution)
dotnet run --project AirbnbClimateControl/AirbnbClimateControl.csproj checkin
# Run check-out mode (11am execution)
dotnet run --project AirbnbClimateControl/AirbnbClimateControl.csproj checkout
# Run all unit tests (excludes integration tests)
dotnet test --filter "Category!=Integration"
# Run integration tests (requires real credentials)
dotnet test --filter "Category=Integration"The application requires a command-line argument to specify the execution mode:
# 8am execution - Check for check-ins
AirbnbClimateControl.exe checkin
# 11am execution - Check for check-outs
AirbnbClimateControl.exe checkoutInvalid usage (no argument):
Usage: AirbnbClimateControl.exe <checkin|checkout>
checkin - 8am execution: Sets temperature to 63°F if exactly 1 check-in event
checkout - 11am execution: Sets temperature to 41°F if exactly 1 check-out event
Set up two scheduled tasks to run the application daily:
Task 1: Morning Check-in (8:00 AM)
- Open Task Scheduler
- Create a new task:
- Name: Airbnb Climate - Check-in
- Trigger: Daily at 8:00 AM
- Action: Start a program
- Program:
C:\path\to\AirbnbClimateControl.exe - Arguments:
checkin
- Program:
- Settings: ✅ Run whether user is logged on or not
Task 2: Late Morning Check-out (11:00 AM)
- Create another task:
- Name: Airbnb Climate - Check-out
- Trigger: Daily at 11:00 AM
- Action: Start a program
- Program:
C:\path\to\AirbnbClimateControl.exe - Arguments:
checkout
- Program:
# Edit crontab
crontab -e
# Add these lines:
0 8 * * * /usr/bin/dotnet /path/to/AirbnbClimateControl.dll checkin >> /var/log/airbnb-climate.log 2>&1
0 11 * * * /usr/bin/dotnet /path/to/AirbnbClimateControl.dll checkout >> /var/log/airbnb-climate.log 2>&1Deploy with two timer triggers:
checkinfunction: Runs at 8:00 AM dailycheckoutfunction: Runs at 11:00 AM daily
1. Parse command-line argument (checkin/checkout)
2. Validate Airbnb calendar and Envi connections
3. Fetch today's booking events from iCal feed
4. Analyze events with BookingAnalyzer:
- Check-in mode: Look for exactly 1 check-in → 63°F
- Check-out mode: Look for exactly 1 check-out → 41°F
5. If temperature change needed:
- Get device IDs from configuration
- Send temperature command to all devices
6. Log results and complete
| Scenario | Check-in Mode (8am) | Check-out Mode (11am) |
|---|---|---|
| 1 check-in event | ✅ Set 63°F | ❌ No action |
| 1 check-out event | ❌ No action | ✅ Set 41°F |
| Check-in + check-out | ❌ No action (back-to-back) | ❌ No action (back-to-back) |
| Multiple check-ins | ❌ No action | ❌ No action |
| Multiple check-outs | ❌ No action | ❌ No action |
| No events | ❌ No action | ❌ No action |
The application integrates with Envi's RESTful API:
- Authentication: Username/password with bearer token
- Device Discovery:
GET /device/list - Temperature Control:
PATCH /device/update-temperature/{deviceId} - Multi-Device: Updates all configured devices simultaneously
- Format: iCal (iCalendar) standard
- Parser: Ical.Net library
- Event Types: Check-in, Check-out, Occupied
- Timezone: Handles timezone conversions automatically
- .NET 10.0 - Runtime framework
- Ical.Net - iCalendar parsing
- Microsoft.Extensions.Configuration - Configuration management
- Microsoft.Extensions.Configuration.Json - JSON configuration
- Microsoft.Extensions.DependencyInjection - DI container
- Microsoft.Extensions.Http - HTTP client factory
- Microsoft.Extensions.Logging - Logging infrastructure
- xUnit - Unit testing framework
- Moq - Mocking library for tests
The project includes comprehensive test coverage:
AirbnbCalendarServiceTests.cs- Calendar parsing and validationBookingAnalyzerTests.cs- Temperature decision logic (11 test cases)
AirbnbCalendarServiceIntegrationTests.cs- Real Airbnb calendar testsEnviThermostatServiceIntegrationTests.cs- Real Envi API tests
Run tests:
# Unit tests only
dotnet test --filter "Category!=Integration"
# All tests including integration (requires credentials)
dotnet testThe application provides detailed logging:
=== Airbnb Climate Control Started ===
Current time: 2025-12-07 08:00:00
Validating service connections...
All services validated successfully.
Fetching today's bookings...
Retrieved 1 booking event(s) for today.
CheckIn mode (8am): Single check-in event detected. Setting temperature to 63°F
✓ Successfully set temperature to 63°F for 2 device(s)
=== Airbnb Climate Control Completed ===
🔒 Never commit credentials to source control:
- Use
appsettings.jsonfor local development (in.gitignore) - Use environment variables for production
- Consider Azure Key Vault or AWS Secrets Manager for cloud deployments
🔒 Included .gitignore protects:
appsettings.json- Binary directories (
bin/,obj/) - User-specific files
🔒 Test data sanitized:
- All calendar test files use generic placeholder data
- No real guest names, reservation codes, or phone numbers
- Integration tests require explicit credential configuration
- Add your device IDs to
appsettings.jsonunderEnvi:DeviceIds - Run the
GetAllDevicesAsynctest to discover your device IDs
- Verify your Airbnb calendar URL in
appsettings.json - Ensure the URL is publicly accessible
- Check internet connectivity
- Verify Envi username and password
- Check API endpoint URL
- Ensure Envi account is active
- This is expected behavior! The system does nothing for same-day check-out/check-in to avoid conflicts
- Add email/SMS notifications for temperature changes
- Support for multiple properties/calendars
- Web dashboard for monitoring
- Temperature history tracking and analytics
- Configurable temperature presets
- Support for other smart thermostat brands
- Weather-based temperature adjustments
- Guest arrival time predictions
Private project. Modify as needed for your use case.
For issues or questions:
- Check logs for detailed diagnostics
- Verify configuration in
appsettings.json - Run integration tests to validate API connectivity
- Review business logic in
BookingAnalyzer.cs