Home Assistant is an open-source home automation solution.
This repository facilitates packaging Home Assistant into an AWS IoT Greengrass V2 component named aws.greengrass.labs.HomeAssistant. This enables use cases where the customer reqires Home Assistant for local control, but also requires integration with AWS services at the edge and in the cloud.
Using the Home Assistant MQTT Integration, Home Assistant can publish and subscribe to topics on either or both of AWS IoT Core and the Greengrass local Moquette MQTT broker. This allows integration with the cloud, other Greengrass components on the same device and/or with other devices on the local network. Home Assistant can therefore leverage AWS-managed Greengrass components, custom Greengrass components, community Greengrass components and AWS services to deliver powerful home automation solutions that extend Home Assistant's capabilities.
An overview of the system architecture is presented below.
The aws.greengrass.labs.HomeAssistant component is a thin wrapper around a conventional Home Assistant Container deployment.
Home Assistant Container is delivered as a Docker image on Docker Hub and on GitHub. This Greengrass component downloads the selected Docker image from Docker Hub or GitHub with the help of the Docker application manager managed component.
Home Assistant configuration files are designed to be split as the solution scales. By convention, secrets are typically separated from the rest of the configuration and stored in a file named secrets.yaml. This Greengrass component handles secrets.yaml by storing it as a secret in AWS Secrets Manager in the cloud. At the edge, this component retrieves the secrets.yaml file from Secrets Manager with the help of the Secret manager managed component. From the developer machine, the contents of the secrets directory are placed into the Secrets Manager secret by calling create_config_secret.py.
As shown in blue on the architecture diagram, Home Assistant can use its MQTT integration to connect directly to AWS IoT Core. Alternatively, and more powerfully, Home Assistant can instead connect to the local Greengrass Moquette MQTT broker. This is option is shown in red. If Home Assistant and other devices on the local network are registered as Local Client Devices with Greengrass, this architecture allows Home Assistant to communicate with those other devices via the broker and with other Greengrass components via Greengrass Interprocess Communication. Furthermore, the MQTT bridge connects AWS IoT Core as an additional publisher and subscriber, facilitating cloud integration as well.
Item | Description |
---|---|
/artifacts | Greengrass V2 component artifacts that run on the Greengrass edge runtime. |
/cicd | CDK Typescript app for a CodePipeline CI/CD pipeline. |
/images | Images for README files. |
/libs | Python libraries shared by Python scripts. |
/secrets | Home Assistant secrets (secrets.yaml and optional certificates). |
/tests | Pytest unit tests. |
create_config_secret.py | Creates or updates the Home Assistant configuration secret in Secrets Manager. |
deploy_component_version.py | Deploys a component version to the Greengrass core device target. |
gdk_build.py | Custom build script for the Greengrass Development Kit (GDK) - Command Line Interface. |
gdk-config.json | Configuration for the Greengrass Development Kit (GDK) - Command Line Interface. |
recipe.json | Greengrass V2 component recipe template. |
quickstart.sh | Creates a secret, and creates and deploys a component version in a single operation. |
This component requires that the Greengrass device be running a Linux operating system. It supports all architectures supported by Greengrass itself.
The Greengrass edge runtime needs to be deployed to a suitable machine, virtual machine or EC2 instance. Please see the Home Assistant installation guide for information on the resources required.
Your core device must meet the requirements to run Docker containers using Docker Compose and Docker Hub.
This component requires both python3 and pip3 to be installed on the core device.
Assuming the bucket name in gdk-config.json is left unchanged, this component downloads artifacts from an S3 bucket named greengrass-home-assistant-REGION-ACCOUNT. Therefore your Greengrass core device role must allow the s3:GetObject permission for this bucket. For more information: https://docs.aws.amazon.com/greengrass/v2/developerguide/device-service-role.html#device-service-role-access-s3-bucket
Additionally, this component downloads sensitive Home Assistant configuration from Secrets Manager. Therefore your Greengrass core device role must also allow the secretsmanager:GetSecretValue permission for the greengrass=home-assistant-ID secret.
Policy template to add to your device role (substituting correct values for ACCOUNT, REGION and ID):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::greengrass-home-assistant-REGION-ACCOUNT/*"
},
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "arn:aws:secretsmanager:REGION:ACCOUNT:secret:greengrass-home-assistant-ID"
}
]
}
It may be necessary to upgrade your AWS CLI if you wish to use any greengrassv2 commands, as these are relatively recent additions to the CLI.
Most of the scripts in this repository are Python scripts. They are Python 3 scripts and hence python3 and pip3 are required.
Package dependencies can be resolved as follows:
pip3 install -r requirements.txt
Please consider to use a virtual environment.
Boto3 is included in the package dependencies and therefore your machine requires appropriate credentials.
This component makes use of the Greengrass Development Kit (GDK) - Command Line Interface (CLI). This can be installed as follows:
pip3 install git+https://github.com/aws-greengrass/aws-greengrass-gdk-cli.git
The quickstart.sh script is a Bash script. If using a Windows machine, you will need a Bash environment. Alternatively you can run the Python scripts individually.
The jq utility is used by quickstart.sh. Release packages for Linux, OS X and Windows are available on the jq site.
Alternatively, Ubuntu includes a jq package:
sudo apt update
sudo apt install jq
Here we define two ways to get started: Quickstart or Slowstart.
All scripts are compatible with Linux, Mac or Windows operating systems, provided a Bash environment is available.
The quickstart.sh bash script is supplied to help you get going fast. It rolls the constituent steps up into a single command.
Before running the script, users must deploy Greengrass V2 to a physical machine, virtual machine or EC2 instance, meeting all of the prerequisites including the requirements to run Docker containers using Docker Compose and Docker Hub. Addtionally, users must set the AWS region in gdk-config.json.
It is not necessary to perform any Home Assistant configuration changes. Out of the box, Home Assistant will be deployed with the latest stable version and with default configuration.
The Quickstart script will:
The script accepts 1 argument: the Greengrass Core device name.
Example execution:
bash quickstart.sh MyCoreDeviceThingName
For any serious use of the component, Quickstart shall not be appropriate.
If not using Quickstart, you must perform the following steps:
For iterative configuration changes, repeat steps as appropriate.
Example of steps 8, 9, 10 and 12:
python3 create_config_secret.py
gdk component build
gdk component publish
python3 deploy_component_version.py 1.0.0 MyCoreDeviceThingName
This example:
This repository offers a CodePipeline CI/CD pipeline as a CDK application. This can be optionally deployed to the same account as the Greengrass core.
This CI/CD pipeline automates steps 9, 10 and 12. With the pipeline deployed, users can make iterative configuration changes, update the configuration secret using create_config_secret.py, and then trigger the CI/CD pipeline to handle the rest.
Configuration of Home Assistant can be done predominantly through its user interface. However, it can also be configured using the YAML files in artifacts/config and secrets. Please consult the Home Assistant configuration documentation for details.
The configuration files in this projects are merely skeleton files. Home Assistant can be deployed with these files, yielding a greenfields installation.
Production deployments should reference a specific Docker image tag (not just latest) in artifacts/docker-compose.yml.
Docker images from Home Assistant's GitHub releases can be used directly as the image in artifacts/docker-compose.yml.
Here we present Home Assistant configuration options to integrate with AWS IoT Core and AWS IoT Greengrass.
We can use the MQTT Integration to connect Home Assistant directly to AWS IoT Core. Firstly create a Thing representing Home Assistant, and obtain the device certificate, private key and CA certificate. These certificates and keys should NOT be committed to your source repository and thus we instead disseminate them to Greengrass using Secrets Manager. The certificates and key should be added to the secrets directory. An example structure:
secrets/secrets.yaml
secrets/mqtt/AmazonRootCA1.pem
secrets/mqtt/dc536a53c3fcbce54833f9d90ab3ef1bd54523b4f371f60a811c0970dc8d4d82-certificate.pem.crt
secrets/mqtt/dc536a53c3fcbce54833f9d90ab3ef1bd54523b4f371f60a811c0970dc8d4d82-private.pem.key
Obtain the AWS IoT Core endpoint:
aws iot describe-endpoint --endpoint-type iot:Data-ATS
{
"endpointAddress": "ENDPOINTID-ats.iot.REGION.amazonaws.com"
}
And add that to a secret in secrets/secrets.yaml:
aws_iot_core_endpoint: ENDPOINTID-ats.iot.REGION.amazonaws.com
Update the secret in Secrets Manager:
python3 create_config_secret.py
Files to add to secret: ['secrets/secrets.yaml', 'secrets/mqtt/dc536a53c3fcbce54833f9d90ab3ef1bd54523b4f371f60a811c0970dc8d4d82-certificate.pem.crt', 'secrets/mqtt/dc536a53c3fcbce54833f9d90ab3ef1bd54523b4f371f60a811c0970dc8d4d82-private.pem.key', 'secrets/mqtt/AmazonRootCA1.pem']
Updating the Home Assistant secret greengrass-home-assistant
Successfully updated the Home Assistant secret
Update the artifacts/config/configuration.yaml to add the AWS IoT Core connection information for the MQTT integration within Home Assistant (where the Thing name is "home-assistant"):
# Example configuration.yaml entry for connecting to IoT Core
mqtt:
broker: !secret aws_iot_core_endpoint
port: 8883
certificate: /config/mqtt/AmazonRootCA1.pem
client_key: /config/mqtt/dc536a53c3fcbce54833f9d90ab3ef1bd54523b4f371f60a811c0970dc8d4d82-private.pem.key
client_cert: /config/mqtt/dc536a53c3fcbce54833f9d90ab3ef1bd54523b4f371f60a811c0970dc8d4d82-certificate.pem.crt
client_id: home-assistant
tls_insecure: false
tls_version: '1.2'
protocol: '3.1.1'
And then create and deploy a new component version.
Greengrass V2 includes an AWS-managed Moquette MQTT broker component. This can be deployed to Greengrass to allow Greengrass components and devices on your local network to communicate with each other, without relying on an internet connection to AWS IoT Core.
Using the MQTT Integration, Home Assistant can be a "local IoT device" that connects to the Moquette broker. Additionally, Greengrass V2 includes an AWS-managed MQTT Bridge component. When this is also deployed, Home Assistant can use its MQTT Integration to communicate with local devices, Greengrass components and AWS IoT Core; the best of all worlds.
To begin, update the Greengrass deployment to add the necessary components to your Greengrass core device:
As with connecting to AWS IoT Core, the device certificate and key should be added to your secrets. However, instead of the Amazon Root CA certificate being added for authenticating AWS IoT Core, you instead need the CA generated by the component installations; this can be found at /greengrass/v2/work/aws.greengrass.clientdevices.Auth/ca.pem on your Greengrass device and copied to your secrets directory on your developer machine. These certificates and keys should NOT be committed to your source repository and thus we instead disseminate them to Greengrass using Secrets Manager.
secrets/secrets.yaml
secrets/mqtt/ca.pem
secrets/mqtt/dc536a53c3fcbce54833f9d90ab3ef1bd54523b4f371f60a811c0970dc8d4d82-certificate.pem.crt
secrets/mqtt/dc536a53c3fcbce54833f9d90ab3ef1bd54523b4f371f60a811c0970dc8d4d82-private.pem.key
Update the secrets in Secrets Manager:
python3 create_config_secret.py
Files to add to secret: ['secrets/secrets.yaml', 'secrets/mqtt/dc536a53c3fcbce54833f9d90ab3ef1bd54523b4f371f60a811c0970dc8d4d82-certificate.pem.crt', 'secrets/mqtt/dc536a53c3fcbce54833f9d90ab3ef1bd54523b4f371f60a811c0970dc8d4d82-private.pem.key', 'secrets/mqtt/ca.pem']
Updating the Home Assistant secret greengrass-home-assistant
Successfully updated the Home Assistant secret
Update the artifacts/config/configuration.yaml to add the Moquette broker connection information for the MQTT integration within Home Assistant (where the Thing name is "home-assistant"):
# Example configuration.yaml entry for connecting to the Greengrass MQTT broker (Moquette)
mqtt:
# Moquette is on the same machine as Home Assistant
broker: localhost
port: 8883
# CA certificate copied from /greengrass/v2/work/aws.greengrass.clientdevices.Auth/ca.pem
certificate: /config/mqtt/ca.pem
client_key: /config/mqtt/dc536a53c3fcbce54833f9d90ab3ef1bd54523b4f371f60a811c0970dc8d4d82-private.pem.key
client_cert: /config/mqtt/dc536a53c3fcbce54833f9d90ab3ef1bd54523b4f371f60a811c0970dc8d4d82-certificate.pem.crt
client_id: home-assistant
tls_insecure: false
tls_version: '1.2'
protocol: '3.1.1'
And then create and deploy a new component version.
Home Assistant supports secure remote access if you have a domain name and/or a static IP address.
Alternatively, you can enable HTTPS on your local network using self-signed certificates. These can be generated using openssl as follows:
openssl req -sha256 -addext "subjectAltName = IP:xxx.xxx.xxx.xxx" -newkey rsa:4096 -nodes -keyout privkey.pem -x509 -days 730 -out fullchain.pem
These certificates should NOT be committed to your source repository and thus we instead disseminate them to Greengrass using Secrets Manager. The certificates should be added to the secrets directory. An example structure:
secrets/secrets.yaml
secrets/https/fullchain.pem
secrets/https/privkey.pem
Update the secrets in Secrets Manager:
python3 create_config_secret.py
Files to add to secret: ['secrets/secrets.yaml', 'secrets/https/fullchain.pem', 'secrets/https/privkey.pem']
Updating the Home Assistant secret greengrass-home-assistant
Successfully updated the Home Assistant secret
And then create and deploy a new component version.
Removing this component from your deployment will not remove all vestiges from your Greengrass core device. Additional steps:
If this component is deployed with default settings, persistent data and settings are located in /greengrass/v2/work/aws.greengrass.labs.HomeAssistant/config.
Tips for investigating failed deployments, or deployments that succeed but Home Assistant is still not working as expected.
Detailed component logs can be found on the Core Device in /greengrass/v2/logs/aws.greengrass.labs.HomeAssistant.log.
The Greengrass Core log file can be found at /greengrass/v2/logs/greengrass.log.
For more information please refer to the Greengrass V2 documentation: https://docs.aws.amazon.com/greengrass/v2/developerguide/monitor-logs.html
Consider to install the Greengrass Command Line Interface component to obtain greater visibility into the state of your core device.
The logs within the Docker container can be inspected as follows:
docker logs homeassistant
If a Docker image of the wrong architecture is deployed, it will fail to start. A message similar to the following indicates that the wrong architecture is being used:
standard_init_linux.go:228: exec user process caused: exec format error
This message will appear in /greengrass/v2/logs/aws.greengrass.labs.HomeAssistant.log.
To resolve incorrect architecture, please check the available architectures for the image tag. Image tags on DockerHub do not always support all architectures. Update docker-compose.yml and deploy a new version of the component.
The Greengrass Secret Manager component needs to fetch the configuration secret from the cloud, for any changes to secrets.yaml or the certificates to be seen by the Home Assistant component. The Secret Manager will not necessarily fetch the secret even when a new version of the component is deployed. Restart or reboot the core device to force a fetch.
The deployed secrets.yaml can be found at /greengrass/v2/work/aws.greengrass.labs.HomeAssistant/secrets.yaml.
Static analysis is performed using Pylint. Example execution:
pylint artifacts libs tests *.py
Unit tests are performed using pytest and moto.
Example execution:
pytest --cov=artifacts --cov=.
Producing an HTML coverage report into the htmlcov directory:
pytest --cov=artifacts --cov=. --cov-report=html
Producing a coverage report for just the on-device artifacts (100% coverage):
pytest --cov=artifacts