# Home control Alexa Skill An Alexa skill that triggers water recirculation on Rinnai tankless water heaters and supports homeassistant device control ## Usage > "Alexa, ask house to start the hot water" This will authenticate with the Rinnai API and start a 15-minute recirculation cycle. > "Alexa, turn on the bedroom light" This will use the homeassistant REST API to find the bedroom device and turn it on. You can turn on, turn off, toggle, and query status ## Building Requires [Zig 0.15](https://ziglang.org/) and [mise](https://mise.jdx.dev/) for version management. The build defaults to `aarch64-linux` for AWS Lambda Graviton (arm64) deployment. ```bash # Debug build (arm64) zig build # Release build (arm64) zig build -Doptimize=ReleaseFast # Run tests (uses host CPU/OS) zig build test ``` ## Dependencies - [aws-sdk-for-zig](https://git.lerch.org/lobo/aws-sdk-for-zig) - AWS SDK for Zig - [lambda-zig](https://git.lerch.org/lobo/lambda-zig) - AWS Lambda runtime for Zig - [controlr](https://git.lerch.org/lobo/controlr) - Rinnai API client (provides `rinnai` module) ## Deployment Setup Before deploying, you need to configure both AWS credentials and ASK CLI authentication. ### 1. AWS Credentials AWS credentials are required for Lambda deployment. You can configure them in several ways: #### Option A: AWS CLI Configuration (Recommended) ```bash # Configure default profile aws configure # Or configure a named profile aws configure --profile personal ``` This creates `~/.aws/credentials` and `~/.aws/config` files. #### Option B: Environment Variables ```bash export AWS_ACCESS_KEY_ID=AKIA... export AWS_SECRET_ACCESS_KEY=... export AWS_DEFAULT_REGION=us-west-2 ``` #### Using a Non-Default AWS Profile If your default AWS profile is your work account but you want to deploy to your personal account: ```bash # Set the profile for the current shell session export AWS_PROFILE=personal # Or specify it per-command zig build awslambda_deploy -Dprofile=personal zig build deploy -Dprofile=personal ``` You can also set the region: ```bash zig build awslambda_deploy -Dprofile=personal -Dregion=us-west-2 ``` ### 2. ASK CLI Authentication The ASK CLI requires authentication with your Amazon Developer account to deploy Alexa skills. #### First-Time Setup ```bash # Install dependencies (if not already installed) bun install # Configure ASK CLI (opens browser for Amazon login). Note this takes an ungodly # amount of time to do anything and it will look like everything is hung bun x ask configure ``` This will: 1. Open your browser to sign in with your Amazon Developer account 2. Store credentials in `~/.ask/cli_config` #### Verify Authentication ```bash bun x ask smapi list-skills-for-vendor ``` ### 3. Environment Variables The Lambda function needs credentials for the services it interacts with. Create a `.env` file in the project root (this file is gitignored): ```bash # .env # Rinnai API credentials for water heater control COGNITO_USERNAME=your@email.com COGNITO_PASSWORD=your_password # Home Assistant configuration HOME_ASSISTANT_URL=https://your-homeassistant.example.com HOME_ASSISTANT_TOKEN=your_long_lived_access_token ``` #### Rinnai Credentials The `COGNITO_USERNAME` and `COGNITO_PASSWORD` are your Rinnai app login credentials. These are used to authenticate with the Rinnai API for water recirculation control. #### Home Assistant Token To generate a long-lived access token in Home Assistant: 1. Go to your Home Assistant profile (click your username in the sidebar) 2. Scroll down to "Long-Lived Access Tokens" 3. Click "Create Token" 4. Give it a name (e.g., "Alexa Lambda") 5. Copy the token immediately (it won't be shown again) The `HOME_ASSISTANT_URL` should be the external URL of your Home Assistant instance. These credentials will be automatically deployed to Lambda when you use the `-Denv-file=.env` option. ## Build Steps | Step | Description | |------|-------------| | `zig build` | Build the bootstrap executable | | `zig build test` | Run unit tests | | `zig build awslambda_package` | Package Lambda function into zip | | `zig build awslambda_iam` | Create/verify IAM role | | `zig build awslambda_deploy` | Deploy Lambda function to AWS | | `zig build awslambda_run` | Invoke the deployed Lambda function | | `zig build ask_deploy` | Deploy Alexa skill metadata | | `zig build deploy` | Deploy both Lambda and Alexa skill | ### Build Options | Option | Description | Default | |--------|-------------|---------| | `-Doptimize=ReleaseFast` | Build with optimizations | Debug | | `-Dtarget=native` | Build for local machine | aarch64-linux | | `-Dfunction-name=NAME` | Lambda function name | exe name (house-control) | | `-Dprofile=PROFILE` | AWS profile to use | default | | `-Dregion=REGION` | AWS region | from profile | | `-Drole-name=ROLE` | IAM role name | lambda_basic_execution | | `-Dpayload=JSON` | Payload for `awslambda_run` | {} | | `-Denv-file=PATH` | Environment variables file | none | ## Deployment ### Prerequisites Before deploying, ensure you have: 1. **AWS Account** with credentials configured (see [Deployment Setup](#deployment-setup)) 2. **Amazon Developer Account** with ASK CLI authenticated (`bun x ask configure`) 3. **Credentials** in `.env` file (see [Environment Variables](#3-environment-variables)): - Rinnai account credentials (for water recirculation) - Home Assistant URL and long-lived access token (for device control) ### Full Deployment (Lambda + Alexa Skill) ```bash zig build deploy -Doptimize=ReleaseFast \ -Dprofile=personal \ -Dregion=us-west-2 \ -Denv-file=.env ``` This command orchestrates a multi-step deployment pipeline: 1. **Build** - Compile Lambda function for arm64 2. **Package** - Create deployment zip with bootstrap executable 3. **Deploy Lambda** - Create/update function in AWS, set env vars from `.env` 4. **Generate skill.json** - Inject Lambda ARN into `skill.template.json` 5. **ASK Deploy** - Deploy Alexa skill metadata and interaction model 6. **Add Permission** - Grant Alexa permission to invoke Lambda with skill-specific token The permission step uses the skill ID (from `.ask/ask-states.json`) as an `event_source_token` condition, restricting invocation to only this specific Alexa skill rather than allowing any Alexa skill to invoke the Lambda. ### Lambda Only ```bash zig build awslambda_deploy -Doptimize=ReleaseFast \ -Dprofile=personal \ -Dregion=us-west-2 \ -Denv-file=.env ``` Note: This only deploys the Lambda function. To invoke the function from Alexa, you must also deploy the skill (`zig build deploy`) to set up the permission. ### Alexa Skill Only ```bash zig build ask_deploy ``` ## Project Structure ``` water_recirculation/ ├── build.zig # Build configuration ├── build.zig.zon # Dependencies ├── .env # Credentials (gitignored) ├── skill.template.json # Skill manifest template (Lambda ARN placeholder) ├── ask-resources.json # ASK CLI deployment config ├── package.json # Node.js deps for ASK CLI ├── src/ │ ├── main.zig # Lambda entry point │ └── homeassistant.zig # Home Assistant API client ├── tools/ │ ├── gen-skill-json.zig # Generates skill.json from template │ └── add-alexa-permission.zig # Adds skill-specific Lambda permission ├── skill-package/ │ ├── skill.json # Generated (gitignored) │ └── interactionModels/ │ └── custom/ │ └── en-US.json # Interaction model with intents/slots └── .ask/ └── ask-states.json # ASK CLI state (contains skill ID) ``` ## Sample Utterances ### Water Recirculation - "start the hot water" - "turn on the hot water" - "heat the water" - "preheat the water" - "start recirculation" - "warm up the water" ### Home Assistant Device Control - "turn on the bedroom light" - "turn off the kitchen" - "toggle the basement fireplace" - "is the deck on" - "check the family room" ## Lambda Details - **Function**: `house-control` - **Region**: us-west-2 - **Architecture**: arm64 (Graviton) - **Runtime**: provided.al2023 ## Alexa Skill - **Skill ID**: `amzn1.ask.skill.5cc9bf04-8be9-4229-936d-49a22fae6a3e` - **Invocation**: "Alexa, ask house to..." ## License MIT