From cec1e4fd076baf9f88efddbe471b6da22f68bec3 Mon Sep 17 00:00:00 2001 From: Georg Ledermann Date: Wed, 31 Jan 2024 13:47:05 +0100 Subject: [PATCH] Add guide for full cloud setup --- README.md | 7 + guide/external-server-cloud/.env | 135 +++++++++++ guide/external-server-cloud/README.md | 215 ++++++++++++++++++ .../external-server-cloud/docker-compose.yml | 209 +++++++++++++++++ guide/raspberry-pi/.env | 25 +- guide/synology/.env | 25 +- 6 files changed, 610 insertions(+), 6 deletions(-) create mode 100644 guide/external-server-cloud/.env create mode 100644 guide/external-server-cloud/README.md create mode 100644 guide/external-server-cloud/docker-compose.yml diff --git a/README.md b/README.md index 5c1f57a..c695c19 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,13 @@ If you have a SENEC.Home battery system, installing is simple. The toolchain is Server costs at Hetzner: €4,51 per month +4. [Remote installation with cloud access to SENEC](/guide/external-server-cloud) + + You need a remote server somewhere on the internet (tested with Hetzner Cloud). No Raspberry or other local hardware required. Data is pulled from SENEC via cloud access by using your credentials from mein-senec.de + **Please note: Cloud access is new and not yet tested by many users.** + + Server costs at Hetzner: €4,51 per month + ## B: You have a PV system, but no SENEC? If you do not have a SENEC battery system, you may still be able to use **SOLECTRUS**. There is a brand new [MQQT-collector](https://github.com/solectrus/mqtt-collector), so SOLECTRUS can be used with any PV device that supports MQTT. Please note that the MQTT-collector is in an experimental stage and I would appreciate your feedback. diff --git a/guide/external-server-cloud/.env b/guide/external-server-cloud/.env new file mode 100644 index 0000000..399cb91 --- /dev/null +++ b/guide/external-server-cloud/.env @@ -0,0 +1,135 @@ +################################################################## +# Dashboard application (the main part) +# +# Domain name or IP address of your host +APP_HOST=my-cloud-server.de +# +# SSL redirect: Use "true" if you want to auto-redirect to https, but ensure that you have a valid SSL certificate +# and a reverse proxy in front of the app! +# In all other cases, the option must be "false"! +FORCE_SSL=false +# +# Secret token to secure cookies, 128 chars long hexadecimal encoded string (don't use this example, make some random changes!) +# Currently there are no cookies in Soletrus, but this may change in the future +SECRET_KEY_BASE=f60debe97dcb73280a2cc83668fd60e8d0e8e48269036a7bce980ee53cfb312e377989a750b8c945a5f69b041289ecb4e2d9e40641b81257c65ac2d43e3c837f +# +# Date of commissioning of your photovoltaic system +INSTALLATION_DATE=2022-01-27 +# +# Password for the PostgreSQL database, used by the app to comunicate internally with the database +# Caution: Do not change this after the first run, otherwise the app will no longer be able to connect to the database! +POSTGRES_PASSWORD=my-secret-db-password +# +# Password to login as administrator, required to manage settings like historical prices +ADMIN_PASSWORD=my-secret-login-password +# +# Optional: Allow iframe embedding +# FRAME_ANCESTORS=https://my-other-home-automation-software.com +# +# Start web server Puma in single mode (recommended to reduce memory usage) +WEB_CONCURRENCY=0 +# + +################################################################## +# SENEC adapter settings +SENEC_ADAPTER=cloud + +# Credentials for mein-senec.de +SENEC_USERNAME=me@example.com +SENEC_PASSWORD=my-secret-password + +# System ID of your SENEC system, not reqired if you have just one system +# SENEC_SYSTEM_ID=123456 + +# Interval in seconds for polling the SENEC cloud, minimum 30 seconds +SENEC_INTERVAL=60 + +################################################################## +# Influx database settings +# +# Influx host (to access from SOLECTRUS dashboard and collectors) +INFLUX_HOST=influxdb +INFLUX_SCHEMA=http +INFLUX_PORT=8086 +# +# Credentials for the Influx database, don't change after the first run! +INFLUX_ORG=solectrus +INFLUX_USERNAME=admin +INFLUX_PASSWORD=ExAmPl3PA55W0rD +INFLUX_ADMIN_TOKEN=my-super-secret-admin-token +# +# Set these names before first run, they can't be changed later! +INFLUX_BUCKET=solectrus +INFLUX_MEASUREMENT_PV=SENEC +INFLUX_MEASUREMENT_FORECAST=Forecast +# +# To keep things simple, we use ONE token (INFLUX_ADMIN_TOKEN) for both writing and reading. +# For better security, you can use two separate tokens, created via the InfluxDB frontend. +INFLUX_TOKEN_WRITE=my-super-secret-admin-token +INFLUX_TOKEN_READ=my-super-secret-admin-token +# +# Volume path for storing the Influx data +INFLUX_VOLUME_PATH=./influxdb +# +# Interval in seconds for polling the InfluxDB +INFLUX_POLL_INTERVAL=300 + +################################################################## +# REDIS settings +# +REDIS_VOLUME_PATH=./redis + +################################################################## +# PostgreSQL database settings +# +DB_VOLUME_PATH=./postgresql + +################################################################## +# Solar forecasting with https://forecast.solar +# API docs: https://doc.forecast.solar/doku.php?id=api:estimate +# +# Latitude of the plant location +FORECAST_LATITUDE=50.92149 +# +# Longitude of the plant location +FORECAST_LONGITUDE=6.36267 +# +# Plane declination: 0 (horizontal) - 90 (vertical) +FORECAST_DECLINATION=30 +# +# Plane azimuth: -180 ... 180 (-180 = north, -90 = east, 0 = south, 90 = west, 180 = north) +FORECAST_AZIMUTH=20 +# +# Installed modules power in kilowatt peak (kWp) +FORECAST_KWP=8.4 +# +# Optional damping factors (http://doc.forecast.solar/damping) +# FORECAST_DAMPING_MORNING=0.5 +# FORECAST_DAMPING_EVENING=0 +# +# Optional configuration for multiple planes +# +# Number of planes +# FORECAST_CONFIGURATIONS=2 +# +# Starting from 0, add params different from the values defined above +# FORECAST_0_AZIMUTH=90 +# FORECAST_0_KWP=5.32 +# FORECAST_1_AZIMUTH=-90 +# FORECAST_1_KWP=7.84 +# +# Available params are: +# - FORECAST_x_LATITUDE +# - FORECAST_x_LONGITUDE +# - FORECAST_x_DECLINATION +# - FORECAST_x_AZIMUTH +# - FORECAST_x_KWP +# - FORECAST_x_DAMPING_MORNING +# - FORECAST_x_DAMPING_EVENING +# +# Update interval in seconds, 900s = 15 minutes, the public (and free) API allows a minimum of 900 seconds +# BEWARE: Each plane counts as one request, so if you have multiple planes, you need to multiply the interval! +FORECAST_INTERVAL=900 +# +# Optional API key for registered users of forecast.solar (https://doc.forecast.solar/account_models) +# FORECAST_SOLAR_APIKEY=abc123 diff --git a/guide/external-server-cloud/README.md b/guide/external-server-cloud/README.md new file mode 100644 index 0000000..42bdd3a --- /dev/null +++ b/guide/external-server-cloud/README.md @@ -0,0 +1,215 @@ +# Remote installation with cloud access to SENEC + +This guides demonstrates how to set up a SOLECTRUS instance on a remote server at Hetzner with cloud access to SENEC. +**Please note: Cloud access is new and not yet tested by many users.** + +### a) Order your server at Hetzner + +Sign up on Hetzner: +https://hetzner.cloud/?ref=NggV8HU9FqCz +(referral link, will give you a discount of €20 - and me too) + +Order your server: + +- Go to https://console.hetzner.cloud/projects +- Select "New project", name it "SOLECTRUS", open the project +- Select "Add server" +- Location: Select a location near you +- Image: Select "Apps", then "Docker CE" +- Type: The smallest machine is enough, so select "Arm64" architecture and then "CAX11" +- SSH-Key: If you already have an SSH key, you can add it here to avoid struggling with SSH password. Otherwise, leave it blank. +- Order (for €4,51 per month) + +### b) First Login + +After the server has been created, it receives a public IP address. Write it down, it will be referred later [YOUR-SERVER-IP-ADDRESS]. + +Login to your server: + +```console +ssh root@[YOUR-SERVER-IP-ADDRESS] +``` + +If your are not using SSH keys, you are asked to enter your password. Type in our password you get from Hetzner per email. On first login, you are asked to change your password. Choose a strong password. + +Check if `Docker` is installed and running: + +```console +docker --version +Docker version 25.0.1, build 29cf629 + +docker compose version +Docker Compose version v2.24.2 +``` + +Nice, `Docker` is preinstalled. + +### c) Create folders for configuration and Docker volumes: + +```console +mkdir solectrus +cd solectrus +mkdir redis postgresql influxdb +``` + +### d) Create configuration file + +Download the configuration file from the repository; + +```console +curl -L "https://raw.githubusercontent.com/solectrus/hosting/main/guide/external-server-cloud/.env" -o .env +``` + +Edit the downloaded file and change values to your needs. + +```console +pico .env +``` + +IMPORTANT settings, MUST be changed: + +- APP_HOST # Hostname or IP address of your cloud server +- SENEC_USERNAME # Your SENEC username +- SENEC_PASSWORD # Your SENEC password +- SENEC_SYSTEM_ID # Your SENEC system ID (optional, if you have multiple systems) + +Not required, but highly recommended: + +- ADMIN_PASSWORD +- INSTALLATION_DATE +- INFLUX_PASSWORD +- INFLUX_ADMIN_TOKEN +- FORECAST_LATITUDE +- FORECAST_LONGITUDE +- FORECAST_DECLINATION +- FORECAST_AZIMUTH +- FORECAST_KWP + +WARNING: Don't forget to change passwords, because otherwise everyone can access your database! + +Save file and close the editor: Ctrl+S, then Ctrl+X + +### e) Download Docker compose file `./docker-compose.yml` + +```console +curl -L "https://raw.githubusercontent.com/solectrus/hosting/main/guide/external-server/docker-compose.yml" -o docker-compose.yml +``` + +### f) Start Docker containers + +To check if all works fine, we start the containers in the foreground: + +```console +docker compose up +``` + +This could take some minutes for the first run, because some images are download. You see some output like this: + +``` +✔ Network solectrus_default Created +✔ Container solectrus-db-1 Created +✔ Container solectrus-influxdb-1 Created +✔ Container solectrus-redis-1 Created +✔ Container solectrus-app-1 Created +✔ Container solectrus-forecast-collector-1 Created +✔ Container solectrus-senec-collector-1 Created +Attaching to solectrus-app-1, solectrus-db-1, solectrus-forecast-collector-1, solectrus-influxdb-1, solectrus-redis-1 +.... +app-1 | Starting SOLECTRUS... +app-1 | Version: v0.14.2 - 2024-01-07T19:02:01+01:00 - v0.14.2 +app-1 | ---------------- +app-1 | InfluxDB is up and running! +app-1 | influxdb (172.18.0.2:8086) open +app-1 | PostgreSQL is up and running! +app-1 | Preparing database... +app-1 | db (172.18.0.3:5432) open +.... +app-1 | Created database 'solectrus_production' +app-1 | Database is ready! +app-1 | => Booting Puma +app-1 | => Rails 7.1.2 application starting in production +app-1 | => Run `bin/rails server --help` for more startup options +app-1 | Puma starting in single mode... +app-1 | * Puma version: 6.4.1 (ruby 3.2.2-p53) ("The Eagle of Durango") +app-1 | * Min threads: 5 +app-1 | * Max threads: 5 +app-1 | * Environment: production +app-1 | * PID: 1 +app-1 | * Listening on http://0.0.0.0:3000 +app-1 | Use Ctrl-C to stop +``` + +Note: + +- Port `3000` (Dashboard UI) is mapped to 80, so you can access it from your browser without specifying the port + +### g) Open the app in your browser + +Open `http://[YOUR-SERVER-IP-ADDRESS]` in your browser. You should see the dashboard. + +### i) Run services in the background + +Stop services by pressing Ctrl+C. Then start again as daemon: + +```console +docker compose up -d +Starting solectrus_redis_1 ... done +Starting solectrus_db_1 ... done +Starting solectrus_influxdb_1 ... done +Starting solectrus_forecast-collector_1 ... done +Starting solectrus_senec-collector_1 ... done +Starting solectrus_app_1 ... done +``` + +To check if this works, reboot the machine: + +```console +reboot +``` + +Wait a bit, then login again and check if Docker Compose has auto-started the services. + +```console +ssh root@[YOUR-SERVER-IP-ADDRESS] +cd solectrus +docker ps + + +IMAGE STATUS +ghcr.io/solectrus/solectrus:latest Up 31 seconds (healthy) ... +ghcr.io/solectrus/forecast-collector:latest Up 31 seconds ... +ghcr.io/solectrus/senec-collector:latest Up 31 seconds ... +influxdb:2.7-alpine Up 31 seconds (healthy) ... +postgres:16-alpine Up 31 seconds (healthy) ... +redis:7-alpine Up 31 seconds (healthy) ... +``` + +### j) Finish! + +You are done with step 1. SOLECTRUS is now installed on your server and can be accessed from your browser. + +`http://[YOUR-SERVER-IP-ADDRESS]` + +### h) Optional: Import historical data + +On [mein-senec.de](https://mein-senec.de) you find download links for your historical data. Download the CSV files and import them into SOLECTRUS. See [CSV-Importer](https://github.com/solectrus/csv-importer) for more information. + +### i) Staying up to date + +To update your installation to the latest release, run: + +```console +ssh root@[YOUR-SERVER-IP-ADDRESS] +cd solectrus + +docker compose pull +docker compose up -d +``` + +To not have to do this manually every time, the `docker-compose.yml` contains [Watchtower](https://containrrr.dev/watchtower/), which is a free tool to automatically update running Docker containers. Once installed, it will check for new Docker images once every day and updates your containers automatically. And of course, Watchtower also runs in a Docker container. + +### c) Finish! + +You are done. You should see the measurements from your SENEC device in your SOLECTRUS instance: + +`http://[YOUR-SERVER-IP-ADDRESS]` diff --git a/guide/external-server-cloud/docker-compose.yml b/guide/external-server-cloud/docker-compose.yml new file mode 100644 index 0000000..c896a7b --- /dev/null +++ b/guide/external-server-cloud/docker-compose.yml @@ -0,0 +1,209 @@ +version: '3.7' + +services: + app: + image: ghcr.io/solectrus/solectrus:latest + labels: + - 'com.centurylinklabs.watchtower.scope=solectrus' + depends_on: + db: + condition: service_healthy + influxdb: + condition: service_healthy + redis: + condition: service_healthy + links: + - db + - influxdb + - redis + ports: + - 80:3000 + environment: + - APP_HOST + - FORCE_SSL + - SECRET_KEY_BASE + - INSTALLATION_DATE + - ADMIN_PASSWORD + - FRAME_ANCESTORS + - DB_HOST=db + - DB_PASSWORD=${POSTGRES_PASSWORD} + - DB_USER=postgres + - REDIS_URL=redis://redis:6379/1 + - INFLUX_HOST + - INFLUX_TOKEN=${INFLUX_TOKEN_READ} + - INFLUX_ORG + - INFLUX_BUCKET + - INFLUX_MEASUREMENT_PV + - INFLUX_MEASUREMENT_FORECAST + - INFLUX_POLL_INTERVAL + - WEB_CONCURRENCY + healthcheck: + test: ['CMD-SHELL', 'nc -z 127.0.0.1 3000 || exit 1'] + restart: always + logging: + options: + max-size: '10m' + max-file: '3' + + influxdb: + image: influxdb:2.7-alpine + labels: + - 'com.centurylinklabs.watchtower.scope=solectrus' + volumes: + - ${INFLUX_VOLUME_PATH}:/var/lib/influxdb2 + environment: + - DOCKER_INFLUXDB_INIT_MODE=setup + - DOCKER_INFLUXDB_INIT_USERNAME=${INFLUX_USERNAME} + - DOCKER_INFLUXDB_INIT_PASSWORD=${INFLUX_PASSWORD} + - DOCKER_INFLUXDB_INIT_ORG=${INFLUX_ORG} + - DOCKER_INFLUXDB_INIT_BUCKET=${INFLUX_BUCKET} + - DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=${INFLUX_ADMIN_TOKEN} + command: influxd run --bolt-path /var/lib/influxdb2/influxd.bolt --engine-path /var/lib/influxdb2/engine --store disk + ports: + - 8086 + restart: always + healthcheck: + test: ['CMD', 'influx', 'ping'] + interval: 30s + timeout: 10s + retries: 5 + start_period: 30s + logging: + options: + max-size: '10m' + max-file: '3' + + db: + image: postgres:16-alpine + labels: + - 'com.centurylinklabs.watchtower.scope=solectrus' + environment: + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + volumes: + - ${DB_VOLUME_PATH}:/var/lib/postgresql/data + restart: always + healthcheck: + test: ['CMD-SHELL', 'pg_isready -U postgres'] + interval: 10s + timeout: 20s + retries: 5 + start_period: 30s + logging: + options: + max-size: '10m' + max-file: '3' + + redis: + image: redis:7-alpine + labels: + - 'com.centurylinklabs.watchtower.scope=solectrus' + volumes: + - ${REDIS_VOLUME_PATH}:/data + restart: always + healthcheck: + test: ['CMD', 'redis-cli', 'ping'] + interval: 10s + timeout: 20s + retries: 5 + start_period: 30s + logging: + options: + max-size: '10m' + max-file: '3' + + senec-collector: + image: ghcr.io/solectrus/senec-collector:latest + restart: always + labels: + - 'com.centurylinklabs.watchtower.scope=solectrus' + depends_on: + influxdb: + condition: service_healthy + links: + - influxdb + environment: + - SENEC_ADAPTER + - SENEC_USERNAME + - SENEC_PASSWORD + - SENEC_SYSTEM_ID + - SENEC_INTERVAL + - INFLUX_HOST + - INFLUX_TOKEN=${INFLUX_TOKEN_WRITE} + - INFLUX_ORG + - INFLUX_BUCKET + - INFLUX_MEASUREMENT=${INFLUX_MEASUREMENT_PV} + - INFLUX_SCHEMA + logging: + options: + max-size: '10m' + max-file: '3' + + forecast-collector: + image: ghcr.io/solectrus/forecast-collector:latest + labels: + - 'com.centurylinklabs.watchtower.scope=solectrus' + depends_on: + influxdb: + condition: service_healthy + links: + - influxdb + environment: + - INFLUX_HOST + - INFLUX_TOKEN=${INFLUX_TOKEN_WRITE} + - INFLUX_ORG + - INFLUX_BUCKET + - INFLUX_MEASUREMENT=${INFLUX_MEASUREMENT_FORECAST} + - FORECAST_LATITUDE + - FORECAST_LONGITUDE + - FORECAST_DECLINATION + - FORECAST_AZIMUTH + - FORECAST_KWP + - FORECAST_CONFIGURATIONS + - FORECAST_0_LATITUDE + - FORECAST_0_LONGITUDE + - FORECAST_0_DECLINATION + - FORECAST_0_AZIMUTH + - FORECAST_0_KWP + - FORECAST_0_DAMPING_MORNING + - FORECAST_0_DAMPING_EVENING + - FORECAST_1_LATITUDE + - FORECAST_1_LONGITUDE + - FORECAST_1_DECLINATION + - FORECAST_1_AZIMUTH + - FORECAST_1_KWP + - FORECAST_1_DAMPING_MORNING + - FORECAST_1_DAMPING_EVENING + - FORECAST_2_LATITUDE + - FORECAST_2_LONGITUDE + - FORECAST_2_DECLINATION + - FORECAST_2_AZIMUTH + - FORECAST_2_KWP + - FORECAST_2_DAMPING_MORNING + - FORECAST_2_DAMPING_EVENING + - FORECAST_3_LATITUDE + - FORECAST_3_LONGITUDE + - FORECAST_3_DECLINATION + - FORECAST_3_AZIMUTH + - FORECAST_3_KWP + - FORECAST_3_DAMPING_MORNING + - FORECAST_3_DAMPING_EVENING + - FORECAST_INTERVAL + - FORECAST_SOLAR_APIKEY + restart: always + logging: + options: + max-size: '10m' + max-file: '3' + + watchtower: + image: containrrr/watchtower + labels: + - 'com.centurylinklabs.watchtower.scope=solectrus' + volumes: + - /var/run/docker.sock:/var/run/docker.sock + command: --scope solectrus --cleanup + restart: always + logging: + options: + max-size: '10m' + max-file: '3' diff --git a/guide/raspberry-pi/.env b/guide/raspberry-pi/.env index 3fe3cd2..324a788 100644 --- a/guide/raspberry-pi/.env +++ b/guide/raspberry-pi/.env @@ -72,13 +72,32 @@ DB_VOLUME_PATH=/home/pi/solectrus/postgresql ################################################################## # SENEC Collector -# -# Change this to your own SENEC IP address! -SENEC_HOST=192.168.178.123 + +### When you have a SENEC.Home V2 or V3 + +SENEC_ADAPTER=local + +# Change the SENEC_HOST to the IP address of your SENEC system +SENEC_HOST=192.168.0.0 + SENEC_SCHEMA=https SENEC_INTERVAL=5 SENEC_LANGUAGE=de +### When you have a SENEC.Home 4 + +SENEC_ADAPTER=cloud + +# Credentials for mein-senec.de +SENEC_USERNAME=me@example.com +SENEC_PASSWORD=my-secret-password + +# System ID of your SENEC system, not reqired if you have just one system +# SENEC_SYSTEM_ID=123456 + +# Interval in seconds for polling the SENEC cloud, minimum 30 seconds +SENEC_INTERVAL=60 + ################################################################## # Solar forecasting with https://forecast.solar # API docs: https://doc.forecast.solar/doku.php?id=api:estimate diff --git a/guide/synology/.env b/guide/synology/.env index c3e8265..4636535 100644 --- a/guide/synology/.env +++ b/guide/synology/.env @@ -72,13 +72,32 @@ DB_VOLUME_PATH=/volume1/docker/solectrus/postgresql ################################################################## # SENEC Collector -# -# Change this to your own SENEC IP address! -SENEC_HOST=192.168.178.123 + +### When you have a SENEC.Home V2 or V3 + +SENEC_ADAPTER=local + +# Change the SENEC_HOST to the IP address of your SENEC system +SENEC_HOST=192.168.0.0 + SENEC_SCHEMA=https SENEC_INTERVAL=5 SENEC_LANGUAGE=de +### When you have a SENEC.Home 4 + +SENEC_ADAPTER=cloud + +# Credentials for mein-senec.de +SENEC_USERNAME=me@example.com +SENEC_PASSWORD=my-secret-password + +# System ID of your SENEC system, not reqired if you have just one system +# SENEC_SYSTEM_ID=123456 + +# Interval in seconds for polling the SENEC cloud, minimum 30 seconds +SENEC_INTERVAL=60 + ################################################################## # Solar forecasting with https://forecast.solar # API docs: https://doc.forecast.solar/doku.php?id=api:estimate