Skip to main content
To supply a market location in a grid, the Lieferant needs a Lieferantenrahmenvertrag (LRV) with its Netzbetreiber. The contract is the BNetzA’s standard (BK6-13-042 as amended by BK6-20-160), the same for every VNB. It needs no written form: it is in force once the Lieferant accepts it (§ 13 Nr. 1 LRV). Where Lieferant and BKV are the same company, the Zuordnungsvereinbarung is part of it and needs no signature of its own (§ 17 Nr. 1). The Zuordnungsermächtigung still goes separately by MaBiS. The bridge asks each Netzbetreiber from the Lieferant’s own mailbox. It reads the answers and does what an answer allows. Everything else goes to a person in the inbox. The code lives in lieferant/lrv/ and reads partner data through the same directory as the BKV (marktpartner/).

Two variants

There is one open Vorgang per Netzbetreiber and variant. A second request for the same pair is skipped, and so is a gv request to a partner the contract records already hold a Lieferantenrahmenvertrag with.

Whom it goes to

The Netzbetreiber says this itself in the PARTIN it sends to the Lieferant (PARTIN AHB 1.1, 37001, NAD contact blocks). The block for Rahmenverträge (Z11) is sent to a Lieferant only, never to a BKV. That is why the directory reads the Lieferant’s datasheets first, then the BKV’s. The Vorgang records where the address came from: the function, the unit and the datasheet (sender, receiver, reference, date). If no block yields an address, nothing is sent. The Vorgang is NO_CONTACT and its case waits for a person, who can either:
  • name an address by hand (email, one partner per request), or
  • allow the BDEW code list’s address (bdew_fallback).
The bridge never guesses an address. The order of functions is configurable (LRV_KONTAKTFUNKTIONEN_GV / _DV).

Draft, release, send

1

Request

POST /v1/process/lrv/anfragen with the partners (MP-ID, Bilanzierungsgebiet EIC or name) and the variant. Each request is drafted from the templates in data/lrv/ (German, Sie-Form). Every subject carries the token [LRV-<MP-ID>-<kurzid>] that answers are attributed by.
2

Release

The draft waits as a proposal of the tool lrv-senden in the Vorgang’s case. Releasing it, in the inbox or by POST /v1/process/lrv/vorgaenge/{id}/freigeben, sends it. With autopilot: true the request goes out at once, and so do the later answers built from the document pool and the reminder.
3

Send

The attachments are made at the moment of sending: the Kontaktdatenblätter from the company’s templates with the send date as Stand, and the Deckblatt as a filled PDF. The mail leaves the Lieferant’s mailbox and is filed in its Sent folder. The exact bytes go to the archive. A gv request sets the contract record to angefragt.

Answers

The routine (or POST /v1/process/lrv/poll) reads the Lieferant’s inbox. An answer is attributed by, in this order:
  1. the token in subject or text;
  2. the Message-ID of one of our mails in In-Reply-To / References;
  3. the sender’s domain plus an MP-ID in the text, ours or the Netzbetreiber’s, if that names exactly one open Vorgang.
A mail that cannot be attributed stays in the mailbox untouched. An attributed mail is archived exactly as it arrived. It is then read by the model (CLASSIFIER_MODEL, with up to three PDF attachments as documents) into a fixed schema:
  • status, confidence
  • requested_documents, provided_documents
  • deadline, contact_person, portal_url, conditions
  • summary_de
  • plus a verbatim beleg, and the abweichungen from the standard for a contract of the Netzbetreiber’s own
The model only reads; the bridge decides. A reading leads to a step only if all of the following hold:
  • its confidence reaches LRV_MIN_KONFIDENZ (0.8);
  • its quote stands in the partner’s own words: above the quoted part, and not a sentence of our own mail;
  • it names no condition that only a person may grant.
A handled answer moves to the archive folder (LF_IMAP_FOLDER_ARCHIVE). One that went to a person stays in the inbox, where it is read. An answer to a Vorgang that is already final is archived and handed to a person, not read again. The BKV’s Erstkontakt reconciliation leaves mails with an LRV token alone.
Never automatic, whatever an answer asks: a signature, a registration in a portal, a promise of prepayment or security (§ 11 LRV), a change to the contract. Each becomes a task for a person. The form filler never writes a signature, date, place-of-signing or contact-person field.

Deadlines

The routine counts in Werktage of the market calendar: no weekends, no holidays of any Land, not 24 or 31 December. It counts from the day our last mail went out:
  • after LRV_NACHFASS_WERKTAGE (5) without an answer: one reminder, with the attachments made anew, drafted for release or sent at once on autopilot;
  • after LRV_ESKALATION_WERKTAGE (10): ESKALIERT. A person takes over, an unreleased reminder is dropped, and nothing more is sent. A later answer is still processed.
An auto-reply does not stop the clock; an answer does, and a reply of ours starts it again. The routine is the built-in agent Lieferantenrahmenvertrag (lrv), which is off until it is enabled in the console’s agents. It runs only when the Lieferant’s IMAP is configured, and last in the orchestrator’s round, so that a slow mailbox never delays the day steps. It reads the inbox first and then looks at the deadlines. A failed read stops the round (lrv_fehler), so a reminder is never sent blind.

Records

Each Vorgang is a state machine in the ledger lrv_vorgaenge:
  • Process states: ENTWURF, NO_CONTACT, GESENDET, NACHGEFASST, ESKALIERT, ABGEBROCHEN.
  • Answer states: the readings above.
Every transition is kept in the Vorgang’s verlauf with:
  • its moment;
  • its trigger: a mail, the reading, a person, a deadline;
  • its raw data.
The entries are hash-chained, so a changed entry breaks the chain. Every mail, sent and received, is stored as raw bytes under lrv/<Vorgang>/ on the audit share. A file is written once and never overwritten, and its SHA-256 is in the verlauf. Contracts and filled forms lie under lrv/<Vorgang>/dateien/. GET /v1/process/lrv/vorgaenge/{id} reports whether the chain and the archive are intact.
This makes a change detectable, not impossible. Storage that cannot be changed at all (WORM, an immutability policy on the share) is a matter of the storage account, not of this code.

Document pool

What a Netzbetreiber may ask for beyond the request is uploaded once per kind:
  • handelsregisterauszug
  • zertifikat
  • edi_vereinbarung
  • vollmacht
Files are PDF, XLSX, DOCX or an image, up to 10 MB each. A new upload replaces the current file, and the replaced ones are kept.
The Kontaktdatenblätter are never in the pool: they are made from the configuration (PARTIN_COMPANY, MP-IDs, EIC) whenever a mail goes out. The Regelzone and the ÜNB of the Bilanzkreisvertrag come from HOME_CONTROL_AREA; for n:lead that is Amprion.

API

All endpoints use the process scope under /v1/process/lrv. The events are:
  • lrv_gesendet, lrv_antworten, lrv_fristen, lrv_abgeschlossen;
  • lrv_no_contact, lrv_eskaliert and lrv_fehler as warnings in the operator app’s feed.
lrv_eskaliert also raises an alert. The settings are listed under Configuration → Lieferant.