Swap to private solarweb access
Deploy Solar Relay / deploy (push) Successful in 56s

This commit is contained in:
franzz committed 2026-11-02 18:06:01 +01:00
1 parent 646ba3be81
commit aae5b73581
14 files changed
+883 -142

No files matched your search

+102 -35
View File
@@ -28,10 +28,10 @@ observations never expire, even if their measurement dates are much older.
```bash
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --only-binary=pyarrow -r requirements.txt
python3 -m pip install --only-binary=pyarrow -r requirements.txt
cp config.example.toml config.toml
python -m solar_relay --config config.toml status
python -m solar_relay --config config.toml run
python3 -m solar_relay --config config.toml status
python3 -m solar_relay --config config.toml run
```
Use `.venv/bin/python` directly if you prefer not to activate the environment.
@@ -96,7 +96,8 @@ uploader, status request or CLI replay from overwriting another operation. HTTP
requests happen outside the archive lock.
The upload request is a JSON object with `schema_version: 1` and a `samples` array,
authenticated with the bearer token named by `upload.token_env`. The website must
authenticated with `upload.token` from private `config.toml`, or the environment
variable named by `upload.token_env` when that setting is empty. The website must
commit its data before responding:
```json
@@ -130,6 +131,11 @@ stop the service and other CLI writers before copying the archive directory as a
## Recovering history after Wi-Fi loss
The default mode always collects live data from the inverter's local Fronius API.
The optional backup (`[history].enabled = true`) fills historical energy gaps from
Solar.web in a separate worker. It does not replace or change live collection;
when there are no eligible gaps, it makes no Solar.web requests.
GEN24 records historical data for transfer to Solar.web after reconnecting. This is
separate from its local Solar API: Fronius explicitly lists archive access for GEN24
as unavailable, and this inverter's `GetArchiveData.cgi` returns 404. Inspecting its
@@ -137,36 +143,88 @@ current web interface also found no energy-history retrieval endpoint. Its SDP s
download is an encrypted `.cry` diagnostic file, not a documented energy-history API.
See the official [Solar API manual, section 5.1.1](https://www.fronius.com/~/downloads/Solar%20Energy/Operating%20Instructions/42%2C0410%2C2012.pdf)
and [Solar.web Query API manual, section 6.5](https://www.fronius.com/~/downloads/Solar%20Energy/User%20Information/SE_UI_API_InterfaceDocumentation_EN.pdf).
for the local API's archive limitations.
Optional recovery reads missing five-minute **measured energy** through the separate,
authenticated Solar.web Query API, after the inverter uploads its backlog. This uses
no public guest page. Obtain Query API access and keys from Fronius; its commercial
terms are separate from normal Solar.web access. No cloud calls occur while disabled.
Optional recovery signs in to Solar.web with a real Fronius account and reads its
private daily charts after the inverter uploads its backlog, using the same login
flow and chart series as the sibling `solar` website. No cloud calls occur while
disabled. A public guest link and Query API subscription/keys are not needed.
Set `[history].enabled = true` and `pv_system_id` in the configuration, and put these
in the service's root-readable `/etc/solar-relay/solar-relay.env`:
Create a dedicated Solar.web / Fronius account and grant it permission to view this
installation's metrics. Keep public sharing disabled. The account can have guest
permissions on the installation, but it signs in privately through the normal account
login; the deactivated public guest interface is never used.
```text
SOLARWEB_ACCESS_KEY_ID=your-access-key-id
SOLARWEB_ACCESS_KEY_VALUE=your-access-key-value
Set the backup account credentials directly in your private `config.toml`:
```toml
[history]
enabled = true
pv_system_id = "your-pv-system-uuid"
username = "your-account-email"
password = "your-account-password"
```
The recovery worker checks hourly, looking back seven days by default and allowing
a two-hour delay for the inverter's hourly uploads. It fetches only UTC days with
missing energy extractions, requests five energy channels, limits each request to
24 hours, and skips intervals already present. Requests use HTTPS, headers for
credentials, timeouts and no redirects. Missing/partial cloud data stays missing and
is tried again later. The configured lookback cannot exceed the retention period.
No extra environment file is needed for this login. Set both `username` and `password`;
an incomplete pair is rejected. Direct credentials take precedence over the environment.
Use TOML literal strings (`'...'`) if a password contains backslashes or double quotes.
Alternatively, leave both credentials empty and set the environment variables named
by `username_env` and `password_env`. For the systemd service, these can go in its
root-readable `/etc/solar-relay/solar-relay.env`:
```text
SOLARWEB_USERNAME=your-account-email
SOLARWEB_PASSWORD=your-account-password
```
While live collection runs, the separate recovery worker checks at startup and hourly
by default. It checks every five-minute energy interval back to
`collector.retention_days` (30 days by default), including entirely empty days and
dates before the first local observation. A two-hour delay allows the inverter to
upload its recent history. Only local dates containing gaps are fetched, and existing
live or recovered energy is preserved. When all eligible intervals are present, no
Solar.web requests are made. Unavailable chart days remain missing for retry and do
not prevent other dates from being recovered. Login and network failures stop that
attempt and retry on the next scheduled check.
Set `collector.timezone` to the installation's Solar.web timezone; local chart dates
include 23/25-hour DST days. The old `history.lookback_days` setting is accepted but
ignored; `collector.retention_days` controls the automatic recovery window.
Recovery pairs the `FromGen` Production series from the consumption view with the
`ToConsumer` Consumption series from the production view, regardless of the display
language. As in `solar`, each five-minute W value is treated as constant over that
interval and divided by 12 to obtain Wh. Self-consumption is the smaller of production
and consumption; purchase/export are their nonnegative differences. These are chart
estimates, rather than the former Query API's measured Wh channels. The original
paired power values and conversion method are retained in each recovered record.
Null or unpaired readings stay missing and are tried again later.
Login uses HTTPS and in-memory cookies. Credentials are submitted only to the Fronius
password endpoint; SSO callbacks and redirects are restricted to the Solar.web and
Fronius login hosts. Credentials are excluded from configuration reprs and never
logged. Session cookies and authentication responses are never logged or written to
disk. An expired session is renewed once. Rejected credentials,
MFA, CAPTCHA, consent, or a changed sign-in form stop that attempt with a redacted
error. Complete any required interactive account setup in a browser.
When migrating from Query API recovery, replace `access_key_id_env` and
`access_key_value_env` with `username` and `password` in `[history]`, or use the
environment fallback above. Obsolete configuration keys are accepted and ignored
for migration. Restart the service after updating its configuration or environment.
Recovery requires the account credentials even if API keys remain set.
```bash
.venv/bin/python -m solar_relay --config config.toml recover \
--from 2026-10-29 --until 2026-10-31
```
Manual recovery accepts at most 30 days per invocation and can query dates older than
the automatic lookback. Only aligned 300-second energy records with all required Wh
channels are accepted; longer aggregates are not split into invented five-minute values.
Manual recovery with explicit date bounds accepts at most 30 days per invocation and
can query dates older than the automatic retention window. Unbounded recovery checks
the whole retention window, even when longer than 30 days. Only aligned five-minute
chart samples in W are accepted;
longer aggregates and unexpected units are rejected.
Recovery stores stable UUIDs and `history_interval` records, which the main website
uses directly without integrating them as live power. Install the corresponding
`solar` receiver update before enabling cloud recovery.
@@ -186,13 +244,14 @@ fresh installation, create it from the example only when it does not exist:
```bash
cd /var/www/html/solar-relay
test -e config.toml || cp config.example.toml config.toml
chmod 0644 config.toml
sudo chgrp www-data config.toml
chmod 0640 config.toml
```
The `www-data` service user needs read access to this configuration. It contains
setting values and environment variable names; keep credentials in the root-readable
environment file below. Ensure the proxy serves the status endpoint rather than
repository files.
The `www-data` service user needs read access to this private configuration, which
may contain the upload token and Solar.web login credentials. Keep real credentials
out of `config.example.toml` and Git. Ensure the proxy serves the status endpoint
rather than repository files.
Keep the archive under `/var/www/html/solar-relay/data/archive`. The relative setting
`data/archive` resolves to that location because paths are relative to `config.toml`.
@@ -222,12 +281,20 @@ exist before starting the service; otherwise systemd exits with `226/NAMESPACE`
before Python can create it. Existing data must be writable by `www-data`. Use
`sudo -u www-data` for archive-writing CLI commands to preserve ownership.
Set `[upload].url` to the main website's `https://your-solar-host/index.php?a=relay`.
Put `SOLAR_RELAY_TOKEN=your-shared-token` in `/etc/solar-relay/solar-relay.env` with
permissions 0600, readable by root. Configure the same token and source ID on the
main website as described in its README. Tokens and API keys stay out of TOML/Git.
Create `/etc/solar-relay` with `sudo install -d -m 0755 /etc/solar-relay` when adding
that optional environment file.
Set the upload URL and shared bearer token in private `config.toml`:
```toml
[upload]
url = "https://your-solar-host/index.php?a=relay"
token = "your-shared-token"
```
Configure the same token and source ID on the main website as described in its README.
No extra environment file is needed. Alternatively, leave `token` empty and provide
the variable named by `token_env` (default `SOLAR_RELAY_TOKEN`). For systemd, put
`SOLAR_RELAY_TOKEN=your-shared-token` in `/etc/solar-relay/solar-relay.env` with
permissions 0600, readable by root. Create `/etc/solar-relay` with
`sudo install -d -m 0755 /etc/solar-relay` when adding that optional environment file.
```bash
sudo cp deploy/solar-relay.service /etc/systemd/system/
@@ -322,4 +389,4 @@ node --check solar_relay/web/status.js
Tests cover normalization, real local HTTP delivery/retries, Parquet round-trips,
concurrent writers, interrupted writes, retention, DST completeness,
mocked authenticated history recovery, status routes and the deployment script.
Live Solar.web recovery requires real Query API credentials and is not exercised by tests.
Live Solar.web recovery requires real account credentials and is not exercised by tests.