# Scalar-Typen für die GraphQL-Schnittstelle - siehe DateTimeScalarConfig.class scalar DateTime scalar Date type Query { allWaehrungen: [Waehrung!]! waehrungByCurrencyCode(currencyCode: String!): [Waehrung!] waehrungByCurrencyType(currencyType: String!): [Waehrung!] sensors: [Sensor] sensor(id: ID!): Sensor measureConceptList(measurementConceptId: ID!, namePattern: String) : [MeasureConcept] findObservation( measurementConceptId: ID!, sensorName: String, observationVariableNamePattern:String, startTime:String, endTime:String) : [Observation] findGapsInObservations (measurementConceptId: ID!,sensorId: ID, startTime: String, endTime: String, gapDurationMinutes: Int, turnOfMonth: Boolean): [ObservationGap] findNearestObservations(measurementConceptId: ID!,sensorName: String, observationVariableName: String, variableUnitIdList: [ID], timeUTC: String,timeOrder: String): [ObservationDetails] findObservationSummaryList(measurementConceptId: ID!): [ObservationSummary] findObservationVariableSummaryList(measurementConceptId: ID!): [ObservationVariableSummary] getObservationVariableUnitData(observationUnitList: [ID], observationVariableName: String, unitName: String ): [ObservationVariableUnitData]! getIndexes(indexFamilyId: Int, id: Int, name: String): [Index] getIndexValues(indexId: Int, periodFrom: String, periodTo: String): [IndexValue] reportMC(siteId: Int!, tenant: String!, dateTimeFromIsoUtc: String, dateTimeToIsoUtc: String): [MesskonzeptRow] reportEichfristen(MKA_ANLAGENR: String, MKA_NAME: String, EICHJAHR: Int): [EichfristenRow] getMBusConfiguration(m2mId: Int!): M2MConfiguration! getMKAList: [MKA] getCustomerAccountHistory(ecNumber: String!, monatYYYYMM: String, anzMonateRetour: Int): [CustomerAccountHistory] getMKAByAnlagenr(mkaAnlagenr: String!): [MKA] getMKAByName(mkaName: String!): [MKA] getOpenSolarReport(queryName: String!, params: [ReportParam]): ReportResponse isAnlagenabrechnungRunning(anlagenNr: String!): Boolean! getAllRunningInstances(processDefinitionKey: String!): [String] # -------------------------------------------------------------- # Abfragen für das "LLM Meter Reading Recording" OERedshift - Beginn # -------------------------------------------------------------- # Sucht Sensoren, deren Name mit * beginnt. Liefert Sensor-ID, Name, zugehöriges MeasureConcept (id, name, descr). Das LLM braucht das, um bei mehreren Treffern dem User die MeasureConcept-Auswahl anzubieten. sensorsForMeterNumber(meterNumber: String!): [SensorInfo!]! # Liefert den letzten existierenden Messwert (Zählerstand + Zeitpunkt) für einen Sensor. Default-Variable: ENERGY_INST_VAL. Das LLM braucht das, um festzustellen, ob überhaupt ein Anfangsstand existiert. lastObservation(sensorId: ID!, variableName: String): Observation # Prüft, ob am angegebenen Tag bereits ein Zählerstand vorhanden ist. Kernregel: Doppelerfassung am selben Tag verhindern. observationsForDay(sensorId: ID!, date: Date!, variableName: String): [Observation!]! # Prüft für den Zeitraum from-to, ob für jeden Monatswechsel jeweils ein Wert kurz vor und kurz nach 00:00 UTC existiert. Liefert eine Liste der fehlenden Monate/Seiten (before/after midnight).Das ist die zentrale Validierung für die Ultimo-Regel. monthlyGapCheck(sensorId: ID!, from: DateTime!, to: DateTime!, variableName: String): [MonthGap!]! # Listet die verfügbaren ObservationVariables und zur Variable gehörige Unit für einen Sensor. Alphabetisch sortiert nach Variable-Name. Das LLM braucht das, um dem User die Auswahl der Variable zu ermöglichen (z.B. ENERGY_INST_VAL, ENERGY_DAY_VAL, POWER_VAL, etc.) availableVariableUnits(sensorId: ID!): [VariableUnitInfo!]! # -------------------------------------------------------------- # Abfragen für das "LLM Meter Reading Recording" - Ende # -------------------------------------------------------------- } # Eingabetyp für die Parameter des Reports input ReportParam { key: String! value: String! } # ReportResponse is a generic response for reports with: title, headers and data (OpenSolar Reports type ReportResponse { title: String headers: [String] data: [ReportData] } # das Ergebnis des Reports sind 0-n Zeilen (ReportData) mit Werten (values) type ReportData { values: [String] } type MKA { id: ID! dbkUid: String! updateKey: String! updateCount: Int! updateUid: String! firstApprovalUid: String! finalApprovalUid: String! lockUid: String firstApprovalStamp: String! finalApprovalStamp: String! lockStamp: String status: Int! rekey01: String! rekey02: String! mkaAnlagenr: String! mkaGiltab: String! mkaStatus: String! mkaMonatVon: Int! mkaName: String! mkaDatumIbn: String mkaStichtag: String! mkaZession: Int mkaAnmerkVm: String mkaAnmerkNo: String mkaAnmerkFl: String mkaAdresse: String mkaPlz: String mkaVerantwort: String mkaGenehmMail: String } type CustomerAccountHistory { building: String teilnehmer: String meteringpoint: String mandatreferenz: String monat: String akontoEUR: Float istVerbrauch: Float unitVerbrauch: String preisUnit: Float unitPreis: String preisVerbrauchEUR: Float saldoEUR: Float fehler: String } type Mutation { createWaehrung(waehrung: WaehrungInput!): Waehrung! updateWaehrung(id: ID!, waehrung: WaehrungInput!): Waehrung! deleteWaehrung(id: ID!): Boolean! createSensor(name: String!, nameExtern: String, description: String, measureConceptId: ID!): Sensor updateSensor(id: ID!, name: String!, nameExtern: String, description: String, measureConceptId: ID!): Sensor deleteSensor(id: ID!): String createObservation ( measureConceptId: ID! ,sensorNameLike:String, observationVariableNameLike: String, observationVariableUnitId: ID, observationTimeString: String, userName:String, meterValue:Float, imageFileName: String): Observation # -------------------------------------------------------------- # Abfragen für das "LLM Meter Reading Recording" OERedshift - Beginn # -------------------------------------------------------------- # Die Haupt-Mutation für einen einzelnen Zählerstand. Input: sensorId, moment, value (metervalue), variableUnit (optional, default ENERGY_INST_VAL). Serverseitig erzwingt sie die Regel "kein zweiter Wert am selben Tag" und gibt einen klaren Fehler zurück, falls verletzt. Sonst wird Observation erzeugt. recordMeterReading(input: MeterReadingInput!): MeterReadingResult! # Batch-Mutation für eine Serie von Ultimo-Ständen. Input: sensorId, variableUnit, eine zeitlich sortierte Liste von {month: YearMonth, meterValue: Float}. Es sollen Observations erzeugt werden. recordUltimoReadings(input: UltimoReadingsInput!): UltimoResult! # Setzt den Anfangszählerstand. Input: sensorId, startDate, startValue (default 0), variableUnit. Wird gebraucht, wenn lastObservation keinen Treffer liefert. Getrennt von recordMeterReading, damit das LLM den Initialfall explizit steuern kann. # es wird auch erlaubt einen Erststand VOR den aktuell ersten Stand zu setzen. Oft gebraucht wenn Zählereinbau bei 0, der erste Wert in der DB aber schon Zäherstand > 0 hat initializeMeterReading(input: InitMeterInput!): MeterReadingResult! # -------------------------------------------------------------- # Abfragen für das "LLM Meter Reading Recording" OERedshift - Ende # -------------------------------------------------------------- } input MeterReadingInput { sensorId: ID! moment: DateTime! value: Float! variableName: String variableUnit: String } input InitMeterInput { sensorId: ID! startDate: Date! startValue: Float = 0 variableName: String variableUnit: String } input UltimoReadingsInput { sensorId: ID! variableName: String variableUnit: String readings: [UltimoReadingEntry!]! } input UltimoReadingEntry { month: String! # YearMonth im Format "YYYY-MM" meterValue: Float! } input WaehrungInput { dbkUid: String! updateKey: String! updateName: String! updateCount: Int! firstApprovalUid: String! finalApprovalUid: String! lockUid: String firstApprovalStamp: String! finalApprovalStamp: String! lockStamp: String status: Int! currencyCode: String! currencyType: String! isEuroCurrency: String! decimalPlaces: Int! } type Index { id: Int indexFamilyId: Int isInactive: Boolean name: String isCombined: Boolean isCapitalPreservationModel: Boolean minValue: Float maxValue: Float maxDeltaIncrease: Float maxDeltaDecrease: Float publicationPeriodDuration: Int publicationPeriodDurationUnit: Int publicationReferenceDate: String publicationSchedulingReferenceDate: String schedulingPeriodDuration: Int schedulingPeriodDurationUnit: Int schedulingReferenceDate: String decimals: Int hasUnreliablePublicationSchedule: Boolean tentativeValuePeriodRange: Int tentativeValuePeriodJumping: Int created: String modified: String } type IndexValue { id: Int name: String periodBegin: String value: Float } type EichfristenRow { MKA_ANLAGENR: String MKA_NAME: String BSTAETTE: Int MANDANT: String MK_EICHUNG: String EICHJAHR: Int MK_ZAEHLER: String MK_HAUPTKATEGORIE: String MK_KATEGORIE: String MK_ZAEHLER_GUI: String MK_SERIALNR: String MK_MBUS_PRIM: String MK_MBUS_SEC: String MK_OBSERVATION_VARIABLE: String HERSTELLER: String EINHEIT_KBEZ: String EINHEIT_BEZ: String E_20074_DBK: String ZAEHLER_NEU: String MK_GILT_AB: String MK_GILT_BIS: String } type MesskonzeptRow { zaehler: String einheit: String zaehlerArt: String zaehlerTyp: String observationVariable: String rollVor: Int rollNach: Int m2m: String interf: String serial: String mbusPrim: String mbusSec: String plz: String strasse: String objektNr: Int herstellerBezeich: String bemerk1: String bemerk2: String inputWert: Int kategorie: String messwTyp: String intpolArt: String intpolIntval: Float extpolIntval: Float formel: String raster: String rasterStart: String hauptkategorie: String zaehlerGui: String sichtbarNurOE: String wertKonstant: Float datumIbn: String initialStand: Float verrechnung: String eichung: String giltAb: String giltBis: String } type Observation { id: ID! sensor: Sensor! observationVariableUnit: ObservationVariableUnit! measureType: MeasureType! observationRaster: ObservationRaster! contextHashValue: String moment: String! quality: String! status: Int! value: Float! meterValue: Float! } type ObservationGap { resultRow: Int! observation: Observation! prevMoment: String! gapDurationFormated: String! gapDuration: Int! } type ObservationDetails { resultRow: Int! observation: Observation! observationVariableName: String! unitName : String! } type ObservationVariableUnit { id: ID! observationVariable: ObservationVariable! unit: Unit! } type ObservationVariableUnitData { observationVariableUnitId: ID! observationVariableName: String! unitName: String! } type ObservationVariable { id: ID! name: String! description: String } type ObservationRaster { id: ID! unit: Unit! anzahl: Float! name: String! description: String } type ObservationContext { hashValue: ID! measureConcept: MeasureConcept! sensor: Sensor m2m: String moment: String! binaryMessage: String decodedMessage: String } type Sensor { id: ID! measureConcept: MeasureConcept! name: String! nameExtern: String description: String } type MeasureConcept { id: ID! name: String! description: String sensors: [Sensor] } type MeasureType { id: ID! name: String! description: String } type Unit { id: ID! name: String! description: String } type ObservationSummary { mcId: ID! mcName: String! sensorId: ID! sensorName: String! firstObservation: String! lastObservation: String! countObservation: Int measurementDays: Int integration: String! timeliness: String! } type ObservationVariableSummary { mcId: ID! mcName: String! sensorId: ID! sensorName: String! variableId: ID! variableName: String! firstObservation: String! lastObservation: String! countObservation: Int! minMeterValue: Float maxMeterValue: Float distinctMeterValueCount: Int } type M2MConfiguration { name: String alias: String m2m: String type: String infoText: String notificationInterval: Int notificationQueueName: String observationQueueName: String readingFrequencySeconds: Int queuingIntervalSeconds: Int iterations: Int calibrations: [Calibration] scalings: [Scaling] communicationParameters: CommunicationParameters serialCommunicationParameters: SerialCommunicationParameters winsockCommunicationParameters: WinsockCommunicationParameters sqs: String activeMQ: String activeMQParameters: ActiveMQParameters awsMQTT: String paho: String pahoLocal: String awsMqttParameters: AwsMqttParameters pahoParameters: PahoParameters searchIntervalSeconds: Int meterDefinitions: [MeterDefinition] } type Calibration { observationVariable: String calibrationValue: Float } type Scaling { unitOld: String unitNew: String scaleFactor: Float } type CommunicationParameters { communicationType: String timeOutInMillis: Int retryCount: Int continueIfError: String testCommunication: String } type SerialCommunicationParameters { portName: String baudRate: Int dataBits: Int stopBits: Int parity: Int flowControl: Int } type WinsockCommunicationParameters { inetHost: String inetPort: Int } type ActiveMQParameters { activeMQAddr: String } type AwsMqttParameters { reportingIntervalMillisec: Int awsKeyLocation: String awsKeyPrefix: String } type PahoParameters { reportingIntervalMillisec: Int pahoAddress: String pahoUser: String pahoPassword: String pahoTopicId: String } type MeterDefinition { primaryAddress: String addressString: String meterType: String readIntervalSeconds: Int } type Waehrung { id: ID! dbkUid: String! updateKey: String! updateName: String! updateCount: Int! firstApprovalUid: String! finalApprovalUid: String! lockUid: String firstApprovalStamp: String! finalApprovalStamp: String! lockStamp: String status: Int! currencyCode: String! currencyType: String! isEuroCurrency: String! decimalPlaces: Int! } # --------------------------------------------------- # Hilfstypen für das "LLM Meter Reading Recording" OERedshift - Begin # --------------------------------------------------- type VariableUnitInfo { variableUnitId: ID! variableName: String! unitName: String! } type SensorInfo { sensorId: ID! sensorName: String! sensorNameExtern: String descr: String measureConcept: MeasureConceptInfo! } type MeasureConceptInfo { id: ID! name: String! descr: String } type MonthGap { yearMonth: String! # z.B. "2025-10" missingBeforeMidnight: Boolean! missingAfterMidnight: Boolean! } type ValidationError { code: String! # z.B. DUPLICATE_DAY, MISSING_GAP, NO_INITIAL_READING message: String! details: String # JSON-String mit weiteren Informationen, z.B. die betroffenen Tage bei DUPLICATE_DAY oder MISSING_GAP } type UltimoResult { success: Boolean! created: [Observation!]! errors: [ValidationError!] } type MeterReadingResult { success: Boolean! observation: Observation errors: [ValidationError!] } # --------------------------------------------------- # Hilfstypen für das "LLM Meter Reading Recording" - Ende # ---------------------------------------------------