diff --git a/clients/customer-portal-client/package.json b/clients/customer-portal-client/package.json index 2357b1d..067e24d 100644 --- a/clients/customer-portal-client/package.json +++ b/clients/customer-portal-client/package.json @@ -1,6 +1,6 @@ { "name": "@epilot/customer-portal-client", - "version": "0.17.5", + "version": "0.18.0", "description": "API Client for epilot portal API", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/clients/customer-portal-client/src/openapi-runtime.json b/clients/customer-portal-client/src/openapi-runtime.json index 131f091..d4554af 100644 --- a/clients/customer-portal-client/src/openapi-runtime.json +++ b/clients/customer-portal-client/src/openapi-runtime.json @@ -815,24 +815,6 @@ "responses": {} } }, - "/v2/portal/entity/add-end-customer/{slug}/{id}": { - "put": { - "operationId": "addEndCustomerRelationToEntity", - "parameters": [ - { - "in": "path", - "name": "slug", - "required": true - }, - { - "in": "path", - "name": "id", - "required": true - } - ], - "responses": {} - } - }, "/v2/portal/entity/{slug}/{id}/activity": { "get": { "operationId": "getEntityActivityFeed", @@ -1155,6 +1137,25 @@ ], "responses": {} } + }, + "/v2/portal/metering/reading": { + "post": { + "operationId": "createMeterReading", + "parameters": [ + { + "name": "override_plausibility", + "in": "query", + "required": false + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": {} + } + }, + "responses": {} + } } }, "components": { @@ -1203,6 +1204,11 @@ "content": { "application/json": {} } + }, + "InvalidRequestCreateMeterReading": { + "content": { + "application/json": {} + } } } }, diff --git a/clients/customer-portal-client/src/openapi.d.ts b/clients/customer-portal-client/src/openapi.d.ts index 612338d..5209df1 100644 --- a/clients/customer-portal-client/src/openapi.d.ts +++ b/clients/customer-portal-client/src/openapi.d.ts @@ -32,6 +32,13 @@ declare namespace Components { export type ForbiddenByRule = Schemas.ErrorResp | Schemas.FailedRuleErrorResp; export type InternalServerError = Schemas.ErrorResp; export type InvalidRequest = Schemas.ErrorResp; + export interface InvalidRequestCreateMeterReading { + /** + * Error message + */ + message?: string; + reason?: "contract_period" | "no_counter" | "no_direction" | "timestamp_future" | "less_than_previous" | "greater_than_subsequent" | "meter_decommissioned" | "plausibility_check_failed"; + } export type NotFound = Schemas.ErrorResp; export type Unauthorized = Schemas.ErrorResp; } @@ -1141,6 +1148,7 @@ declare namespace Components { EntityId /* uuid */[] ]; } + export type Direction = "feed-in" | "feed-out"; export interface DocumentWidget { id: string; type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET"; @@ -1590,7 +1598,7 @@ declare namespace Components { * - contract_id array * - contact_id string * - 404 if no contract is found - * If `contact_id` is provided in the response, Contracts are retrieved from this Contact. + * If `contact_id` is provided in the response, Contracts are retrieved from this Contact. In that case, optionally, if you also specify `contact_relation_attribute`, the specified Contact attribute of the user performing the action will be modified to add the matched Contact. * */ ExtensionHookContractIdentification | /** @@ -1608,7 +1616,16 @@ declare namespace Components { * - 200 with the time series data * */ - ExtensionHookCostDataRetrieval))[]; + ExtensionHookCostDataRetrieval | /** + * Hook that checks the plausibility of meter readings before they are saved. This hook makes a POST call whenever a user is trying to save a meter reading. The expected response to the call is: + * - 200: + * If meter reading is plausible, the response should contain: + * - valid: true + * If meter reading is not plausible, the response should contain: + * - valid: false + * + */ + ExtensionHookMeterReadingPlausibilityCheck))[]; } export interface ExtensionConfig { /** @@ -1696,7 +1713,7 @@ declare namespace Components { * - contract_id array * - contact_id string * - 404 if no contract is found - * If `contact_id` is provided in the response, Contracts are retrieved from this Contact. + * If `contact_id` is provided in the response, Contracts are retrieved from this Contact. In that case, optionally, if you also specify `contact_relation_attribute`, the specified Contact attribute of the user performing the action will be modified to add the matched Contact. * */ export interface ExtensionHookContractIdentification { @@ -1747,6 +1764,12 @@ declare namespace Components { [name: string]: string; }; }; + /** + * Name of the Contact attribute to update with the matched Contact ID. Must be a Contact relation attribute supporting multiple entities. + * example: + * represents_contact + */ + contact_relation_attribute?: string; } /** * Hook that will allow using the specified source as data for consumption visualizations. This hook is triggered to fetch the data. Format of the request and response has to follow the following specification: TBD. The expected response to the call is: @@ -1806,6 +1829,75 @@ declare namespace Components { }; }; } + /** + * Hook that checks the plausibility of meter readings before they are saved. This hook makes a POST call whenever a user is trying to save a meter reading. The expected response to the call is: + * - 200: + * If meter reading is plausible, the response should contain: + * - valid: true + * If meter reading is not plausible, the response should contain: + * - valid: false + * + */ + export interface ExtensionHookMeterReadingPlausibilityCheck { + type: "meterReadingPlausibilityCheck"; + auth?: { + /** + * HTTP method to use for authentication + */ + method?: string; + /** + * URL to use for authentication. Supports variable interpolation. + */ + url: string; + /** + * Parameters to append to the URL. Supports variable interpolation. + */ + params?: { + [name: string]: string; + }; + /** + * Headers to use for authentication. Supports variable interpolation. + */ + headers?: { + [name: string]: string; + }; + /** + * JSON body to use for authentication. Supports variable interpolation. + */ + body?: { + [name: string]: string; + }; + }; + call: { + /** + * URL to call. Supports variable interpolation. + */ + url: string; + /** + * JSON body to use for authentication. Supports variable interpolation. + */ + body: { + [name: string]: string; + }; + /** + * Headers to use. Supports variable interpolation. + */ + headers: { + [name: string]: string; + }; + }; + /** + * Response to the call + */ + resolved: { + /** + * Indicate whether the meter reading is plausible + * example: + * {{CallResponse.data.valid}} + */ + valid?: string; + }; + } /** * Hook that will allow using the specified source as data for price visualizations. This hook is triggered to fetch the data. Format of the request and response has to follow the following specification: TBD. The expected response to the call is: * - 200 with the time series data @@ -2410,6 +2502,62 @@ declare namespace Components { }; schema?: string; } + export interface MeterReading { + /** + * The reading value of the meter + * example: + * 240 + */ + value: number; + read_by?: /** + * The person who recorded the reading + * example: + * John Doe + */ + ReadBy; + reason?: /** + * The reason for recording the reading + * example: + * Storing the feed-in record + */ + Reason; + /** + * The ID of the associated meter + */ + meter_id: /** + * Entity ID + * example: + * 5da0a718-c822-403d-9f5d-20d4584e0528 + */ + EntityId /* uuid */; + /** + * The ID of the associated meter counter + */ + counter_id?: /** + * Entity ID + * example: + * 5da0a718-c822-403d-9f5d-20d4584e0528 + */ + EntityId /* uuid */; + /** + * The direction of the reading (feed-in or feed-out) + */ + direction?: Direction; + /** + * If the value is not provided, the system will be set with the time the request is processed. + * example: + * 2022-10-10T00:00:00.000Z + */ + timestamp?: string; + /** + * The source of the reading + */ + source: Source; + /** + * The status of the reading + */ + status?: ReadingStatus; + } export interface MeterReadingWidget { id: string; type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET"; @@ -3080,6 +3228,19 @@ declare namespace Components { _updated_at: string; // date-time _schema: "product"; } + /** + * The person who recorded the reading + * example: + * John Doe + */ + export type ReadBy = string | null; + export type ReadingStatus = "valid" | "in-validation" | "implausible" | null | ""; + /** + * The reason for recording the reading + * example: + * Storing the feed-in record + */ + export type Reason = string | null; export interface RegistrationIdentifier { /** * Name of the identifier/attribute @@ -3279,6 +3440,8 @@ declare namespace Components { */ slug?: string; } + export type Source = "ECP" | "ERP" | "360" | "journey-submission"; + export type TariffType = "ht" | "nt"; export interface TeaserWidget { id: string; type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET"; @@ -3842,35 +4005,6 @@ declare namespace Paths { export type $500 = Components.Responses.InternalServerError; } } - namespace AddEndCustomerRelationToEntity { - namespace Parameters { - export type Id = /** - * Entity ID - * example: - * 5da0a718-c822-403d-9f5d-20d4584e0528 - */ - Components.Schemas.EntityId /* uuid */; - export type Slug = /** - * URL-friendly identifier for the entity schema - * example: - * contact - */ - Components.Schemas.EntitySlug; - } - export interface PathParameters { - slug: Parameters.Slug; - id: Parameters.Id; - } - namespace Responses { - export interface $200 { - entity?: Components.Schemas.EntityItem; - relations?: Components.Schemas.EntityItem[]; - } - export type $401 = Components.Responses.Unauthorized; - export type $403 = Components.Responses.Forbidden; - export type $500 = Components.Responses.InternalServerError; - } - } namespace CanTriggerPortalFlow { namespace Parameters { export type Origin = /* Origin of the portal */ Components.Schemas.Origin; @@ -4037,6 +4171,24 @@ declare namespace Paths { export type $500 = Components.Responses.InternalServerError; } } + namespace CreateMeterReading { + namespace Parameters { + export type OverridePlausibility = boolean; + } + export interface QueryParameters { + override_plausibility?: Parameters.OverridePlausibility; + } + export type RequestBody = Components.Schemas.MeterReading; + namespace Responses { + export interface $200 { + data?: Components.Schemas.MeterReading; + } + export type $400 = Components.Responses.InvalidRequestCreateMeterReading; + export type $401 = Components.Responses.Unauthorized; + export type $403 = Components.Responses.Forbidden; + export type $500 = Components.Responses.InternalServerError; + } + } namespace CreateSSOUser { namespace Parameters { export type Origin = /* Origin of the portal */ Components.Schemas.Origin; @@ -7245,16 +7397,6 @@ export interface OperationMethods { data?: any, config?: AxiosRequestConfig ): OperationResponse - /** - * addEndCustomerRelationToEntity - addEndCustomerRelationToEntity - * - * Add portal user relation to an entity - */ - 'addEndCustomerRelationToEntity'( - parameters?: Parameters | null, - data?: any, - config?: AxiosRequestConfig - ): OperationResponse /** * getEntityActivityFeed - getEntityActivityFeed * @@ -7451,6 +7593,16 @@ export interface OperationMethods { data?: any, config?: AxiosRequestConfig ): OperationResponse + /** + * createMeterReading - Create Meter Reading + * + * Inserts a new meter reading. + */ + 'createMeterReading'( + parameters?: Parameters | null, + data?: Paths.CreateMeterReading.RequestBody, + config?: AxiosRequestConfig + ): OperationResponse } export interface PathsDictionary { @@ -8108,18 +8260,6 @@ export interface PathsDictionary { config?: AxiosRequestConfig ): OperationResponse } - ['/v2/portal/entity/add-end-customer/{slug}/{id}']: { - /** - * addEndCustomerRelationToEntity - addEndCustomerRelationToEntity - * - * Add portal user relation to an entity - */ - 'put'( - parameters?: Parameters | null, - data?: any, - config?: AxiosRequestConfig - ): OperationResponse - } ['/v2/portal/entity/{slug}/{id}/activity']: { /** * getEntityActivityFeed - getEntityActivityFeed @@ -8352,6 +8492,18 @@ export interface PathsDictionary { config?: AxiosRequestConfig ): OperationResponse } + ['/v2/portal/metering/reading']: { + /** + * createMeterReading - Create Meter Reading + * + * Inserts a new meter reading. + */ + 'post'( + parameters?: Parameters | null, + data?: Paths.CreateMeterReading.RequestBody, + config?: AxiosRequestConfig + ): OperationResponse + } } export type Client = OpenAPIClient @@ -8381,6 +8533,7 @@ export type CreateSSOUserRequest = Components.Schemas.CreateSSOUserRequest; export type CreateUserRequest = Components.Schemas.CreateUserRequest; export type Currency = Components.Schemas.Currency; export type DeleteEntityFile = Components.Schemas.DeleteEntityFile; +export type Direction = Components.Schemas.Direction; export type DocumentWidget = Components.Schemas.DocumentWidget; export type EmailTemplates = Components.Schemas.EmailTemplates; export type Entity = Components.Schemas.Entity; @@ -8399,6 +8552,7 @@ export type ExtensionHook = Components.Schemas.ExtensionHook; export type ExtensionHookConsumptionDataRetrieval = Components.Schemas.ExtensionHookConsumptionDataRetrieval; export type ExtensionHookContractIdentification = Components.Schemas.ExtensionHookContractIdentification; export type ExtensionHookCostDataRetrieval = Components.Schemas.ExtensionHookCostDataRetrieval; +export type ExtensionHookMeterReadingPlausibilityCheck = Components.Schemas.ExtensionHookMeterReadingPlausibilityCheck; export type ExtensionHookPriceDataRetrieval = Components.Schemas.ExtensionHookPriceDataRetrieval; export type ExtensionHookRegistrationIdentifiersCheck = Components.Schemas.ExtensionHookRegistrationIdentifiersCheck; export type ExtensionSeamlessLink = Components.Schemas.ExtensionSeamlessLink; @@ -8413,6 +8567,7 @@ export type InstallmentEvent = Components.Schemas.InstallmentEvent; export type JourneyActions = Components.Schemas.JourneyActions; export type Meter = Components.Schemas.Meter; export type MeterChartWidget = Components.Schemas.MeterChartWidget; +export type MeterReading = Components.Schemas.MeterReading; export type MeterReadingWidget = Components.Schemas.MeterReadingWidget; export type Opportunity = Components.Schemas.Opportunity; export type Order = Components.Schemas.Order; @@ -8423,12 +8578,17 @@ export type PortalConfig = Components.Schemas.PortalConfig; export type PortalUser = Components.Schemas.PortalUser; export type PortalWidget = Components.Schemas.PortalWidget; export type Product = Components.Schemas.Product; +export type ReadBy = Components.Schemas.ReadBy; +export type ReadingStatus = Components.Schemas.ReadingStatus; +export type Reason = Components.Schemas.Reason; export type RegistrationIdentifier = Components.Schemas.RegistrationIdentifier; export type ReimbursementEvent = Components.Schemas.ReimbursementEvent; export type Rule = Components.Schemas.Rule; export type SaveEntityFile = Components.Schemas.SaveEntityFile; export type SavePortalFile = Components.Schemas.SavePortalFile; export type Schema = Components.Schemas.Schema; +export type Source = Components.Schemas.Source; +export type TariffType = Components.Schemas.TariffType; export type TeaserWidget = Components.Schemas.TeaserWidget; export type TriggerPortalFlow = Components.Schemas.TriggerPortalFlow; export type UpdateOnlyPortalConfigAttributes = Components.Schemas.UpdateOnlyPortalConfigAttributes; diff --git a/clients/customer-portal-client/src/openapi.json b/clients/customer-portal-client/src/openapi.json index d792cf2..9fc1972 100644 --- a/clients/customer-portal-client/src/openapi.json +++ b/clients/customer-portal-client/src/openapi.json @@ -3756,73 +3756,6 @@ } } }, - "/v2/portal/entity/add-end-customer/{slug}/{id}": { - "put": { - "operationId": "addEndCustomerRelationToEntity", - "summary": "addEndCustomerRelationToEntity", - "description": "Add portal user relation to an entity", - "tags": [ - "ECP" - ], - "security": [ - { - "PortalAuth": [] - } - ], - "parameters": [ - { - "in": "path", - "name": "slug", - "schema": { - "$ref": "#/components/schemas/EntitySlug" - }, - "required": true, - "description": "The slug of an entity" - }, - { - "in": "path", - "name": "id", - "schema": { - "$ref": "#/components/schemas/EntityId" - }, - "required": true, - "description": "The ID of the Entity" - } - ], - "responses": { - "200": { - "description": "Portal user is added as a relation to the requested entity successfully.", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "entity": { - "$ref": "#/components/schemas/EntityItem" - }, - "relations": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntityItem" - } - } - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, - "500": { - "$ref": "#/components/responses/InternalServerError" - } - } - } - }, "/v2/portal/entity/{slug}/{id}/activity": { "get": { "operationId": "getEntityActivityFeed", @@ -5039,6 +4972,73 @@ } } } + }, + "/v2/portal/metering/reading": { + "post": { + "operationId": "createMeterReading", + "summary": "Create Meter Reading", + "description": "Inserts a new meter reading.", + "tags": [ + "ECP" + ], + "security": [ + { + "PortalAuth": [] + } + ], + "parameters": [ + { + "name": "override_plausibility", + "in": "query", + "required": false, + "description": "Override plausibility check", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "requestBody": { + "description": "Meter reading payload.", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeterReading" + } + } + } + }, + "responses": { + "200": { + "description": "Meter reading created successfully.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/MeterReading" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/InvalidRequestCreateMeterReading" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } } }, "components": { @@ -5175,6 +5175,37 @@ } } } + }, + "InvalidRequestCreateMeterReading": { + "description": "The request could not be validated", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/ErrorResp" + }, + { + "properties": { + "reason": { + "type": "string", + "enum": [ + "contract_period", + "no_counter", + "no_direction", + "timestamp_future", + "less_than_previous", + "greater_than_subsequent", + "meter_decommissioned", + "plausibility_check_failed" + ] + } + } + } + ] + } + } + } } }, "securitySchemes": { @@ -8145,6 +8176,9 @@ }, { "$ref": "#/components/schemas/ExtensionHookCostDataRetrieval" + }, + { + "$ref": "#/components/schemas/ExtensionHookMeterReadingPlausibilityCheck" } ] } @@ -8377,7 +8411,7 @@ ] }, "ExtensionHookContractIdentification": { - "description": "Hook that replaces the built-in contract identification for self-assignment. This hook makes a POST call whenever a user is trying to self-assign a contract to find the corresponding contract(s). The expected response to the call is:\n - 200 if found with either:\n - contract_id array\n - contact_id string\n - 404 if no contract is found\nIf `contact_id` is provided in the response, Contracts are retrieved from this Contact.\n", + "description": "Hook that replaces the built-in contract identification for self-assignment. This hook makes a POST call whenever a user is trying to self-assign a contract to find the corresponding contract(s). The expected response to the call is:\n - 200 if found with either:\n - contract_id array\n - contact_id string\n - 404 if no contract is found\nIf `contact_id` is provided in the response, Contracts are retrieved from this Contact. In that case, optionally, if you also specify `contact_relation_attribute`, the specified Contact attribute of the user performing the action will be modified to add the matched Contact.\n", "type": "object", "properties": { "type": { @@ -8456,6 +8490,11 @@ "headers", "result" ] + }, + "contact_relation_attribute": { + "type": "string", + "description": "Name of the Contact attribute to update with the matched Contact ID. Must be a Contact relation attribute supporting multiple entities.", + "example": "represents_contact" } }, "required": [ @@ -8463,6 +8502,106 @@ "call" ] }, + "ExtensionHookMeterReadingPlausibilityCheck": { + "description": "Hook that checks the plausibility of meter readings before they are saved. This hook makes a POST call whenever a user is trying to save a meter reading. The expected response to the call is:\n - 200:\n If meter reading is plausible, the response should contain:\n - valid: true\n If meter reading is not plausible, the response should contain:\n - valid: false\n", + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "meterReadingPlausibilityCheck" + ] + }, + "auth": { + "type": "object", + "properties": { + "method": { + "type": "string", + "description": "HTTP method to use for authentication", + "default": "POST" + }, + "url": { + "type": "string", + "description": "URL to use for authentication. Supports variable interpolation." + }, + "params": { + "type": "object", + "description": "Parameters to append to the URL. Supports variable interpolation.", + "additionalProperties": { + "type": "string" + }, + "default": {} + }, + "headers": { + "type": "object", + "description": "Headers to use for authentication. Supports variable interpolation.", + "additionalProperties": { + "type": "string" + }, + "default": {} + }, + "body": { + "type": "object", + "description": "JSON body to use for authentication. Supports variable interpolation.", + "additionalProperties": { + "type": "string" + }, + "default": {} + } + }, + "required": [ + "url" + ] + }, + "call": { + "type": "object", + "properties": { + "url": { + "type": "string", + "description": "URL to call. Supports variable interpolation." + }, + "body": { + "type": "object", + "description": "JSON body to use for authentication. Supports variable interpolation.", + "additionalProperties": { + "type": "string" + }, + "default": {} + }, + "headers": { + "type": "object", + "description": "Headers to use. Supports variable interpolation.", + "additionalProperties": { + "type": "string" + }, + "default": {} + } + }, + "required": [ + "url", + "headers", + "body", + "result" + ] + }, + "resolved": { + "type": "object", + "description": "Response to the call", + "properties": { + "valid": { + "type": "string", + "description": "Indicate whether the meter reading is plausible", + "example": "{{CallResponse.data.valid}}" + } + } + } + }, + "required": [ + "type", + "call", + "resolved" + ] + }, "ExtensionHookPriceDataRetrieval": { "description": "Hook that will allow using the specified source as data for price visualizations. This hook is triggered to fetch the data. Format of the request and response has to follow the following specification: TBD. The expected response to the call is:\n - 200 with the time series data\n", "type": "object", @@ -8732,6 +8871,98 @@ "type", "call" ] + }, + "Direction": { + "type": "string", + "enum": [ + "feed-in", + "feed-out" + ] + }, + "TariffType": { + "type": "string", + "enum": [ + "ht", + "nt" + ] + }, + "Source": { + "type": "string", + "enum": [ + "ECP", + "ERP", + "360", + "journey-submission" + ] + }, + "Reason": { + "type": "string", + "nullable": true, + "example": "Storing the feed-in record", + "description": "The reason for recording the reading" + }, + "ReadBy": { + "type": "string", + "nullable": true, + "example": "John Doe", + "description": "The person who recorded the reading" + }, + "ReadingStatus": { + "type": "string", + "nullable": true, + "enum": [ + "valid", + "in-validation", + "implausible", + null, + "" + ] + }, + "MeterReading": { + "type": "object", + "required": [ + "value", + "meter_id", + "source" + ], + "properties": { + "value": { + "type": "number", + "example": 240, + "description": "The reading value of the meter" + }, + "read_by": { + "$ref": "#/components/schemas/ReadBy" + }, + "reason": { + "$ref": "#/components/schemas/Reason" + }, + "meter_id": { + "$ref": "#/components/schemas/EntityId", + "description": "The ID of the associated meter" + }, + "counter_id": { + "$ref": "#/components/schemas/EntityId", + "description": "The ID of the associated meter counter" + }, + "direction": { + "$ref": "#/components/schemas/Direction", + "description": "The direction of the reading (feed-in or feed-out)" + }, + "timestamp": { + "type": "string", + "description": "If the value is not provided, the system will be set with the time the request is processed.", + "example": "2022-10-10T00:00:00.000Z" + }, + "source": { + "$ref": "#/components/schemas/Source", + "description": "The source of the reading" + }, + "status": { + "$ref": "#/components/schemas/ReadingStatus", + "description": "The status of the reading" + } + } } } },