Skip to main content

energy_api/
lib.rs

1//! # energy-api
2//!
3//! Rust client and server bindings for the German energy market API-Webdienste
4//! (MaKo — Marktkommunikation).
5//!
6//! ## Module layout
7//!
8//! ```text
9//! energy_api
10//! ├── models/       OpenAPI/AsyncAPI types shared by all APIs
11//! ├── transport/    HTTP + mTLS builder, JWS sign/verify
12//! ├── directory/    Verzeichnisdienst — REST client, WebSocket client, server
13//! ├── client/       Electricity API clients  (feature = "client")
14//! │   ├── control_measures   NB/LF and MSB send calls
15//! │   └── malo_ident         LF and NB callback calls
16//! └── server/       Electricity API servers  (feature = "server")
17//!     ├── control_measures   MSB and NB/LF receive handlers + axum router
18//!     └── malo_ident         NB and LF receive handlers + axum router
19//! ```
20//!
21//! ## Feature flags
22//!
23//! | Feature     | Enables                                                  |
24//! |-------------|----------------------------------------------------------|
25//! | `client`    | HTTP clients for all APIs (reqwest + rustls)             |
26//! | `server`    | Axum router factories for server implementations         |
27//! | `websocket` | WebSocket subscription client (tokio-tungstenite)        |
28//! | `crypto`    | JWS ECDSA-SHA256 sign/verify for directory records (p256)|
29//!
30//! ## Quick start
31//!
32//! ### Look up an endpoint via the directory
33//!
34//! ```no_run
35//! # #[cfg(feature = "client")]
36//! # async fn example() -> Result<(), energy_api::Error> {
37//! use energy_api::directory::DirectoryServiceClient;
38//! use url::Url;
39//!
40//! let base = Url::parse("https://verzeichnisdienst.example.de/")?;
41//! let client = DirectoryServiceClient::new_insecure(base)?;
42//! let (record, _cert, _sig) = client
43//!     .get_record("1234567890123", "controlMeasuresV1", 1)
44//!     .await?;
45//! println!("{}", record.url);
46//! # Ok(())
47//! # }
48//! ```
49//!
50//! ### Send a grid control command
51//!
52//! ```no_run
53//! # #[cfg(feature = "client")]
54//! # async fn example() -> Result<(), energy_api::Error> {
55//! use energy_api::client::ControlMeasuresClient;
56//! use energy_api::models::electricity::{
57//!     CommandControl, LocationId, NeloId, MaximumPowerValue,
58//! };
59//! use url::Url;
60//! use uuid::Uuid;
61//!
62//! let client = ControlMeasuresClient::new(
63//!     Url::parse("https://msb.example.de/")?,
64//!     reqwest::Client::new(),
65//! );
66//! client.send_konfiguration(
67//!     Uuid::new_v4(),
68//!     "2025-06-01T10:00:00.000Z",
69//!     &LocationId::NetworkLocation(NeloId("E1234848431".into())),
70//!     &CommandControl {
71//!         maximum_power_value: MaximumPowerValue("10.5".into()),
72//!         execution_time_from: "2025-06-01T10:00:00Z".into(),
73//!         execution_time_until: None,
74//!     },
75//!     None,
76//! ).await?;
77//! # Ok(())
78//! # }
79//! ```
80
81#![allow(clippy::too_many_arguments)]
82#![allow(clippy::large_enum_variant)]
83
84pub mod directory;
85pub mod error;
86pub mod models;
87pub mod spec_version;
88pub mod transport;
89
90#[cfg(feature = "client")]
91pub mod client;
92
93#[cfg(feature = "server")]
94pub mod server;
95
96pub use error::Error;