diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index 9713462..0000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,45 +0,0 @@ -FROM ubuntu:20.04 - -WORKDIR /workspaces - -# Default ENV -ENV LANG C.UTF-8 -ENV DEBIAN_FRONTEND noninteractive - -# Set shell -SHELL ["/bin/bash", "-o", "pipefail", "-c"] - -# Use the mirror protocol for a fast mirror -RUN sed -i -e 's/http:\/\/archive\.ubuntu\.com\/ubuntu\//mirror:\/\/mirrors\.ubuntu\.com\/mirrors\.txt/' /etc/apt/sources.list - -# Install docker, jq, socat -# https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/ -RUN apt-get update && apt-get install -y --no-install-recommends \ - apt-transport-https \ - ca-certificates \ - curl \ - dbus \ - software-properties-common \ - gpg-agent \ - git \ - jq \ - socat \ - sudo \ - && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - \ - && add-apt-repository "deb https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \ - && apt-get update && apt-get install -y --no-install-recommends \ - docker-ce \ - docker-ce-cli \ - containerd.io -# This is a development container. Don't bother to clean up apt cache, this way we have it handy later - -COPY .devcontainer/start_ha.sh /usr/local/bin/start_ha.sh - -# Install dependencies for the add-on development below. For example, if you're running Node.js, -# you may want something like the following... -# RUN apt-get install -y --no-install-recommends nodejs npm - -# Generate a machine-id for this container -RUN rm /etc/machine-id && dbus-uuidgen --ensure=/etc/machine-id - -ENV DEBIAN_FRONTEND=dialog diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 913bf0b..9d55028 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,29 +1,31 @@ -// For format details, see https://aka.ms/vscode-remote/devcontainer.json -// TODO: When https://github.com/microsoft/vscode-remote-release/issues/2129 is fixed, move to ${localWorkspaceFolderBasename}\ { - "name": "Home Assistant Add-On", - "context": "..", - "dockerFile": "Dockerfile", - "appPort": 8123, - "runArgs": [ - "-e", - "GIT_EDITOR=code --wait", - "--privileged" - ], - "settings": { - "terminal.integrated.shell.linux": "/bin/bash" - }, - "workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/test_hassio/addons/local/myaddon,type=bind,consistency=delegated", - "workspaceFolder": "/workspaces/test_hassio/addons/local/myaddon", - "mounts": [ - // Cache docker images between devcontainer rebuilds (and share between devcontainers) - "source=vsc-hassio-docker,target=/var/lib/docker,type=volume" - ] - - // Post-create command to initialize the workspace. For example, for a node.js add-on you may want: - // "postCreateCommand": "cd /workspaces/test_hassio/addons/local/myaddon && npm install", - // "extensions": [ - // "dbaeumer.vscode-eslint", - // "maty.vscode-mocha-sidebar" - // ] + "name": "HA Addon: TeslaMate", + "image": "ghcr.io/home-assistant/devcontainer:addons", + "appPort": ["7123:8123", "7357:4357"], + "postStartCommand": "sudo sed -i 's/export SUPERVISOR_VERSION=.*/export SUPERVISOR_VERSION=2024.03.1.dev1803/' /etc/supervisor_scripts/common && bash devcontainer_bootstrap", // Workaround until https://github.com/home-assistant/supervisor/issues/5021 is fixed" + "runArgs": ["-e", "GIT_EDITOR=code --wait", "--privileged"], + "containerEnv": { + "WORKSPACE_DIRECTORY": "${containerWorkspaceFolder}" + }, + "customizations": { + "vscode": { + "extensions": [ + "timonwong.shellcheck", + "esbenp.prettier-vscode" + ], + "settings": { + "terminal.integrated.profiles.linux": { + "zsh": { + "path": "/usr/bin/zsh" + } + }, + "terminal.integrated.defaultProfile.linux": "zsh", + "editor.formatOnPaste": false, + "editor.formatOnSave": true, + "editor.formatOnType": true, + "files.trimTrailingWhitespace": true + } + } + }, + "mounts": ["type=volume,target=/var/lib/docker"] } diff --git a/.devcontainer/start_ha.sh b/.devcontainer/start_ha.sh deleted file mode 100755 index 7262a35..0000000 --- a/.devcontainer/start_ha.sh +++ /dev/null @@ -1,103 +0,0 @@ -#!/bin/bash -set -eE - -DOCKER_TIMEOUT=30 -DOCKER_PID=0 - - -function start_docker() { - local starttime - local endtime - - echo "Starting docker..." - dockerd 2> /dev/null & - DOCKER_PID=$! - - echo "Waiting for docker to initialize..." - starttime="$(date +%s)" - endtime="$(date +%s)" - until docker info >/dev/null 2>&1; do - if [ $((endtime - starttime)) -le $DOCKER_TIMEOUT ]; then - sleep 1 - endtime=$(date +%s) - else - echo "Timeout while waiting for docker to come up" - exit 1 - fi - done - echo "Docker was initialized" -} - - -function stop_docker() { - local starttime - local endtime - - echo "Stopping in container docker..." - if [ "$DOCKER_PID" -gt 0 ] && kill -0 "$DOCKER_PID" 2> /dev/null; then - starttime="$(date +%s)" - endtime="$(date +%s)" - - # Now wait for it to die - kill "$DOCKER_PID" - while kill -0 "$DOCKER_PID" 2> /dev/null; do - if [ $((endtime - starttime)) -le $DOCKER_TIMEOUT ]; then - sleep 1 - endtime=$(date +%s) - else - echo "Timeout while waiting for container docker to die" - exit 1 - fi - done - else - echo "Your host might have been left with unreleased resources" - fi -} - - -function install() { - docker pull homeassistant/amd64-hassio-supervisor:dev - docker pull homeassistant/amd64-hassio-cli:dev -} - -function cleanup_hass_data() { - rm -rf /workspaces/test_hassio/{apparmor,backup,config.json,dns,dns.json,homeassistant,homeassistant.json,ingress.json,share,ssl,tmp,updater.json} - rm -rf /workspaces/test_hassio/addons/{core,data,git} -} - -function cleanup_docker() { - echo "Cleaning up stopped containers..." - docker rm $(docker ps -a -q) -} - -function run_supervisor() { - docker run --rm --privileged \ - --name hassio_supervisor \ - --security-opt seccomp=unconfined \ - --security-opt apparmor:unconfined \ - -v /run/docker.sock:/run/docker.sock \ - -v /run/dbus:/run/dbus \ - -v "/workspaces/test_hassio":/data \ - -v /etc/machine-id:/etc/machine-id:ro \ - -e SUPERVISOR_SHARE="/workspaces/test_hassio" \ - -e SUPERVISOR_NAME=hassio_supervisor \ - -e SUPERVISOR_DEV=1 \ - -e HOMEASSISTANT_REPOSITORY="homeassistant/qemux86-64-homeassistant" \ - homeassistant/amd64-hassio-supervisor:dev -} - -case "$1" in - "--cleanup") - echo "Cleaning up old environment" - cleanup_docker || true - cleanup_hass_data || true - exit 0;; - *) - echo "Creating development Home Assistant environment" - start_docker - trap "stop_docker" ERR - install - cleanup_docker || true - run_supervisor - stop_docker;; -esac \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.md b/.github/ISSUE_TEMPLATE/BUG_REPORT.md deleted file mode 100644 index 989912a..0000000 --- a/.github/ISSUE_TEMPLATE/BUG_REPORT.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: "Bug report \U0001F41B" -about: Report errors or unexpected behaviour -title: 'Bug Report' -labels: bug -assignees: 'matt-FFFFFF' - ---- - - - -**Describe the bug** - - -**Steps to reproduce** - -1. -2. - -**Screenshots** diff --git a/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md deleted file mode 100644 index 9e08ef1..0000000 --- a/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -name: "Feature request \U0001F680" -about: Suggest an idea for this project -title: 'Feature Request' -labels: enhancement -assignees: 'matt-FFFFFF' - ---- - - - -**Describe the solution you'd like** diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 2afa0a7..0000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -version: 2 - -updates: - - package-ecosystem: github-actions - directory: "/" - schedule: - interval: daily diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 0000000..c771e60 --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended", + ":disableDependencyDashboard" + ], + "prHourlyLimit": 4, + "prBodyTemplate": "{{{table}}}{{{warnings}}}{{{notes}}}{{{changelogs}}}", + "semanticCommits": "disabled", + "commitMessageTopic": "{{#if (containsString depName 'teslamate')}}TeslaMate{{else}}{{depName}}{{/if}}", + "customManagers": [ + { + "customType": "regex", + "fileMatch": "^build\\.json$", + "matchStrings": [ + "\"teslamate_version\": \"(?\\d+\\.\\d+\\.\\d+)\"" + ], + "datasourceTemplate": "github-releases", + "depNameTemplate": "teslamate-org/teslamate" + } + ], + "prBodyColumns": [ + "Package", + "Update", + "Change" + ] +} diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 0000000..98ec1f0 --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,32 @@ +name: Lint + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + lint: + name: Lint add-on + runs-on: ubuntu-latest + steps: + - name: โคต๏ธ Check out code from GitHub + uses: actions/checkout@v4.1.4 + + - name: ๐Ÿš€ Run Home Assistant Add-on Lint + uses: frenck/action-addon-linter@v2 + with: + path: "./" + + - name: Check versions match + run: | + docker_ver=$(grep "FROM teslamate/teslamate" Dockerfile | cut -d':' -f2) + build_ver=$(jq -r ".args.teslamate_version" build.json) + if [ "$docker_ver" != "$build_ver" ]; then + echo -e "\033[31;1mTeslaMate versions don't match: Dockerfile => ${docker_ver} | build.json => ${build_ver}\033[0m" + exit 1 + fi + echo -e "\033[32;1mTeslaMate versions match: Dockerfile => ${docker_ver} | build.json => ${build_ver}\033[0m" diff --git a/.github/workflows/publisher.yaml b/.github/workflows/publisher.yaml new file mode 100644 index 0000000..09ef611 --- /dev/null +++ b/.github/workflows/publisher.yaml @@ -0,0 +1,51 @@ +name: "Publish" + +on: + release: + types: [published] + workflow_dispatch: + workflow_call: + inputs: + version: + required: false + type: string + +jobs: + publish: + name: Publish + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + strategy: + matrix: + arch: ["amd64", "armv7", "aarch64"] + + steps: + - name: Checkout the repository + uses: actions/checkout@v4.1.4 + + - name: Get version + run: | + version=${{ inputs.version }} + if [ -n "$version" ]; then + echo "latest_release=$version" >> $GITHUB_ENV + else + echo "latest_release=$(curl --header "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" --silent https://api.github.com/repos/$GITHUB_REPOSITORY/releases/latest | jq -r .tag_name | sed s/v// )" >> $GITHUB_ENV + fi + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3.1.0 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and publish + uses: home-assistant/builder@master + with: + args: | + --${{ matrix.arch }} \ + --version ${{ env.latest_release }} \ + --target /data/ \ + --addon diff --git a/.github/workflows/release.yml b/.github/workflows/releaser.yml similarity index 56% rename from .github/workflows/release.yml rename to .github/workflows/releaser.yml index 4fbbbe1..d0133b0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/releaser.yml @@ -6,20 +6,26 @@ on: required: true default: i -name: Create release +name: Releaser jobs: - build: - name: create_release + release: + name: Create Release runs-on: ubuntu-latest + outputs: + version: ${{ steps.semver.outputs.semver }} + permissions: + contents: write + packages: write steps: - - name: Checkout Teslamate + - name: Checkout repository uses: actions/checkout@v4 with: path: teslamate + token: ${{ secrets.GITHUB_TOKEN }} - name: Get latest release run: | - echo "latest_release=$(curl --silent https://api.github.com/repos/$GITHUB_REPOSITORY/releases/latest | jq -r .tag_name | sed s/v// )" >> $GITHUB_ENV + echo "latest_release=$(curl --header "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" --silent https://api.github.com/repos/$GITHUB_REPOSITORY/releases/latest | jq -r .tag_name | sed s/v// )" >> $GITHUB_ENV - name: Increment semver id: semver uses: matt-FFFFFF/simple-semver@v0.1.1 @@ -33,34 +39,42 @@ jobs: git tag -a v${{ steps.semver.outputs.semver }} -m 'Release automation' git push --tags working-directory: ${{ github.workspace }}/teslamate - - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.REPO_PAT }} + - name: Create release + uses: softprops/action-gh-release@v2.0.4 with: tag_name: v${{ steps.semver.outputs.semver }} - release_name: Release v${{ steps.semver.outputs.semver }} - body_path: ${{ github.workspace }}/teslamate/CHANGELOG.md + generate_release_notes: true draft: false prerelease: false - - name: Checkout repository - uses: actions/checkout@v4 + token: ${{ secrets.GITHUB_TOKEN }} + - name: Checkout addon repo + uses: actions/checkout@v4.1.4 with: path: repo - repository: matt-FFFFFF/hassio-addon-repository - token: ${{ secrets.REPO_PAT }} + repository: lildude/ha-addons + token: ${{ secrets.HA_ADDONS_PAT }} + - name: Update addon repo run: | - cp -vf ${{ github.workspace }}/teslamate/*.png ${{ github.workspace }}/repo/teslamate + cp -vf ${{ github.workspace }}/teslamate/*.png ${{ github.workspace }}/repo/teslamate cp -vf ${{ github.workspace }}/teslamate/*.md ${{ github.workspace }}/repo/teslamate jq '.version="${{ steps.semver.outputs.semver }}"' < ${{ github.workspace }}/teslamate/config.json > ${{ github.workspace }}/repo/teslamate/config.json + echo "$(curl --silent --header "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/$GITHUB_REPOSITORY/releases/latest | jq -r .body)" > ${{ github.workspace }}/repo/teslamate/CHANGELOG.md - name: Add changes to addon repo run: | if [ "$(git status -s)" ]; then git add . - git commit -m 'Update from hassio-addon-teslamate' + git commit -m 'Update ha-addon-teslamate to v${{ steps.semver.outputs.semver }}' git push fi working-directory: ${{ github.workspace }}/repo/teslamate + build: + name: Build addon + needs: release + permissions: + contents: read + packages: write + uses: ./.github/workflows/publisher.yaml + with: + version: ${{ needs.release.outputs.version }} diff --git a/.github/workflows/teslamate.yml b/.github/workflows/teslamate.yml deleted file mode 100644 index 0e3910e..0000000 --- a/.github/workflows/teslamate.yml +++ /dev/null @@ -1,117 +0,0 @@ -name: Teslamate CI/CD - -on: - push: - branches: - - main - paths: - - '**' - - '!**.md' - - '!.github/**' - release: - types: [published] - pull_request: - paths: - - '**' - - '!**.md' - -env: - DOCKER_USERNAME: mattffffff - -jobs: - build: - - runs-on: ubuntu-latest - - strategy: - matrix: - arch: [amd64, armhf, armv7, aarch64] - fail-fast: true - - steps: - - uses: actions/checkout@v4 - with: - submodules: 'true' - - name: Set TESLAMATE_TAG - run: | - echo "TESLAMATE_TAG=$(jq -r '.args.TESLAMATE_TAG ' < build.json)" >> $GITHUB_ENV - - name: Docker version - run: docker version - - name: Setup qemu - id: qemu - uses: docker/setup-qemu-action@v3 - with: - platforms: all - - name: Install buildx - id: buildx - uses: docker/setup-buildx-action@v3 - with: - version: latest - - name: Available platforms - run: echo ${{ steps.buildx.outputs.platforms }} - - name: Set PLATFORM & ARCH variables - run: | - case "${{ matrix.arch }}" in - "amd64" ) - echo "PLATFORM=linux/amd64" >> $GITHUB_ENV - echo "ARCH=amd64" >> $GITHUB_ENV - ;; - "aarch64" ) - echo "PLATFORM=linux/arm64" >> $GITHUB_ENV - echo "ARCH=aarch64" >> $GITHUB_ENV - ;; - "armhf" ) - echo "PLATFORM=linux/arm/v7" >> $GITHUB_ENV - echo "ARCH=armhf" >> $GITHUB_ENV - ;; - "armv7" ) - echo "PLATFORM=linux/arm/v7" >> $GITHUB_ENV - echo "ARCH=arm" >> $GITHUB_ENV - ;; - esac - - name: Update config.json if release - run: | - export RELEASE=$( echo $GITHUB_REF | cut -d/ -f3 | sed s/v// ) - jq ".version=\"$RELEASE\"" < config.json > config_release.json - rm config.json && mv config_release.json config.json - if: ${{ github.event_name == 'release' }} - - name: Set environment variables from config.json - run: | - echo "ADDON_VERSION=$(jq -r .version < config.json)" >> $GITHUB_ENV - echo "ADDON_NAME=$(jq -r .name < config.json)" >> $GITHUB_ENV - echo "ADDON_DESCRIPTION=$(jq -r .description < config.json)" >> $GITHUB_ENV - - name: Login to docker hub - run: sudo docker login -u $DOCKER_USERNAME -p ${{ secrets.DOCKER_PASSWORD }} - - name: Buildx build (if not main) - run: | - DOCKER_CLI_EXPERIMENTAL=enabled sudo docker buildx build \ - --pull \ - --platform=$PLATFORM \ - --build-arg TESLAMATE_TAG=$TESLAMATE_TAG \ - --build-arg ARCH=$ARCH \ - --label io.hass.type="addon" \ - --label io.hass.name="$ADDON_NAME" \ - --label io.hass.description="$ADDON_DESCRIPTION" \ - --label io.hass.version="$ADDON_VERSION" \ - --label io.hass.arch="${{ matrix.arch }}" \ - --label io.hass.url="https://github.com/matt-FFFFFF/hassio-addon-repository/blob/main/teslamate/README.md" \ - -t $DOCKER_USERNAME/teslamate-${{ matrix.arch }}:$ADDON_VERSION \ - ./ - if: ${{ github.ref != 'refs/heads/main' }} - - name: Buildx build --push (if main or release) - run: | - DOCKER_CLI_EXPERIMENTAL=enabled sudo docker buildx build \ - --pull \ - --push \ - --platform=$PLATFORM \ - --build-arg TESLAMATE_TAG=$TESLAMATE_TAG \ - --build-arg ARCH=$ARCH \ - --label io.hass.type="addon" \ - --label io.hass.name="$ADDON_NAME" \ - --label io.hass.description="$ADDON_DESCRIPTION" \ - --label io.hass.version="$ADDON_VERSION" \ - --label io.hass.arch="${{ matrix.arch }}" \ - --label io.hass.url="https://github.com/matt-FFFFFF/hassio-addon-repository/blob/main/teslamate/README.md" \ - -t $DOCKER_USERNAME/teslamate-${{ matrix.arch }}:$ADDON_VERSION \ - ./ - if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'release' }} diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..7286959 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,44 @@ +name: Test + +on: + push: + branches: + - main + paths: + - build.yaml + - config.yaml + - build.json + - config.json + - Dockerfile + - rootfs/** + pull_request: + branches: + - main + paths: + - build.yaml + - config.yaml + - build.json + - config.json + - Dockerfile + - rootfs/** + +jobs: + build: + runs-on: ubuntu-latest + name: Build add-on + strategy: + matrix: + arch: ["amd64", "armv7", "aarch64"] + + steps: + - name: Check out repository + uses: actions/checkout@v4.1.4 + + - name: Build add-on + uses: home-assistant/builder@master + with: + args: | + --test \ + --${{ matrix.arch }} \ + --target /data/ \ + --addon diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index 55863e5..0000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "recommendations": [ - "ms-azuretools.vscode-docker", - "github.vscode-pull-request-github" - ] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..84f5d51 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,17 @@ +{ + "json.schemas": [ + { + "fileMatch": [ + "**/build.json" + ], + "url": "https://raw.githubusercontent.com/frenck/action-addon-linter/main/src/build.schema.json" + }, + { + "fileMatch": [ + "**/config.json" + ], + "url": "https://raw.githubusercontent.com/frenck/action-addon-linter/main/src/config.schema.json" + } + ], + "json.schemaDownload.enable": true +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 1cfad2d..40c4f15 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,41 +1,19 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "Start Home Assistant", - "type": "shell", - "command": "/usr/local/bin/start_ha.sh", - "group": { - "kind": "test", - "isDefault": true, - }, - "presentation": { - "reveal": "always", - "panel": "new" - }, - "problemMatcher": [] - },{ - "label": "Cleanup stale Home Assistant environment", - "type": "shell", - "command": "/usr/local/bin/start_ha.sh --cleanup", - "group": "test", - "presentation": { - "reveal": "always", - "panel": "new" - }, - "problemMatcher": [] - },{ - "label": "Run Home Assistant CLI", - "type": "shell", - "command": "docker run --rm -ti -v /etc/machine-id:/etc/machine-id --network=hassio --add-host hassio:172.30.32.2 homeassistant/amd64-hassio-cli:dev", - "group": "test", - "presentation": { - "reveal": "always", - "panel": "new" - }, - "problemMatcher": [] - } - ] -} \ No newline at end of file + "version": "2.0.0", + "tasks": [ + { + "label": "Start Home Assistant", + "type": "shell", + "command": "supervisor_run", + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "dedicated" + }, + "problemMatcher": [] + } + ] +} diff --git a/DOCS.md b/DOCS.md new file mode 100644 index 0000000..70483a3 --- /dev/null +++ b/DOCS.md @@ -0,0 +1,144 @@ +# Home Assistant Add-on: TeslaMate + +A self-hosted data logger for your Tesla ๐Ÿš˜ + +## About + +[TeslaMate][teslamate] is a powerful, self-hosted data logger for your Tesla. + +- Written in **[Elixir][elixir]** +- Data is stored in a **Postgres** database +- Visualization and data analysis with **Grafana** +- Vehicle data is published to a local **MQTT** Broker + +This addon allows you to run [TeslaMate][teslamate] on your Home Assistant server based on the the official TeslaMate [docker image][docker]. + +## Configuration + +The configuration is self-explanatory, but essentially we need details about accessing the PostgreSQL database, Grafana and optionally MQTT. + +### Options + +Remember to restart the add-on when the configuration is changed. + +#### Database Options + +- `database_user`: The username used to connect to your PostgreSQL server. + +- `database_pass`: The password for the user to connect to your PostgreSQL server. + +- `database_port`: The port your PostgreSQL server is listening on. Default: `5432`. + +- `database_host`: The hostname of your PostgreSQL server. Default: `29b65938-postgres` for the [PostgreSQL add-on][postgres]. + +- `database_name`: The name of the PostgreSQL database. Default: `teslamate`. + +- `database_ssl`: Use SSL to connect to the database. + +#### MQTT Options (Optional) + +If you are going to use MQTT, you **must** have a username and password defined for your MQTT user; do not use the HA local login (thanks [quach128](https://github.com/quach128)). + +You must also specify an access control list entry for the teslamate user, for example: + +```text +user teslamate +topic readwrite teslamate/# +``` + +See the [official docs][mosquitto-docs] on how to configure access control with Mosquitto + +- `disable_mqtt`: Disable MQTT? + +- `mqtt_host`: The hostname of your MQTT server. + +- `mqtt_user`: The username used to connect to your MQTT server. + +- `mqtt_pass`: The password for the user to connect to your PostgreSQL server. + +- `mqtt_tls`: Use TLS to connect to MQTT? + +- `mqtt_tls_accept_invalid_certs`: MQTT TLS Accepts invalid certificates + +- `mqtt_namespace`: MQTT Namespace + +#### Grafana Options + +I recommend you use the existing [Grafana addon][grafana-addon] from the community addons, if you do, please enable the following plugins in your yaml configurations, e.g. + +```yaml +plugins: + - natel-discrete-panel + - natel-plotly-panel + - pr0ps-trackmap-panel + - grafana-piechart-panel +custom_plugins: + - name: panodata-map-panel + url: https://github.com/panodata/panodata-map-panel/releases/download/0.16.0/panodata-map-panel-0.16.0.zip + unsigned: true +custom_plugins: [] +env_vars: + - name: GF_SECURITY_ADMIN_USER + value: + - name: GF_SECURITY_ADMIN_PASSWORD + value: +ssl: true # optional if you are using TLS +certfile: fullchain.pem # optional if you are using TLS +keyfile: privkey.pem # optional if you are using TLS +``` + +_Note_ that the security admin password and usernames can only be set on the first start of the Grafana addon, so if you already have it configured you'll need to use the same details or remove the add-on and re-add it. + +- `grafana_import_dashboards`: (Optional, but recommended) Automatically import the grafana dashboards on startup? + +- `grafana_folder_name`: Folder within Grafana to store all the dashboards. Default: `TeslaMate`. + +- `grafana_host`: The hostname of your Grafana server. Default: `a0d7b954-grafana`. + +- `grafana_port`: The port your Grafana server is listening on. Default: `3000`. + +- `grafana_user`: The username used to connect to your Grafana server. + +- `grafana_pass`: The password for the user to connect to your Grafana server. + +- `timezone`: Timezone to use for Granafa dashboards. + +Once you have Grafana up and running, you'll need to configure a data source to read data from the PostgreSQL database: + +![Grafana Postgres data source][grafana-datasource] + +#### Other Options + +- `default_geofence`: (Optional) The default geofence to send via `GEOFENCE` if the car is not in a geofence. + +- `encryption_key`: (Optional) A random string used as encrypt and protect the Tesla API keys. This will be auto-generated on first run if not set. + +- `import_dir`: (Optional) The path to the directory where TeslaMate should look for the TeslaMate export CSV file. Default: `/share/teslamate`. + +## Data Import from TeslaFi + +It is now possible to import CSV data from TeslaFi, refer to the [official docs][teslafi-import]. + +Follow this process: + +1. Copy the CSV data to the `/share/teslamate` folder on your Home Assistant instance. + You can do this using the [Samba][samba-addon] or [SSH][ssh-addon] addons. + +2. Make sure the `import_path` configuration setting is set to `/share/teslamate`. + +3. Restart the TeslaMate addon and navigate to the web UI, you should be presented with the import screen. + +4. Import the data + +5. Once imported sucessfully, delete the CSV files to avoid the import screen being presented. + +[docker]: https://hub.docker.com/r/teslamate/teslamate +[elixir]: https://elixir-lang.org/ +[grafana-addon]: https://github.com/hassio-addons/addon-grafana +[grafana-datasource]: https://raw.githubusercontent.com/lildude/hassio-addon-teslamate/main/media/grafana-postgres.png +[mosquitto-docs]: https://github.com/home-assistant/addons/blob/master/mosquitto/DOCS.md +[postgres]: https://github.com/matt-FFFFFF/hassio-addon-postgres +[samba-addon]: https://github.com/home-assistant/addons/blob/master/samba/DOCS.md +[ssh-addon]: https://github.com/home-assistant/addons/blob/master/ssh/DOCS.md +[teslafi-import]: https://docs.teslamate.org/docs/import/teslafi +[teslamate]: https://github.com/teslamate-org/teslamate/ diff --git a/Dockerfile b/Dockerfile index c103067..4ba9417 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,25 +1,23 @@ -ARG TESLAMATE_TAG - -FROM teslamate/grafana:${TESLAMATE_TAG} as grafana +FROM teslamate/grafana:1.28.5 as grafana #--- -FROM teslamate/teslamate:${TESLAMATE_TAG} +FROM teslamate/teslamate:1.28.5 -ARG ARCH -ARG BASHIO_VERSION=0.11.0 -ARG S6_OVERLAY_VERSION=2.1.0.2 +ARG BUILD_ARCH +ARG BASHIO_VERSION=0.16.2 +ARG S6_OVERLAY_VERSION=3.1.6.2 ENV \ DEBIAN_FRONTEND="noninteractive" \ LANG="C.UTF-8" \ S6_BEHAVIOUR_IF_STAGE2_FAILS=2 \ - S6_CMD_WAIT_FOR_SERVICES=1 + S6_CMD_WAIT_FOR_SERVICES=1 \ + S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \ + S6_SERVICES_GRACETIME=0 USER root -# Commands taken from HA Ubuntu base Dockerfile but switched to wget as curl didn't work using buildx -# https://github.com/home-assistant/docker-base/blob/master/ubuntu/amd64/Dockerfile RUN \ set -x \ && apt-get update && apt-get install -y --no-install-recommends \ @@ -29,20 +27,21 @@ RUN \ curl \ jq \ nginx \ + postgresql-client \ tzdata \ - wget \ + xz-utils \ && rm -rf /var/lib/apt/lists/* \ - \ - && wget https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-${ARCH}.tar.gz \ - && tar zxvf s6-overlay-${ARCH}.tar.gz -C / \ - && rm -f s6-overlay-${ARCH}.tar.gz \ + && S6_ARCH="${BUILD_ARCH}" \ + && if [ "${BUILD_ARCH}" = "amd64" ]; then S6_ARCH="x86_64"; \ + elif [ "${BUILD_ARCH}" = "armv7" ]; then S6_ARCH="arm"; fi \ + && curl -Ls "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz" | tar xpJ -C / \ + && curl -Ls "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-${S6_ARCH}.tar.xz" | tar xpJ -C / \ + && curl -Ls "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-symlinks-noarch.tar.xz" | tar Jxp -C / \ + && curl -Ls "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-symlinks-arch.tar.xz" | tar Jxp -C / \ && mkdir -p /etc/fix-attrs.d \ && mkdir -p /etc/services.d \ - \ && mkdir -p /tmp/bashio \ - && wget https://github.com/hassio-addons/bashio/archive/v${BASHIO_VERSION}.tar.gz \ - && tar xvzf v${BASHIO_VERSION}.tar.gz --strip 1 -C /tmp/bashio \ - && rm -f v${BASHIO_VERSION}.tar.gz \ + && curl -Ls "https://github.com/hassio-addons/bashio/archive/v${BASHIO_VERSION}.tar.gz" | tar xz --strip 1 -C /tmp/bashio \ && mv /tmp/bashio/lib /usr/lib/bashio \ && ln -s /usr/lib/bashio/bashio /usr/bin/bashio \ && rm -rf /tmp/bashio @@ -62,4 +61,10 @@ COPY --from=grafana --chown=root /dashboards /dashboards COPY --from=grafana --chown=root /dashboards_internal /dashboards # S6-Overlay -ENTRYPOINT ["/init"] \ No newline at end of file +ENTRYPOINT ["/init"] + +LABEL \ + org.opencontainers.image.title="Home Assistant Add-on: TeslaMate" \ + org.opencontainers.image.description="A self-hosted data logger for your Tesla." \ + org.opencontainers.image.source="https://github.com/lildude/ha-addon-ghostfolio/" \ + org.opencontainers.image.licenses="MIT" \ No newline at end of file diff --git a/LICENSE b/LICENSE index c10b264..d465789 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 Matt White +Copyright (c) 2024 Colin Seymour Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index d0b65a9..76c1f6c 100644 --- a/README.md +++ b/README.md @@ -1,136 +1,60 @@ -# TeslaMate Addon for Home Assistant +# Home Assistant Add-on: TeslaMate -๐Ÿ”” Note this project is looking for a new maintainer: https://github.com/matt-FFFFFF/hassio-addon-teslamate/issues/124 +A self-hosted data logger for your Tesla ๐Ÿš˜ -This addon builds on the excellent work of [Adrian Kumpf](https://github.com/adriankumpf/teslamate). See his repo for information regarding the TeslaMate application. +## About -This addon is part of [my Home Assistant addon repo](https://github.com/matt-FFFFFF/hassio-addon-repository) - see link for instructions on how to add to Home Assistant. +[TeslaMate][teslamate] is a powerful, self-hosted data logger for your Tesla. -## Installation - -1. Add [my repository](https://github.com/matt-FFFFFF/hassio-addon-repository) to Home Assistant. See [installing third party addons](https://www.home-assistant.io/hassio/installing_third_party_addons/) from the Home Assistant documentation. -2. Add the `TeslaMate` and the `PostgreSQL` addons from my repo and the `Grafana` addon from the community repo. -3. Before starting Postgres, [configure](https://github.com/matt-FFFFFF/hassio-addon-postgres/blob/main/README.md) the addon by setting the DB name, username and password. Now you can start it up. - -### Tesla API Token Encryption Key - -To ensure that the Tesla API tokens are stored securely, an encryption key must be provided via the ENCRYPTION_KEY environment variable. -This is set in the addon configuration, using the `encryption_key` configuration item. - -**A default has been provided but it is highly recommended to change this!** - -### DB Connection - -If using the Postgres addon from my addon repo, the database host is `29b65938-postgres`. -Below is a snippit from the TeslaMate addon configuration, just replace the DB name, username and password on the `Configuration` tab of the addon before starting it and you will be good to go. - -```yaml -database_user: username -database_pass: password -database_name: databasename -database_host: 29b65938-postgres -database_ssl: false -database_port: 5432 -``` - -### MQTT Configuration - -You **must** have a username and password defined for your MQTT user, do not use the HA local login (thanks [quach128](https://github.com/quach128)). Below is a sample configuration using the Mosquitto MQTT addon available in the Home Assistant core addon repo: - -```yaml -disable_mqtt: false -mqtt_host: core-mosquitto -mqtt_user: mymqttuser -mqtt_pass: mymqtttpass -mqtt_tls: false -mqtt_tls_accept_invalid_certs: true -``` - -#### Mosquitto access control list - -You must specify an access control list entry for the teslamate user, for example: - -```text -user teslamate -topic readwrite teslamate/# -``` - -See the [official docs](https://github.com/home-assistant/addons/blob/master/mosquitto/DOCS.md) on how to configure access control with Mosquitto +- Written in **[Elixir][elixir]** +- Data is stored in a **Postgres** database +- Visualization and data analysis with **Grafana** +- Vehicle data is published to a local **MQTT** Broker -### Grafana Configuration +This addon allows you to run [TeslaMate][teslamate] on your Home Assistant server based on the the official TeslaMate [docker image][docker]. -I recommend you use the existing Grafana addon from the community addons, if you do, please enable the following plugins in your yaml configurations, e.g. +[![Sponsor me to maintain this addon][sponsor-badge]](https://github.com/sponsors/lildude) -```yaml -plugins: - - natel-discrete-panel - - natel-plotly-panel - - pr0ps-trackmap-panel - - grafana-piechart-panel -custom_plugins: - - name: panodata-map-panel - url: https://github.com/panodata/panodata-map-panel/releases/download/0.16.0/panodata-map-panel-0.16.0.zip - unsigned: true -custom_plugins: [] -env_vars: - - name: GF_SECURITY_ADMIN_USER - value: - - name: GF_SECURITY_ADMIN_PASSWORD - value: -ssl: true # optional if you are using TLS -certfile: fullchain.pem # optional if you are using TLS -keyfile: privkey.pem # optional if you are using TLS -``` +![TeslaMate Version][teslamate-version] +![Ingress][ingres-badge] +![Supported Architectures][archs] -> Note that the security admin password and usernames can only be set on the first start of the Grafana addon, so if you already have it configured you'll need to remove it and re-add it. +## Requirements -#### Data Source +TeslaMate needs a PostgreSQL database. +All development and testing has been done using [PostgreSQL add-on][postgres] for convenience but you're welcome to use your own. -Configure a PostgreSQL data source as follows: +For convenience, my [add-ons repository][addons-repo] includes configuration that points to the [PostgreSQL add-on][postgres] so you can install everything from one repo. -![Grafana Postgres data source](https://raw.githubusercontent.com/matt-FFFFFF/hassio-addon-teslamate/main/media/grafana-postgres.png) +To get the full experience, it is recommended that you also install the community [Grafana add-on][grafana-addon] and [MQTT integration][mqtt]. -#### Automatically Uploading Grafana Dashboards - -Without this step you won't be able to use the TeslaMate dashboards, so this is recommended. - -Configure the `Grafana` addon and set the admin username and password - we will need this to upload the dashboards: - -> Important! These environment variables are only parsed on the initial set up of Grafana. -> If you already have the addon configured you'll need to remove it and re-add, setting this configuration for the initial start-up. - -```yaml -env_vars: - - name: GF_SECURITY_ADMIN_USER - value: admin - - name: GF_SECURITY_ADMIN_PASSWORD - value: mysecretpassword -``` - -Now configure the `Teslamate` addon: - -```yaml -grafana_import_dashboards: true -grafana_folder_name: TeslaMate -grafana_host: a0d7b954-grafana # this is correct if you use the community addon -grafana_port: 3000 # this is correct if you use the community addon -grafana_user: admin -grafana_pass: mysecretpassword -``` - -## Data Import from TeslaFi - -It is now possible to import CSV data from TeslaFi, refer to the [official docs](https://docs.teslamate.org/docs/import/teslafi). - -Follow this process: - -1. Copy the CSV data to the `/share/teslamate` folder on your Home Assistant instance. -You can do this using the [Samba](https://github.com/home-assistant/addons/blob/master/samba/DOCS.md) or [SSH](https://github.com/home-assistant/addons/blob/master/ssh/DOCS.md) addons. - -2. Make sure the `import_path` configuration setting is set to `/share/teslamate`. - -3. Restart the TeslaMate addon and navigate to the web UI, you should be presented with the import screen. - -4. Import the data +## Installation -5. Once imported sucessfully, delete the CSV files to avoid the import screen being presented. +1. Add my [add-ons repository][addons-repo] to Home Assistant or click the button below to open my add-on repository on your Home Assistant instance. + + [![Open add-on repo on your Home Assistant instance][repo-btn]][addon] + +1. Install this add-on. +1. Install the PostgreSQL add-on and configure and start it, if you wish to use this add-on. The database name isn't important here as the TeslaMate addon will create the database you name in the settings if it doesn't exist. +1. Configure Grafana as detailed in this addon's documentation. +1. Enter your PostgreSQL configuration information. +1. Enter your Grafana configuration information. +1. Enter your MQTT configuration information. +1. Click the `Save` button to store your configuration. +1. Start the add-on. +1. Check the logs of the add-on to see if everything went well. +1. Click the `OPEN WEB UI` button to open TeslaMate. + +[addon]: https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Flildude%2Fha-addons +[addons-repo]: https://github.com/lildude/ha-addons +[archs]: https://img.shields.io/badge/dynamic/json?color=green&label=Arch&query=%24.arch&url=https%3A%2F%2Fraw.githubusercontent.com%2Flildude%2Fha-addon-teslamate%2Fmain%2Fconfig.json +[docker]: https://hub.docker.com/r/teslamate/teslamate +[elixir]: https://elixir-lang.org/ +[grafana-addon]: https://github.com/hassio-addons/addon-grafana +[ingres-badge]: https://img.shields.io/badge/dynamic/json?label=Ingress&query=%24.ingress&url=https%3A%2F%2Fraw.githubusercontent.com%2Flildude%2Fha-addon-teslamate%2Fmain%2Fconfig.json +[mqtt]: https://www.home-assistant.io/integrations/mqtt +[postgres]: https://github.com/matt-FFFFFF/hassio-addon-postgres +[repo-btn]: https://my.home-assistant.io/badges/supervisor_add_addon_repository.svg +[sponsor-badge]: https://img.shields.io/badge/Sponsor_Me-%E2%9D%A4-ec6cb9?logo=GitHub +[teslamate-version]: https://img.shields.io/badge/dynamic/json?label=TeslaMate%20Version&url=https%3A%2F%2Fraw.githubusercontent.com%2Flildude%2Fha-addon-teslamate%2Fmain%2Fbuild.json&query=%24.args.teslamate_version +[teslamate]: https://github.com/teslamate-org/teslamate/ diff --git a/build.json b/build.json index 137b75a..ae1f9fd 100644 --- a/build.json +++ b/build.json @@ -1,5 +1,13 @@ { - "args": { - "TESLAMATE_TAG": "1.28.5" - } -} + "build_from": { + "aarch64": "teslamate/teslamate:not-used", + "amd64": "teslamate/teslamate:not-used", + "armv7": "teslamate/teslamate:not-used" + }, + "args": { + "teslamate_version": "1.28.5" + }, + "codenotary": { + "signer": "colin@symr.io" + } +} \ No newline at end of file diff --git a/config.json b/config.json index 2f29a9a..782ecd6 100644 --- a/config.json +++ b/config.json @@ -3,41 +3,40 @@ "version": "dev", "slug": "teslamate", "description": "A self-hosted data logger for your Tesla.", + "url": "https://github.com/lildude/ha-addon-teslamate", "arch": [ - "armhf", "armv7", "aarch64", "amd64" ], - "startup": "application", - "boot": "auto", "ingress": true, + "init": false, "panel_icon": "mdi:car-connected", "panel_title": "TeslaMate", "options": { - "database_user": "username", - "database_pass": "password", - "database_name": "databasename", + "database_user": null, + "database_pass": null, + "database_name": "teslamate", "database_host": "29b65938-postgres", - "database_ssl": false, "database_port": 5432, - "default_geofence": "", - "disable_mqtt": false, - "encryption_key": "myencryptionkey", - "grafana_import_dashboards": false, + "database_ssl": false, + "grafana_import_dashboards": true, "grafana_folder_name": "TeslaMate", "grafana_host": "a0d7b954-grafana", "grafana_port": 3000, - "grafana_user": "admin", - "grafana_pass": "pass", - "import_dir": "/share/teslamate", + "grafana_user": "", + "grafana_pass": "", + "disable_mqtt": false, "mqtt_host": "core-mosquitto", - "mqtt_user": "user", - "mqtt_pass": "pass", - "mqtt_tls": true, + "mqtt_user": "", + "mqtt_pass": "", + "mqtt_tls": false, "mqtt_tls_accept_invalid_certs": false, "mqtt_namespace": "", - "timezone": "Europe/London" + "timezone": "Europe/London", + "import_dir": "/share/teslamate", + "default_geofence": "", + "encryption_key": "" }, "schema": { "database_user": "str", @@ -46,27 +45,27 @@ "database_host": "str", "database_ssl": "bool", "database_port": "int", - "default_geofence": "str", - "disable_mqtt": "bool", - "encryption_key": "password", "grafana_import_dashboards": "bool", "grafana_folder_name": "str", "grafana_host": "str", "grafana_port": "int", - "grafana_user": "str", - "grafana_pass": "password", - "import_dir": "str", - "mqtt_host": "str", - "mqtt_user": "str", - "mqtt_pass": "password", + "grafana_user": "str?", + "grafana_pass": "password?", + "disable_mqtt": "bool", + "mqtt_host": "str?", + "mqtt_user": "str?", + "mqtt_pass": "password?", "mqtt_tls": "bool", "mqtt_tls_accept_invalid_certs": "bool", - "mqtt_namespace": "str", - "timezone": "str" + "mqtt_namespace": "str?", + "timezone": "str", + "import_dir": "str", + "default_geofence": "str?", + "encryption_key": "password?" }, "map": [ "share:rw" ], - "url": "https://github.com/matt-FFFFFF/hassio-addon-repository/blob/master/teslamate/README.md", - "image": "mattffffff/teslamate-{arch}" + "codenotary": "colin@symr.io", + "image": "ghcr.io/lildude/ha-addon-teslamate-{arch}" } diff --git a/scripts/ha-bootstrap.sh b/scripts/ha-bootstrap.sh deleted file mode 100755 index 7f89c5b..0000000 --- a/scripts/ha-bootstrap.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bashio - -# Database things -export DATABASE_HOST=$(bashio::config 'database_host') -export DATABASE_NAME=$(bashio::config 'database_name') -export DATABASE_PASS=$(bashio::config 'database_pass') -export DATABASE_PORT=$(bashio::config 'database_port') -export DATABASE_USER=$(bashio::config 'database_user') - -# MQTT things -export DISABLE_MQTT=$(bashio::config 'disable_mqtt') -export MQTT_HOST=$(bashio::config 'mqtt_host') -export MQTT_NAMESPACE=$(bashio::config 'mqtt_namespace') -export MQTT_PASSWORD=$(bashio::config 'mqtt_pass') -export MQTT_TLS_ACCEPT_INVALID_CERTS=$(bashio::config 'mqtt_tls_accept_invalid_certs') -export MQTT_TLS=$(bashio::config 'mqtt_tls') -export MQTT_USERNAME=$(bashio::config 'mqtt_user') - - -# Other things -export IMPORT_DIR=$(bashio::config 'import_dir') -export PORT=4000 -export TZ=$(bashio::config 'timezone') -export ENCRYPTION_KEY=$(bashio::config 'encryption_key') -export DEFAULT_GEOFENCE=$(bashio::config 'default_geofence') - -# Import dashboards -if [ $(bashio::config 'grafana_import_dashboards') == 'true' ]; then - /dashboards.sh restore -fi - -# https://developers.home-assistant.io/blog/2023/04/13/new_limits_for_add_ons/ -ulimit -n 1048576 - -exec $(/usr/bin/env sh) /entrypoint.sh "$@" diff --git a/services/nginx/finish b/services/nginx/finish index cb029b9..546dcbb 100644 --- a/services/nginx/finish +++ b/services/nginx/finish @@ -1,2 +1,9 @@ -#!/bin/sh -s6-svscanctl -t /var/run/s6/services \ No newline at end of file +#!/command/with-contenv bashio +# -*- bash -*- +# shellcheck shell=bash +if [[ "${1}" -ne 0 ]] && [[ "${1}" -ne 256 ]]; then + bashio::log.warning "Nginx crashed, halting add-on" + /run/s6/basedir/bin/halt +fi + +bashio::log.info "Nginx stopped, restarting..." \ No newline at end of file diff --git a/services/nginx/run b/services/nginx/run index d468e7f..394e955 100644 --- a/services/nginx/run +++ b/services/nginx/run @@ -1,3 +1,5 @@ -#!/usr/bin/with-contenv sh +#!/command/with-contenv bashio +# -*- bash -*- +# shellcheck shell=bash mkdir /run/nginx -exec nginx -g 'daemon off;' \ No newline at end of file +exec nginx -g 'daemon off;error_log /proc/1/fd/1 error;' \ No newline at end of file diff --git a/services/teslamate/finish b/services/teslamate/finish index cb029b9..b62c3fc 100644 --- a/services/teslamate/finish +++ b/services/teslamate/finish @@ -1,2 +1,9 @@ -#!/bin/sh -s6-svscanctl -t /var/run/s6/services \ No newline at end of file +#!/command/with-contenv bashio +# -*- bash -*- +# shellcheck shell=bash +if [[ "${1}" -ne 0 ]] && [[ "${1}" -ne 256 ]]; then + bashio::log.warning "TeslaMate crashed, halting add-on" + /run/s6/basedir/bin/halt +fi + +bashio::log.info "TeslaMate stopped, restarting..." \ No newline at end of file diff --git a/services/teslamate/run b/services/teslamate/run index 7145b54..6df47ed 100644 --- a/services/teslamate/run +++ b/services/teslamate/run @@ -1,4 +1,36 @@ -#!/usr/bin/with-contenv sh +#!/usr/bin/with-contenv bashio +# -*- bash -*- +# shellcheck shell=bash +set -e + +# Database things +DATABASE_HOST=$(bashio::config 'database_host') +DATABASE_NAME=$(bashio::config 'database_name') +DATABASE_PASS=$(bashio::config 'database_pass') +DATABASE_PORT=$(bashio::config 'database_port') +DATABASE_USER=$(bashio::config 'database_user') + +# MQTT things +DISABLE_MQTT=$(bashio::config 'disable_mqtt') +MQTT_HOST=$(bashio::config 'mqtt_host') +MQTT_NAMESPACE=$(bashio::config 'mqtt_namespace') +MQTT_PASSWORD=$(bashio::config 'mqtt_pass') +MQTT_TLS_ACCEPT_INVALID_CERTS=$(bashio::config 'mqtt_tls_accept_invalid_certs') +MQTT_TLS=$(bashio::config 'mqtt_tls') +MQTT_USERNAME=$(bashio::config 'mqtt_user') + +# Other things +IMPORT_DIR=$(bashio::config 'import_dir') +PORT=4000 +TZ=$(bashio::config 'timezone') +DEFAULT_GEOFENCE=$(bashio::config 'default_geofence') + +encryption_key=$(bashio::config 'encryption_key') +if bashio::config.is_empty 'encryption_key'; then + encryption_key=$(openssl rand -hex 32) + bashio::addon.option 'encryption_key' "$encryption_key" +fi +ENCRYPTION_KEY=$(bashio::config 'encryption_key') ingress_entry=$(curl -X GET \ -H "Authorization: Bearer ${SUPERVISOR_TOKEN}" \ @@ -6,7 +38,42 @@ ingress_entry=$(curl -X GET \ -s http://supervisor/addons/self/info | \ jq -r '.data.ingress_entry') -sed -i "s^url: \[^url: \[path: \"${ingress_entry}\", ^" /opt/app/releases/*/runtime.exs +export URL_PATH=$ingress_entry + +export DATABASE_HOST DATABASE_NAME DATABASE_PASS DATABASE_PORT DATABASE_USER \ + DISABLE_MQTT MQTT_HOST MQTT_NAMESPACE MQTT_PASSWORD MQTT_TLS_ACCEPT_INVALID_CERTS \ + MQTT_TLS MQTT_USERNAME IMPORT_DIR PORT TZ DEFAULT_GEOFENCE ENCRYPTION_KEY URL_PATH + +# Import dashboards +if bashio::config.true 'grafana_import_dashboards'; then + /dashboards.sh restore +fi + +# Create the PostgreSQL database if it doesn't exist +if pg_isready -h "$DATABASE_HOST" -p "$DATABASE_PORT" > /dev/null 2>&1; then + bashio::log.info "Creating database $DATABASE_NAME on $DATABASE_HOST" + + res=$(PGPASSWORD="$DATABASE_PASS" psql -h "$DATABASE_HOST" -p "$DATABASE_PORT" -U "$DATABASE_USER" postgres -c "CREATE DATABASE $DATABASE_NAME" 2>&1) || true + case "$res" in + "CREATE DATABASE") + bashio::log.info "Database $DATABASE_NAME created" + ;; + *"already exists"*) + bashio::log.info "Database $DATABASE_NAME already exists" + ;; + *) + bashio::log.error "Failed to create database $DATABASE_NAME: $res" + exit 1 + ;; + esac +else + bashio::log.error "PostgreSQL is not ready" + exit 1 +fi + +ulimit -n 1048576 + +bashio::log.info "Starting TeslaMate" cd /opt/app -exec /ha-bootstrap.sh bin/teslamate start +exec $(/usr/bin/env sh) /entrypoint.sh bin/teslamate start diff --git a/translations/en.yaml b/translations/en.yaml new file mode 100644 index 0000000..6e3d989 --- /dev/null +++ b/translations/en.yaml @@ -0,0 +1,69 @@ +configuration: + database_user: + name: Database Username + description: The username used to connect to your PostgreSQL server. + database_pass: + name: Database Password + description: The password for the user to connect to your PostgreSQL server. + database_port: + name: Database Port + description: The port your PostgreSQL server is listening on. + database_host: + name: Database Hostname + description: The hostname of your PostgreSQL server. + database_name: + name: Database Name + description: The name of the PostgreSQL database. + database_ssl: + name: Database SSL + description: Use SSL to connect to the database. + disable_mqtt: + name: Disable MQTT? + mqtt_host: + name: MQTT Hostname + description: The hostname of your MQTT server. + mqtt_user: + name: MQTT Username + description: The username used to connect to your MQTT server. + mqtt_pass: + name: MQTT Password + description: The password for the user to connect to your PostgreSQL server. + mqtt_tls: + name: MQTT TLS? + description: Use TLS to connect to MQTT? + mqtt_tls_accept_invalid_certs: + name: MQTT TLS Accept invalid certificates + description: MQTT accepts invalid certificates. + mqtt_namespace: + name: MQTT Namespace + description: MQTT namespace. + grafana_import_dashboards: + name: Import Grafana Dashboards? + description: Automatically import the grafana dashboards on startup? + grafana_folder_name: + name: Grafana Folder Name + description: Folder within Grafana to store all the dashboards. + grafana_host: + name: Grafana Hostname + description: The hostname of your Grafana server. + grafana_port: + name: Grafana Port + description: The port your Grafana server is listening on. + grafana_user: + name: Grafana Username + description: The username used to connect to your Grafana server. + grafana_pass: + name: Grafana Password + description: The password for the user to connect to your Grafana server. + timezone: + name: Timezone + description: Timezone to use for Granafa dashboards. + encryption_key: + name: Encryption Key + description: A random string used as encrypt and protect the Tesla API keys. This will be auto-generated on first run if not set. + default_geofence: + name: Default Geofence + description: The default geofence to send via GEOFENCE if the car is not in a geofence. + import_dir: + name: TeslaFi Import Directory + description: The directory which holds the TeslaFi export you would like to import into TeslaMate.