Download the PHP package lenorix/laravel-datadis-client without Composer

On this page you can find all versions of the php package lenorix/laravel-datadis-client. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-datadis-client

Datadis client for Laravel

Latest Version on Packagist Total Downloads

Read your electricity data from Datadis in Laravel: supplies, contracts, hourly and quarter-hourly consumption, maximum power, reactive energy, authorizations and open data.

It wraps lenorix/datadis-client and connects it to your app:

Requires PHP 8.4 and Laravel 13 (Laravel 11 and 12 are not supported: lenorix/datadis-client needs Guzzle 8).

Installation

Datadis is a third-party service, so its credentials go in config/services.php:

Fill DATADIS_LEDGER_KEY with a random secret, for example the output of php -r "echo bin2hex(random_bytes(32));". It keys the 24 hour guard.

Check it works:

To change any other setting, publish the config: php artisan vendor:publish --tag="datadis-client-config".

Quick start

Every data call needs the supply as Datadis lists it, so look it up first:

The facade forwards to the same client:

Every call, result and error is documented in the client's README.

Common tasks

Use another account

Add it under accounts in config/datadis-client.php (a name with a dot, like tenant.east, works too):

Read the supplies of someone who authorized you

Give or take away access to your supplies

These change data on Datadis and are never retried. The answers of new-authorization, cancel-authorization and partner-delete-user have not been captured from the real service: the client returns the text Datadis sends, so check it. listAuthorization(), partnerUserList() and partnerAgreementDate() were captured in October 2026.

Read an invoice period

Datadis does not publish the billing day: the retailer sets it, and no field of the contract carries it. Give the client the dates of an invoice, or the day the cycle starts, and it tells which months to ask for and adds up the readings exactly:

The dates of an invoice are the reliable source; a cycle from a day is a guess that the retailer may move.

This is a guarded query like any other, and it can be the same one as the daily refresh: on the days the refresh asks the previous month and the current one, a period over those two months is that very query, and whichever runs second throws RepetitionWindowException. If a daily refresh runs, compute the period from the readings it already returned (and stored), or catch the exception.

Read the open data

Aggregated consumption by region, tariff and sector:

Use it from the terminal

All of them take --account=second. The ones that read (supplies, contract, consumption) also take --holder=12345678Z, to read the supplies of someone who authorized you. The authorization commands act for the account itself, so they have no --holder (it would suggest the operation is made for that holder); datadis:authorizations takes --owner= to list only the authorizations given by one owner. A malformed NIF, CUPS, month or date, and a month range Datadis does not serve, fail with a message and send nothing.

The exit code tells a script what happened:

What to know before production

The 24 hour rule

Datadis refuses an identical consumption or maximum power query for 24 hours, and counts the refused ones too (its manual documents the rule for those two). Reactive energy (API v2 only) is guarded too, and shares its entry with maximum power: on the real service it is refused with the parameters of a maximum power query made just before (seen in October 2026 in the client's capture), while a consumption query for the same month does not collide with it. So ask maximum power and reactive energy for different months or on different days. The package stops a repeat before sending it and throws RepetitionWindowException, which is reported as a warning.

Know until when a query is blocked

A refused repeat carries the answer: RepetitionWindowException::$startDate and $endDate are the months the refused query asked for, whoever refused it: they tell a daily refresh, whose range the client picks, exactly which months it did not get. When the package refused the query, $availableAt is when the same query is allowed again, and $lastAttemptAt when it was last sent (both are null when Datadis itself answered with a 429). Its message says it too, so the log line shows it. To look without sending or claiming anything (a command, a screen), ask the client:

maxPowerBlockedUntilOf() and reactiveDataBlockedUntilOf() do the same. A job should call and catch the exception instead: that decides in one step.

See what the guard does

Every query the guard lets go out, frees, imports or refuses is announced with a Laravel event, Lenorix\LaravelDatadisClient\Events\DatadisLedgerChanged, so you can keep a history or audit the guard without reading the cache:

It carries no personal data: account is the name, not the username (a NIF), key is the guard's keyed hash of the query (the same for the same query), and there is no CUPS. What a listener throws is ignored: a broken listener never decides whether a query goes.

A refusal that Datadis itself makes (a 429) is not an event: it is the RepetitionWindowException, which says the same thing the event does and also which months the query asked for. A refusal the guard makes is both: the exception for the caller, the event for the history.

Refresh the current month every day

Asking the same range every day is refused: the guard keeps a query for 24 hours and 10 minutes. For a daily job use the getLatest methods, which alternate the range from one day to the next:

The current month is always in the range, and the previous month is added every second day. Run it once a day.

One exception, which comes from the client: in the month the contract starts, the range is that month every day, because there is no previous month to alternate with. A run within 24 hours and 10 minutes of the day before asks the same query and is refused (RepetitionWindowException), so that month is refreshed every second day, not every day. Catch the exception, as the job in the skill does. From the next month the range alternates again.

When the contract has nothing to refresh this month (it ended before it, or starts after it) the call throws NothingToRefreshException. Catch that type and not its parent InvalidRequestException, which would also hide a real mistake. The other refusals before sending have their own types too: OutOfServedRangeException (a month Datadis does not serve) and OutOfContractRangeException (a range outside the contract). Reactive energy has no such method (it shares its guard entry with maximum power): ask it for closed months. The datadis-sync Boost skill has a complete job.

Moving from your own record of queries

The guard only knows the queries sent through this package. If your app kept its own record before (a table, say), the first run after the switch could repeat a query sent in the last 24 hours and 10 minutes. Datadis would refuse it, and count it.

Before any worker sends a guarded query with the new client, do one of these:

Failures and retries

Network errors and 502, 503 and 504 answers are retried twice, with backoff, for the login, the lists and the other reads. Consumption, maximum power, reactive energy and every call that changes data are never retried, because Datadis may already have counted them. Set DATADIS_HTTP_RETRIES=0 to turn retries off.

A 401 is different: the client logs in again and repeats only the calls that are safe to repeat. A guarded query, an authorization or a partner user change is not sent again: it fails with an AuthenticationException whose requestSent is true. The open data walks (apiSearchAll(), apiSearchAutoAll()) throw a PageLimitReachedException after the last record when they stop at their page limit with a full last page, since more records may remain.

Your password and token

The calls go through plain Guzzle, so Laravel's HTTP events, global middleware and recorders (Telescope, Nightwatch) never see the login password or the token. Keep it that way outside tests.

The token is kept in Laravel's default cache, which the package uses without Laravel's cache events, so the cache watchers do not record it either. The store itself still holds it: protect it like a password.

Queued jobs

The client holds a password and refuses to be serialised (it throws a LogicException). The exceptions it throws can be, without their trace. Type-hint it in handle(), never in the constructor or a property. For a backfill, dispatch one job per month with $tries = 1.

Testing your application

In the test environment (APP_ENV=testing) the calls go through Laravel's Http client, so fake Datadis as any other service:

FakesDatadis::fake() answers every endpoint of the client and the login, starts from a fresh HTTP factory (Http::fake() accumulates stubs, and the first one that matches wins, so a second fake would be ignored), puts your answers before the defaults, and fails on a URL nobody answers instead of reaching Datadis. It forces the package onto Laravel's HTTP client for the test (outside the testing environment it would send through plain Guzzle, which cannot be faked), and it replaces every fake the test had before, for any service: call it first, then add other services with Http::fake(), or pass them in its answers. supply: [...] changes fields of its default supply, and FakesDatadis::token() is a fake token for a test that needs one.

Configuration

All keys are in config/datadis-client.php.

Key What it does Default
default Account used by the container, the facade and the commands (DATADIS_ACCOUNT). default
accounts.* username, password, api_version (v1/v2, DATADIS_API_VERSION), timezone (DATADIS_TIMEZONE), timeout (DATADIS_TIMEOUT), connect_timeout (DATADIS_CONNECT_TIMEOUT), base_url, user_agent, check_username_control. The account named default takes its credentials from services.datadis. v2, Europe/Madrid, 120 s, 10 s
ledger.key Secret of at least 16 bytes for the guard (DATADIS_LEDGER_KEY). from APP_KEY
http.stack guzzle or laravel (DATADIS_HTTP_STACK). laravel lets Laravel's events and recorders see the password and the token. guzzle; laravel in tests
http.retries max (0 to 10, DATADIS_HTTP_RETRIES), base_delay_ms, max_delay_ms. Whole numbers, delays of at least 1 ms and max_delay_ms not below base_delay_ms, or the client fails to build. 2, 1000, 30000
http.options Extra Guzzle options for every call: a proxy, verify... They replace the package's own timeout and connect_timeout. debug is refused, because it would print the login password. none
report_level PSR-3 log level of a refused repeat (DATADIS_REPORT_LEVEL), or null to leave your exception handler alone. warning

Laravel Boost

The package ships Laravel Boost resources, so your coding agent learns how to call Datadis, which calls count against the 24 hour rule, how to write sync jobs and how to test them.

Run php artisan boost:install and, when Boost asks which third-party guidelines and skills to install, pick lenorix/laravel-datadis-client. Without interaction (CI, scripts) Boost only installs what boost.json lists: add "packages": ["lenorix/laravel-datadis-client"] to it and run php artisan boost:update; its four skills (datadis-development, datadis-electricity-domain, datadis-sync, datadis-testing) come with the package. The guideline lands in CLAUDE.md and AGENTS.md, and the skills in .claude/skills and .agents/skills.

Contributing, security and license

To contribute, read changelog.

Created by Jesus Hernandez and contributors. Released under The Unlicense, in the public domain.


All versions of laravel-datadis-client with dependencies

PHP Build Version
Package Version
Requires php Version ^8.4
illuminate/console Version ^13.0
illuminate/contracts Version ^13.0
illuminate/http Version ^13.0
illuminate/support Version ^13.0
lenorix/datadis-client Version ^0.9.0
psr/clock Version ^1.0
spatie/laravel-package-tools Version ^1.16
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package lenorix/laravel-datadis-client contains the following files

Loading the files please wait ...