diff --git a/esphomeyaml-edge/Dockerfile b/esphomeyaml-edge/Dockerfile index 6c81bcaf29..7816df2907 100644 --- a/esphomeyaml-edge/Dockerfile +++ b/esphomeyaml-edge/Dockerfile @@ -1,24 +1,81 @@ -# Dockerfile for HassIO edge add-on -ARG BUILD_FROM=homeassistant/amd64-base-ubuntu:latest +ARG BUILD_FROM=hassioaddons/ubuntu-base:2.2.0 +# hadolint ignore=DL3006 FROM ${BUILD_FROM} -RUN apt-get update && apt-get install -y --no-install-recommends \ +# Set shell +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +# Copy root filesystem +COPY rootfs / + +# Setup base system +ARG BUILD_ARCH=amd64 + +# Copy root filesystem +COPY rootfs / + +RUN \ + # Temporarily move nginx.conf (otherwise dpkg fails) + mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bkp \ + # Install add-on dependencies + && apt-get update \ + && apt-get install -y --no-install-recommends \ + # Python for esphomeyaml python \ python-pip \ python-setuptools \ + # Python Pillow for display component python-pil \ + # Git for esphomelib downloads git \ - && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* && \ - pip install --no-cache-dir --no-binary :all: platformio && \ - platformio settings set enable_telemetry No && \ - platformio settings set check_libraries_interval 1000000 && \ - platformio settings set check_platformio_interval 1000000 && \ - platformio settings set check_platforms_interval 1000000 + # Ping for dashboard online/offline status + iputils-ping \ + # NGINX proxy + nginx \ + \ + && mv /etc/nginx/nginx.conf.bkp /etc/nginx/nginx.conf \ + \ + && pip2 install --no-cache-dir --no-binary :all: https://github.com/OttoWinter/esphomeyaml/archive/dev.zip \ + \ + # tzlocal for automatic timezone detection, requests for HassIO API + && pip2 install --no-cache-dir --no-binary :all: tzlocal \ + \ + # Change some platformio settings + && platformio settings set enable_telemetry No \ + && platformio settings set check_libraries_interval 1000000 \ + && platformio settings set check_platformio_interval 1000000 \ + && platformio settings set check_platforms_interval 1000000 \ + \ + # Build an empty platformio project to force platformio to install all fw build dependencies + # The return-code will be non-zero since there's nothing to build. + && (platformio run -d /opt/pio; echo "Done") \ + \ + # Cleanup + && rm -fr \ + /tmp/* \ + /var/{cache,log}/* \ + /var/lib/apt/lists/* \ + /opt/pio/ -COPY platformio.ini /pio/platformio.ini -RUN platformio run -d /pio; rm -rf /pio +# Build arugments +ARG BUILD_DATE +ARG BUILD_REF +ARG BUILD_VERSION -RUN pip install --no-cache-dir git+https://github.com/OttoWinter/esphomeyaml.git@dev#egg=esphomeyaml && \ - pip install --no-cache-dir pillow tzlocal - -CMD ["esphomeyaml", "/config/esphomeyaml", "dashboard"] +# Labels +LABEL \ + io.hass.name="esphomeyaml" \ + io.hass.description="Manage and program ESP8266/ESP32 microcontrollers through YAML configuration files" \ + io.hass.arch="${BUILD_ARCH}" \ + io.hass.type="addon" \ + io.hass.version=${BUILD_VERSION} \ + maintainer="Otto Winter " \ + org.label-schema.description="Manage and program ESP8266/ESP32 microcontrollers through YAML configuration files" \ + org.label-schema.build-date=${BUILD_DATE} \ + org.label-schema.name="esphomeyaml" \ + org.label-schema.schema-version="1.0" \ + org.label-schema.url="https://esphomelib.com" \ + org.label-schema.usage="https://github.com/OttoWinter/esphomeyaml/tree/dev/esphomeyaml-edge/README.md" \ + org.label-schema.vcs-ref=${BUILD_REF} \ + org.label-schema.vcs-url="https://github.com/OttoWinter/esphomeyaml" \ + org.label-schema.vendor="esphomeyaml" diff --git a/esphomeyaml-edge/README.md b/esphomeyaml-edge/README.md new file mode 100644 index 0000000000..bf395f50ca --- /dev/null +++ b/esphomeyaml-edge/README.md @@ -0,0 +1,100 @@ +# Esphomeyaml HassIO Add-On + +![esphomeyaml logo][logo.png] + +## WARNING! THIS IS AN EDGE VERSION! + +You're viewing the edge (latest build) of the esphomeyaml add-on. This +contains the latest source code with all the latest features. However, the +code in this version of the add-on is unstable and might break at any moment. + +It is intended for: + +- people who want to test the latest features. +- people who can manually re-flash their node via USB if something breaks. +- Developers + +## About + +This add-on allows you to manage and program your ESP8266 and ESP32 based microcontrollers +directly through HassIO **with no programming experience required**. All you need to do +is write YAML configuration files; the rest (over-the-air updates, compiling) is all +handled by esphomeyaml. + +[Click here for the full documentation][docs] + +![esphomeyaml dashboard screenshot][screenshot.png] + +## Installation + +To install this HassIO add-on you need to add the esphomeyaml add-on repository +first: + +1. [Add esphomeyaml's HassIO add-ons repository][https://github.com/OttoWinter/esphomeyaml] to your HassIO instance. You can do this by navigating to the "Add-on Store" tab in the HassIO panel and then entering https://github.com/OttoWinter/esphomeyaml in the "Add new repository by URL" field. +2. Now scroll down to the bottom of the page and select the "esphomeyaml-edge" add-on. +3. Press install to download the add-on and unpack it on your machine. This can take some time. +4. Optional: If you're using SSL certificates and want to encrypt your communication to this add-on, please enter `true` into the `ssl` field and set the `fullchain` and `certfile` options accordingly. +5. Start the add-on, check the logs of the add-on to see if everything went well. +6. Click "OPEN WEB UI" to open the esphomeyaml dashboard. You will be asked for your Home Assistant credentials - esphomeyaml uses HassIO's authentication system to log you in. + +**NOTE**: Installation on RPis running in 64-bit mode is currently not possible. Please use the 32-bit variant of HassOS instead. + +## Docker status + +![Supports armhf Architecture][armhf-shield] +![Supports amd64 Architecture][amd64-shield] +![Supports i386 Architecture][i386-shield] + +[![Docker Layers][layers-shield]][microbadger] +[![Docker Pulls][pulls-shield]][dockerhub] + +## Configuration + +**Note**: _Remember to restart the add-on when the configuration is changed._ + +Example add-on configuration: + +```json +{ + "ssl": false, + "certfile": "fullchain.pem", + "keyfile": "privkey.pem" +} +``` + +### Option: `ssl` + +Enables/Disables encrypted SSL (HTTPS) connections to the web server of this add-on. Set it to `true` to encrypt communications, `false` otherwise. Please note that if you set this to `true` you must also specify a `certfile` and `keyfile`. + +### Option: `certfile` + +The certificate file to use for SSL. + +**Note**: _The file MUST be stored in `/ssl/`, which is the default for Hass.io_ + +### Option: `keyfile` + +The private key file to use for SSL. + +**Note**: _The file MUST be stored in `/ssl/`, which is the default for Hass.io_ + +### Option: `leave_front_door_open` + +Adding this option to the add-on configuration allows you to disable +authentication by setting it to `true`. + +## Embedding into Home Assistant + +It is possible to embed the esphomeyaml dashboard directly into +Home Assistant, allowing you to access your ESP nodes through +the Home Assistant frontend using the `panel_iframe` component. + +Example configuration: + +```yaml +panel_iframe: + esphomeyaml: + title: esphomeyaml Dashboard + icon: mdi:code-brackets + url: https://addres.to.your.hass.io:6052 +``` diff --git a/esphomeyaml-edge/build.json b/esphomeyaml-edge/build.json index f60fa4f7fe..eb0295384a 100644 --- a/esphomeyaml-edge/build.json +++ b/esphomeyaml-edge/build.json @@ -1,10 +1,10 @@ { - "squash": false, - "build_from": { - "aarch64": "homeassistant/aarch64-base-ubuntu:latest", - "amd64": "homeassistant/amd64-base-ubuntu:latest", - "armhf": "homeassistant/armhf-base-ubuntu:latest", - "i386": "homeassistant/i386-base-ubuntu:latest" - }, - "args": {} + "squash": false, + "build_from": { + "aarch64": "hassioaddons/ubuntu-base-aarch64:2.2.0", + "amd64": "hassioaddons/ubuntu-base-amd64:2.2.0", + "armhf": "hassioaddons/ubuntu-base-armhf:2.2.0", + "i386": "hassioaddons/ubuntu-base-i386:2.2.0" + }, + "args": {} } diff --git a/esphomeyaml-edge/config.json b/esphomeyaml-edge/config.json index 951d7d56cc..afdb500c6f 100644 --- a/esphomeyaml-edge/config.json +++ b/esphomeyaml-edge/config.json @@ -2,32 +2,41 @@ "name": "esphomeyaml-edge", "version": "dev", "slug": "esphomeyaml-edge", - "description": "Development build of the esphomeyaml HassIO add-on.", - "url": "https://esphomelib.com/esphomeyaml/index.html", - "startup": "application", + "description": "Development Version! Manage and program ESP8266/ESP32 microcontrollers through YAML configuration files", + "url": "https://github.com/OttoWinter/esphomeyaml/tree/dev/esphomeyaml-edge/README.md", "webui": "http://[HOST]:[PORT:6052]", - "boot": "auto", - "ports": { - "6052/tcp": 6052, - "6053/tcp": 6053 - }, + "startup": "application", "arch": [ "aarch64", "amd64", "armhf", "i386" ], - "auto_uart": true, + "hassio_api": true, + "auth_api": true, + "services": [ + "mqtt:want" + ], + "hassio_role": "default", + "homeassistant_api": false, + "host_network": false, + "boot": "auto", + "ports": { + "6052/tcp": 6052 + }, "map": [ + "ssl", "config:rw" ], "options": { - "password": "" + "ssl": false, + "certfile": "fullchain.pem", + "keyfile": "privkey.pem" }, "schema": { - "password": "str?" - }, - "environment": { - "ESPHOMEYAML_OTA_HOST_PORT": "6053" + "ssl": "bool", + "certfile": "str", + "keyfile": "str", + "leave_front_door_open": "bool?" } } diff --git a/esphomeyaml-edge/icon.png b/esphomeyaml-edge/icon.png new file mode 100644 index 0000000000..6018ac5fc7 Binary files /dev/null and b/esphomeyaml-edge/icon.png differ diff --git a/esphomeyaml-edge/logo.png b/esphomeyaml-edge/logo.png new file mode 100644 index 0000000000..cd37247307 Binary files /dev/null and b/esphomeyaml-edge/logo.png differ diff --git a/esphomeyaml-edge/rootfs/etc/cont-init.d/10-requirements.sh b/esphomeyaml-edge/rootfs/etc/cont-init.d/10-requirements.sh new file mode 100755 index 0000000000..3461cc024c --- /dev/null +++ b/esphomeyaml-edge/rootfs/etc/cont-init.d/10-requirements.sh @@ -0,0 +1,35 @@ +#!/usr/bin/with-contenv bash +# ============================================================================== +# Community Hass.io Add-ons: esphomeyaml +# This files check if all user configuration requirements are met +# ============================================================================== +# shellcheck disable=SC1091 +source /usr/lib/hassio-addons/base.sh + +# Check SSL requirements, if enabled +if hass.config.true 'ssl'; then + if ! hass.config.has_value 'certfile'; then + hass.die 'SSL is enabled, but no certfile was specified.' + fi + + if ! hass.config.has_value 'keyfile'; then + hass.die 'SSL is enabled, but no keyfile was specified' + fi + + if ! hass.file_exists "/ssl/$(hass.config.get 'certfile')"; then + if ! hass.file_exists "/ssl/$(hass.config.get 'keyfile')"; then + # Both files are missing, let's print a friendlier error message + text = "You enabled encrypted connections using the \"ssl\": true option. + However, the SSL files \"$(hass.config.get 'certfile')\" and \"$(hass.config.get 'keyfile')\" + were not found. If you're using HassIO on your local network and don't want + to encrypt connections to the esphomeyaml dashboard, you can manually disable + SSL by setting \"ssl\" to false." + hass.die "${text}" + fi + hass.die 'The configured certfile is not found' + fi + + if ! hass.file_exists "/ssl/$(hass.config.get 'keyfile')"; then + hass.die 'The configured keyfile is not found' + fi +fi diff --git a/esphomeyaml-edge/rootfs/etc/cont-init.d/20-nginx.sh b/esphomeyaml-edge/rootfs/etc/cont-init.d/20-nginx.sh new file mode 100755 index 0000000000..768fb71bf1 --- /dev/null +++ b/esphomeyaml-edge/rootfs/etc/cont-init.d/20-nginx.sh @@ -0,0 +1,24 @@ +#!/usr/bin/with-contenv bash +# ============================================================================== +# Community Hass.io Add-ons: esphomeyaml +# Configures NGINX for use with esphomeyaml +# ============================================================================== +# shellcheck disable=SC1091 +source /usr/lib/hassio-addons/base.sh + +declare certfile +declare keyfile + +mkdir -p /var/log/nginx + +# Enable SSL +if hass.config.true 'ssl'; then + rm /etc/nginx/nginx.conf + mv /etc/nginx/nginx-ssl.conf /etc/nginx/nginx.conf + + certfile=$(hass.config.get 'certfile') + keyfile=$(hass.config.get 'keyfile') + + sed -i "s/%%certfile%%/${certfile}/g" /etc/nginx/nginx.conf + sed -i "s/%%keyfile%%/${keyfile}/g" /etc/nginx/nginx.conf +fi diff --git a/esphomeyaml-edge/rootfs/etc/nginx/nginx-ssl.conf b/esphomeyaml-edge/rootfs/etc/nginx/nginx-ssl.conf new file mode 100755 index 0000000000..81484f5b6d --- /dev/null +++ b/esphomeyaml-edge/rootfs/etc/nginx/nginx-ssl.conf @@ -0,0 +1,62 @@ +worker_processes 1; +pid /var/run/nginx.pid; +error_log stderr; + +events { + worker_connections 1024; +} + +http { + access_log stdout; + include mime.types; + default_type application/octet-stream; + sendfile on; + keepalive_timeout 65; + + upstream esphomeyaml { + ip_hash; + server 127.0.0.1:80; + } + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } + + server { + server_name hassio.local; + listen 6052 default_server ssl; + root /dev/null; + + ssl_certificate /ssl/%%certfile%%; + ssl_certificate_key /ssl/%%keyfile%%; + ssl_protocols TLSv1.2; + ssl_prefer_server_ciphers on; + ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA; + ssl_ecdh_curve secp384r1; + ssl_session_timeout 10m; + ssl_session_cache shared:SSL:10m; + ssl_session_tickets off; + ssl_stapling on; + ssl_stapling_verify on; + + # Redirect http requests to https on the same port. + # https://rageagainstshell.com/2016/11/redirect-http-to-https-on-the-same-port-in-nginx/ + error_page 497 https://$http_host$request_uri; + + location / { + proxy_redirect off; + proxy_pass http://esphomeyaml; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_set_header Authorization ""; + + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_host; + proxy_set_header X-NginX-Proxy true; + } + } +} diff --git a/esphomeyaml-edge/rootfs/etc/nginx/nginx.conf b/esphomeyaml-edge/rootfs/etc/nginx/nginx.conf new file mode 100755 index 0000000000..203e1ac035 --- /dev/null +++ b/esphomeyaml-edge/rootfs/etc/nginx/nginx.conf @@ -0,0 +1,46 @@ +worker_processes 1; +pid /var/run/nginx.pid; +error_log stderr; + +events { + worker_connections 1024; +} + +http { + access_log stdout; + include mime.types; + default_type application/octet-stream; + sendfile on; + keepalive_timeout 65; + + upstream esphomeyaml { + ip_hash; + server 127.0.0.1:80; + } + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } + + server { + server_name hassio.local; + listen 6052 default_server; + root /dev/null; + + location / { + proxy_redirect off; + proxy_pass http://esphomeyaml; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_set_header Authorization ""; + + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_host; + proxy_set_header X-NginX-Proxy true; + } + } +} diff --git a/esphomeyaml-edge/rootfs/etc/services.d/esphomeyaml/finish b/esphomeyaml-edge/rootfs/etc/services.d/esphomeyaml/finish new file mode 100755 index 0000000000..4d0e9a35ff --- /dev/null +++ b/esphomeyaml-edge/rootfs/etc/services.d/esphomeyaml/finish @@ -0,0 +1,9 @@ +#!/usr/bin/execlineb -S0 +# ============================================================================== +# Community Hass.io Add-ons: esphomeyaml +# Take down the S6 supervision tree when esphomeyaml fails +# ============================================================================== +if -n { s6-test $# -ne 0 } +if -n { s6-test ${1} -eq 256 } + +s6-svscanctl -t /var/run/s6/services diff --git a/esphomeyaml-edge/rootfs/etc/services.d/esphomeyaml/run b/esphomeyaml-edge/rootfs/etc/services.d/esphomeyaml/run new file mode 100755 index 0000000000..47b600d2f4 --- /dev/null +++ b/esphomeyaml-edge/rootfs/etc/services.d/esphomeyaml/run @@ -0,0 +1,14 @@ +#!/usr/bin/with-contenv bash +# ============================================================================== +# Community Hass.io Add-ons: esphomeyaml +# Runs the esphomeyaml dashboard +# ============================================================================== +# shellcheck disable=SC1091 +source /usr/lib/hassio-addons/base.sh + +if hass.config.true 'leave_front_door_open'; then + export DISABLE_HA_AUTHENTICATION=true +fi + +hass.log.info "Starting esphomeyaml dashboard..." +exec esphomeyaml /config/esphomeyaml dashboard --port 80 --hassio diff --git a/esphomeyaml-edge/rootfs/etc/services.d/nginx/finish b/esphomeyaml-edge/rootfs/etc/services.d/nginx/finish new file mode 100755 index 0000000000..e0c2ac25ef --- /dev/null +++ b/esphomeyaml-edge/rootfs/etc/services.d/nginx/finish @@ -0,0 +1,9 @@ +#!/usr/bin/execlineb -S0 +# ============================================================================== +# Community Hass.io Add-ons: esphomeyaml +# Take down the S6 supervision tree when NGINX fails +# ============================================================================== +if -n { s6-test $# -ne 0 } +if -n { s6-test ${1} -eq 256 } + +s6-svscanctl -t /var/run/s6/services diff --git a/esphomeyaml-edge/rootfs/etc/services.d/nginx/run b/esphomeyaml-edge/rootfs/etc/services.d/nginx/run new file mode 100755 index 0000000000..51c18ab9a9 --- /dev/null +++ b/esphomeyaml-edge/rootfs/etc/services.d/nginx/run @@ -0,0 +1,10 @@ +#!/usr/bin/with-contenv bash +# ============================================================================== +# Community Hass.io Add-ons: esphomeyaml +# Runs the NGINX proxy +# ============================================================================== +# shellcheck disable=SC1091 +source /usr/lib/hassio-addons/base.sh + +hass.log.info "Starting NGINX..." +exec nginx -g "daemon off;" diff --git a/esphomeyaml-edge/rootfs/opt/pio/platformio.ini b/esphomeyaml-edge/rootfs/opt/pio/platformio.ini new file mode 100644 index 0000000000..7f6ab6851d --- /dev/null +++ b/esphomeyaml-edge/rootfs/opt/pio/platformio.ini @@ -0,0 +1,12 @@ +; This file allows the docker build file to install the required platformio +; platforms + +[env:espressif8266] +platform = espressif8266 +board = nodemcuv2 +framework = arduino + +[env:espressif32] +platform = espressif32 +board = nodemcu-32s +framework = arduino diff --git a/esphomeyaml-edge/screenshot.png b/esphomeyaml-edge/screenshot.png new file mode 100644 index 0000000000..193e01589b Binary files /dev/null and b/esphomeyaml-edge/screenshot.png differ