Skip to main content

Python SDK client for the Daly Energy REST API

Project description

daly-energy

Python SDK client for the Daly Energy REST API.

Installation

pip install daly-energy

Install the query helpers with pandas support when you want DataFrame input:

pip install "daly-energy[query]"

Quick Start

from dalysdk import DalyClient

client = DalyClient(
    workspace_api_key="wk_...",
    user_api_key="uk_...",
)

# List locations
locations = client.locations.list()

# Create a project
project = client.projects.create({
    "name": "My Solar Project",
    "location_index": 1,
})

# Always close when done
client.close()

Or use as a context manager:

with DalyClient(workspace_api_key="wk_...", user_api_key="uk_...") as client:
    projects = client.projects.list()

Saved Energy Model Edit/Rerun

with DalyClient(workspace_api_key="wk_...", user_api_key="uk_...") as client:
    saved = client.energy_models.get_with_inputs(56)
    edited = dict(saved["inputs"])
    edited["output"] = {"name": "Variant A - Updated"}

    client.energy_models.update(56, edited)
    queued = client.energy_models.run_saved(56, async_mode=True)

    assert queued["energyModelId"] == 56

run_saved() reruns the same saved energy-model row in place rather than creating a new one. If you need different output controls for the rerun, update the saved model first and then call run_saved(). The rerun endpoint does not take a request body override.

Energy-model submissions are async-only. The SDK submits create() and run_saved() requests as accepted jobs and treats any 2xx response, including 202 Accepted, as success. Poll client.tasks for completion if you need finished results.

Energy Model Query Workflows

For modern SDK usage, use client.energy_models.query(...) when you want the SDK to normalize an inline weather dataset into the canonical API weatherData payload. Use client.energy_models.create(...) when you already have the full API request body prepared.

with DalyClient(workspace_api_key="wk_...", user_api_key="uk_...") as client:
    accepted = client.energy_models.query(
        {
            "locationId": 9,
            "blocks": [
                {
                    "name": "Block A",
                    "inverterDefinition": {"inverterIndex": 1},
                    "moduleDefinition": {"moduleIndex": 1},
                    "surfaceDefinition": {
                        "surfaceType": "fixed_tilt",
                        "surfaceTilt": 20,
                        "surfaceAzimuth": 180,
                    },
                    "moduleStringingDefinition": {
                        "modulesPerString": 20,
                        "stringsPerInverter": 5,
                    },
                }
            ],
        },
        [
            {
                "timestamp": "2024-01-01T00:00:00Z",
                "ghi": 0.0,
                "dhi": 0.0,
                "temp": 15.0,
                "wind_speed": 1.2,
            },
            {
                "timestamp": "2024-01-01T01:00:00Z",
                "ghi": 10.2,
                "dhi": 8.3,
                "temp": 14.8,
                "wind_speed": 1.1,
            },
        ],
        time_step_format="utc",
    )

query() accepts weather rows keyed by date, timestamp, or datetime and normalizes them to the API's canonical weatherData.date array before submission. If you want to inspect the exact payload before sending it, use client.energy_models.build_query_payload(...).

If you already have the final API payload, submit it directly:

with DalyClient(workspace_api_key="wk_...", user_api_key="uk_...") as client:
    result = client.energy_models.create(
        {
            "location": {
                "latitude": 33.4,
                "longitude": -112.0,
                "elevation": 337,
                "timeZone": -7,
            },
            "weatherData": {
                "date": [
                    1704067200000,
                    1704070800000,
                    1704074400000,
                ],
                "ghi": [0.0, 0.0, 10.2],
                "dhi": [0.0, 0.0, 8.3],
                "windSpeed": [1.2, 1.1, 0.8],
                "temperature": [15.0, 14.8, 14.6],
            },
            "blocks": [
                {
                    "name": "Block A",
                    "inverterDefinition": {"inverterIndex": 1},
                    "moduleDefinition": {"moduleIndex": 1},
                    "surfaceDefinition": {
                        "surfaceType": "fixed_tilt",
                        "surfaceTilt": 20,
                        "surfaceAzimuth": 180,
                    },
                    "moduleStringingDefinition": {
                        "modulesPerString": 20,
                        "stringsPerInverter": 5,
                    },
                }
            ],
        },
        async_mode=True,
    )

Output controls and returned time-series

Use the canonical API output fields directly in the payload you pass to client.energy_models.create(...):

  • output.timeSeries requests plant-level timeSeries
  • output.fullTimeSeries requests extended plant-level series
  • output.blockResults requests blockTimeSeries
  • output.blockIndex filters the returned blockTimeSeries map to one zero-based block
  • output.lossBreakdownTimestamps implies block-level results and adds timestamped loss detail under blockTimeSeries[<blockIndex>].lossBreakdown
  • output.irradianceLossDetail adds annual detail under losses.irradianceLossDetail

Important behavior:

  • output.blockIndex filters the returned response; it does not trim the submitted blocks array down to single-block execution.
  • Returned blockTimeSeries keys preserve the API's original zero-based block numbering, including filtered single-block responses.
  • If you need to change output controls for run_saved(), update the saved row first with client.energy_models.update(...).
  • The SDK no longer assumes inline sync completion for these submissions; use task polling if your workflow needs final outputs.

Legacy query adapters (compatibility only)

  • client.energy_models.create_legacy_query(...)
  • client.run_energy_model(...)
  • LegacyEnergyModel.run_query(...)

These helpers are provided only for backward compatibility. They preserve the old block-query controls (block_results, block_results_index) by translating them into legacy request fields while keeping the full model block list intact. They are not the recommended modern SDK workflow.

Legacy block-query behavior now follows the current API contract:

  • block_results_index maps to deprecated selected-block compatibility fields
  • the API treats that selection as filtered blockTimeSeries output, not reduced execution scope
  • returned block keys still use the original zero-based block indexes
  • compatibility inputs such as run_async, block_results, and block_results_index remain accepted, but they do not restore inline sync execution semantics

LegacyEnergyModel.run_query(...) also keeps legacy method signatures for compatibility, but it does not apply date/time shaping from start_date, end_date, or time_step_format; those arguments are accepted and ignored.

Migration note

If you are migrating from older legacy query code:

  1. Prefer direct client.energy_models.create(...) calls with explicit, complete request payloads.
  2. Keep using LegacyEnergyModel.run_query(...) only as a temporary bridge while removing legacy block-query assumptions.
  3. Do not assume LegacyEnergyModel.run_query(...) reproduces historical date-window query behavior; validate payload shaping in your own code before request submission.

Resources

The client exposes the following resource namespaces:

  • client.locations — Location management
  • client.projects — Project CRUD
  • client.modules — PV module library
  • client.inverters — Inverter library
  • client.energy_models — Energy model runs
  • client.shading_scenes — 3D shading analysis
  • client.weather_data — Weather data management
  • client.tasks — Async task tracking
  • client.workflows — Multi-step workflow orchestration
  • client.workspaces — Workspace management

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

daly_energy-2.0.0.tar.gz (35.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

daly_energy-2.0.0-py3-none-any.whl (33.6 kB view details)

Uploaded Python 3

File details

Details for the file daly_energy-2.0.0.tar.gz.

File metadata

  • Download URL: daly_energy-2.0.0.tar.gz
  • Upload date:
  • Size: 35.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for daly_energy-2.0.0.tar.gz
Algorithm Hash digest
SHA256 74d477a47a3a80bb4aa484440af6b734de061a6ae2c344eb98a57e97fc6094bf
MD5 fb3b3dfacef7d641fd16a31b1aba275c
BLAKE2b-256 3f6018bb0274d1c427566d9a357261bcedb2d90a102e5151e9690f909ce29f59

See more details on using hashes here.

File details

Details for the file daly_energy-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: daly_energy-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 33.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for daly_energy-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b5c490eedee63a9ced3885e17f19034fb95b60bd3b84cfb680f4284cb5864530
MD5 634fe530cf11e460b4260bbfe78b834b
BLAKE2b-256 494a19a4431fb3eacd598c79a0a85f7891c526c85ecbf7348a0eb115a04a6bb8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page