This commit is contained in:
1 parent
646ba3be81
commit
aae5b73581
14 files changed
+883
-142
No files matched your search
@@ -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.
|
||||
Reference in new issue
Block a user