Ctrl K
ComunidadGuías…

spec/fixtures/service_env_contract.yml

Rama develop · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Contract between HELIOS's exporters and the services they configure.
#
# For every managed service (Export::Compose::SERVICE_ORDER) this lists the
# environment variables the service ACTUALLY reads — taken from its source, not
# from its documentation. service_env_contract_spec.rb checks the exported
# compose.yaml against it in both directions:
#
#   * every variable an exporter emits is one the service reads
#   * every variable the service needs is emitted
#
# This is what catches the class of bug where both sides drift apart silently:
# a collector that defaults an unknown variable (importing to the wrong
# measurement), or one that reads a name HELIOS never writes.
#
# `reads`      — exact variable names the service consumes
# `patterns`   — dynamically built names (glob), e.g. MAPPING_0_TOPIC
# `requires`   — must always be emitted; the service fails or misbehaves without it
# `tolerated`  — knowingly emitted but never read (with a reason); keeps the
#                gap visible instead of silently widening the `reads` list
#
# When a service gains or loses a variable upstream, update it here.

dashboard:
  upstream: solectrus/config/application.rb, config/database.yml, app/lib/sensor/config.rb
  reads:
    - TZ
    - APP_HOST
    - FRAME_ANCESTORS
    - PLAUSIBLE_URL
    - HONEYBADGER_API_KEY
    - RORVSWILD_API_KEY
    - CO2_EMISSION_FACTOR
    - CURRENCY
    - INFLUX_SCHEMA
    - INFLUX_HOST
    - INFLUX_PORT
    - INFLUX_ORG
    - INFLUX_BUCKET
    - INFLUX_TOKEN
    - INFLUX_EXCLUDE_FROM_HOUSE_POWER
    - INSTALLATION_DATE
    - ADMIN_PASSWORD
    - LOCKUP_CODEWORD
    - UI_THEME
    - NOMINATIM_URL # an empty value turns the address lookup off
    - SKIP_BROWSER_CHECK
    - REDIS_URL
    - DB_HOST
    - DB_PORT
    - DB_USER
    - DB_PASSWORD
    - RAILS_MAX_THREADS
    - RAILS_LOG_LEVEL
    - PORT
    - ASSET_HOST
    - FORCE_SSL
    - TRUSTED_PROXY_RANGES
    - SECRET_KEY_BASE # read by Rails itself, not by app code
    - WEB_CONCURRENCY # read by Puma itself (worker count), not by puma.rb
  patterns:
    - INFLUX_SENSOR_* # app/lib/sensor/config.rb — one per sensor in the registry
  requires:
    - INFLUX_HOST
    - INFLUX_TOKEN
    - INFLUX_ORG
    - INFLUX_BUCKET
    - DB_HOST
    - DB_USER
    - DB_PASSWORD

ingest:
  upstream: ingest/app/lib/influx_writer.rb, app/lib/sensor_env_config.rb
  reads:
    - TZ
    - INFLUX_HOST
    - INFLUX_PORT
    - INFLUX_SCHEMA
    - INFLUX_ORG # unused by ingest itself, but harmless; see notes below
    - INFLUX_BUCKET
    - INFLUX_EXCLUDE_FROM_HOUSE_POWER
    - RETENTION_HOURS
    - STATS_PASSWORD
    - APP_ENV
  patterns:
    - INFLUX_SENSOR_* # app/lib/sensor_env_config.rb KEYS
  requires:
    - INFLUX_HOST
  # Ingest authenticates each write with the token the caller passes in the
  # Authorization header, so it deliberately gets no INFLUX_TOKEN.

mqtt-collector:
  upstream: mqtt-collector/lib/config.rb
  reads:
    - TZ
    - MQTT_HOST
    - MQTT_PORT
    - MQTT_SSL
    - MQTT_USERNAME
    - MQTT_PASSWORD
    - INFLUX_HOST
    - INFLUX_PORT
    - INFLUX_SCHEMA
    - INFLUX_TOKEN
    - INFLUX_ORG
    - INFLUX_BUCKET
  patterns:
    - MAPPING_*
  requires:
    - MQTT_HOST
    - MQTT_PORT # env.fetch without a fallback — absent means KeyError
    - INFLUX_HOST
    - INFLUX_TOKEN
    - INFLUX_ORG
    - INFLUX_BUCKET

senec-collector:
  upstream: senec-collector/lib/config.rb
  reads:
    - TZ
    - SENEC_ADAPTER
    - SENEC_HOST
    - SENEC_SCHEMA
    - SENEC_LANGUAGE
    - SENEC_INTERVAL
    - SENEC_IGNORE
    - SENEC_REQUEST_MODE
    - SENEC_USERNAME
    - SENEC_PASSWORD
    - SENEC_TOTP_URI
    - SENEC_SYSTEM_ID
    - INFLUX_HOST
    - INFLUX_PORT
    - INFLUX_SCHEMA
    - INFLUX_TOKEN
    - INFLUX_ORG
    - INFLUX_BUCKET
    - INFLUX_MEASUREMENT # NOT INFLUX_MEASUREMENT_SENEC — that is the .env name only
  requires:
    - INFLUX_HOST
    - INFLUX_TOKEN
    - INFLUX_ORG
    - INFLUX_BUCKET

forecast-collector:
  upstream: forecast-collector/app/config.rb, app/config/*.rb
  reads:
    - TZ
    - FORECAST_PROVIDER
    - FORECAST_CONFIGURATIONS
    - FORECAST_INTERVAL
    - FORECAST_LATITUDE
    - FORECAST_LONGITUDE
    - FORECAST_DECLINATION
    - FORECAST_AZIMUTH
    - FORECAST_KWP
    - FORECAST_DAMPING_MORNING
    - FORECAST_DAMPING_EVENING
    - FORECAST_INVERTER # kilowatts, not watts
    - FORECAST_HORIZON
    - FORECAST_SOLAR_APIKEY
    - SOLCAST_SITE
    - SOLCAST_APIKEY
    - PVNODE_SITE_ID
    - PVNODE_APIKEY
    - PVNODE_PAID
    - PVNODE_REQUEST_LIMIT
    - PVNODE_EXTRA_PARAMS
    - INFLUX_HOST
    - INFLUX_PORT
    - INFLUX_SCHEMA
    - INFLUX_TOKEN
    - INFLUX_ORG
    - INFLUX_BUCKET
    - INFLUX_MEASUREMENT
  patterns:
    - FORECAST_*_LATITUDE
    - FORECAST_*_LONGITUDE
    - FORECAST_*_DECLINATION
    - FORECAST_*_AZIMUTH
    - FORECAST_*_KWP
    - FORECAST_*_DAMPING_MORNING
    - FORECAST_*_DAMPING_EVENING
    - FORECAST_*_INVERTER
    - FORECAST_*_HORIZON
    - SOLCAST_*_SITE
    - PVNODE_*_EXTRA_PARAMS
  requires:
    - INFLUX_HOST
    - INFLUX_TOKEN
    - INFLUX_ORG
    - INFLUX_BUCKET

tibber-collector:
  upstream: tibber-collector/app/config.rb
  reads:
    - TZ
    - TIBBER_TOKEN
    - TIBBER_INTERVAL
    - INFLUX_HOST
    - INFLUX_PORT
    - INFLUX_SCHEMA
    - INFLUX_TOKEN
    - INFLUX_ORG
    - INFLUX_BUCKET
    - INFLUX_MEASUREMENT # NOT INFLUX_MEASUREMENT_PRICES — that is the .env name only
  requires:
    - TIBBER_TOKEN
    - INFLUX_HOST
    - INFLUX_TOKEN
    - INFLUX_ORG
    - INFLUX_BUCKET

public-data-collector:
  upstream: public-data-collector/lib/config.rb, lib/providers/*/provider.rb, lib/providers/country.rb
  reads:
    - TZ
    - COUNTRY
    - INTERVAL
    - ENABLE_FUEL # Providers::Base reads <switch> of each provider
    - ENABLE_GAS
    - ENABLE_PUBLIC_GRID
    - BIDDING_ZONE
    - INFLUX_HOST
    - INFLUX_PORT
    - INFLUX_SCHEMA
    - INFLUX_TOKEN
    - INFLUX_ORG
    - INFLUX_BUCKET
  requires:
    - COUNTRY # Env::Error without it
    - ENABLE_FUEL # at least one source must be on
    - INFLUX_HOST
    - INFLUX_TOKEN
    - INFLUX_ORG
    - INFLUX_BUCKET

senec-charger:
  upstream: senec-charger/app/config.rb
  reads:
    - TZ
    - SENEC_HOST
    - SENEC_SCHEMA
    - CHARGER_INTERVAL
    - CHARGER_PRICE_MAX
    - CHARGER_PRICE_TIME_RANGE
    - CHARGER_FORECAST_THRESHOLD
    - CHARGER_DRY_RUN
    - INFLUX_HOST
    - INFLUX_PORT
    - INFLUX_SCHEMA
    - INFLUX_TOKEN
    - INFLUX_ORG
    - INFLUX_BUCKET
    - INFLUX_MEASUREMENT_PRICES # read directly, unlike the collectors' INFLUX_MEASUREMENT
    - INFLUX_MEASUREMENT_FORECAST
  requires:
    - SENEC_HOST
    - INFLUX_HOST
    - INFLUX_TOKEN
    - INFLUX_ORG
    - INFLUX_BUCKET

shelly-collector:
  upstream: shelly-collector/lib/config.rb
  reads:
    - TZ
    - SHELLY_HOST
    - SHELLY_PASSWORD
    - SHELLY_CLOUD_SERVER
    - SHELLY_DEVICE_ID
    - SHELLY_AUTH_KEY
    - SHELLY_INTERVAL
    - SHELLY_INVERT_POWER
    - INFLUX_HOST
    - INFLUX_PORT
    - INFLUX_SCHEMA
    - INFLUX_TOKEN
    - INFLUX_ORG
    - INFLUX_BUCKET
    - INFLUX_MEASUREMENT
    - INFLUX_MODE
    - INFLUX_POWER_DATA_TYPE
  requires:
    - INFLUX_HOST
    - INFLUX_TOKEN
    - INFLUX_ORG

power-splitter:
  upstream: power-splitter/lib/config.rb
  reads:
    - TZ
    - INSTALLATION_DATE
    - POWER_SPLITTER_INTERVAL
    - INFLUX_HOST
    - INFLUX_PORT
    - INFLUX_SCHEMA
    - INFLUX_TOKEN
    - INFLUX_ORG
    - INFLUX_BUCKET
    - INFLUX_EXCLUDE_FROM_HOUSE_POWER
    - REDIS_URL
    - DB_HOST
    - DB_USER
    - DB_PASSWORD
  patterns:
    # The splitter only knows grid_import_power, house_power, heatpump_power,
    # wallbox_power, battery_charging_power and custom_power_01..20
    # (lib/config.rb SENSOR_NAMES). HELIOS emits the whole sensor block; the
    # extra names are simply ignored, so they stay tolerated rather than
    # tightening the exporter and risking a sensor the splitter does need.
    - INFLUX_SENSOR_*
  requires:
    - INFLUX_SENSOR_GRID_IMPORT_POWER # Config::Error without it
    - INFLUX_SENSOR_HOUSE_POWER # Config::Error without it
    - INFLUX_HOST
    - INFLUX_TOKEN
    - INFLUX_ORG
    - INFLUX_BUCKET
  tolerated:
    # HELIOS wires the splitter to Postgres via DB_PASSWORD=${POSTGRES_PASSWORD};
    # the bare POSTGRES_PASSWORD passthrough is what that reference resolves to.
    - POSTGRES_PASSWORD

# csv-importer is not a compose service — CsvImportRunner starts it with
# `docker run -e`. Checked separately by the spec.
csv-importer:
  upstream: csv-importer/app/config.rb
  reads:
    - TZ
    - IMPORT_FOLDER
    - IMPORT_PAUSE
    - SENEC_IGNORE
    - INFLUX_HOST
    - INFLUX_PORT
    - INFLUX_SCHEMA
    - INFLUX_TOKEN
    - INFLUX_TOKEN_WRITE
    - INFLUX_ORG
    - INFLUX_BUCKET
    - INFLUX_OPEN_TIMEOUT
    - INFLUX_READ_TIMEOUT
    - INFLUX_WRITE_TIMEOUT
    - INFLUX_SENSOR_INVERTER_POWER
    - INFLUX_SENSOR_HOUSE_POWER
    - INFLUX_SENSOR_GRID_IMPORT_POWER
    - INFLUX_SENSOR_GRID_EXPORT_POWER
    - INFLUX_SENSOR_BATTERY_CHARGING_POWER
    - INFLUX_SENSOR_BATTERY_DISCHARGING_POWER
    - INFLUX_SENSOR_BATTERY_SOC

# Third-party images: the variables come from the upstream image, not from a
# SOLECTRUS source we can read. Listed so a new service cannot slip past the
# spec unnoticed, but only checked for unknown names.
influxdb:
  upstream: docker.io/influxdb (entrypoint)
  third_party: true
  reads:
    - TZ
    - DOCKER_INFLUXDB_INIT_MODE
    - DOCKER_INFLUXDB_INIT_USERNAME
    - DOCKER_INFLUXDB_INIT_PASSWORD
    - DOCKER_INFLUXDB_INIT_ORG
    - DOCKER_INFLUXDB_INIT_BUCKET
    - DOCKER_INFLUXDB_INIT_ADMIN_TOKEN
    - INFLUXD_METRICS_DISABLED

postgresql:
  upstream: docker.io/postgres (entrypoint)
  third_party: true
  reads:
    - TZ
    - POSTGRES_DB
    - POSTGRES_PASSWORD
    - POSTGRES_USER

redis:
  upstream: docker.io/redis
  third_party: true
  reads:
    - TZ

mosquitto:
  upstream: docker.io/eclipse-mosquitto (read by the generated command, not by the broker itself)
  third_party: true
  reads:
    - TZ
    - MQTT_PASSWORD
    - MQTT_USERNAME

traefik:
  upstream: docker.io/traefik (configured via CLI flags and labels, not env)
  third_party: true
  reads:
    - TZ

watchtower:
  upstream: nickfedor/watchtower
  third_party: true
  reads:
    - TZ
    - WATCHTOWER_CLEANUP
    - WATCHTOWER_POLL_INTERVAL
    - WATCHTOWER_SCHEDULE
    - WATCHTOWER_SCOPE
    - WATCHTOWER_TIMEOUT

helios:
  upstream: this app (config/application.rb, config/environments/production.rb)
  reads:
    - TZ
    - ADMIN_PASSWORD
    - SECRET_KEY_BASE
    - FORCE_SSL